1f5188211SFan Zhang /* SPDX-License-Identifier: BSD-3-Clause 2f5188211SFan Zhang * Copyright(c) 2017-2018 Intel Corporation 3f5188211SFan Zhang */ 4f5188211SFan Zhang 5f5188211SFan Zhang #include <stdio.h> 6f5188211SFan Zhang #include <stdlib.h> 7e1d90eaaSFan Zhang #include <string.h> 8f5188211SFan Zhang #include <unistd.h> 9f5188211SFan Zhang #include <stdbool.h> 10f5188211SFan Zhang #include <assert.h> 11f5188211SFan Zhang #include <getopt.h> 12f5188211SFan Zhang 13f5188211SFan Zhang #include <rte_malloc.h> 14f5188211SFan Zhang #include <rte_cycles.h> 15f5188211SFan Zhang #include <rte_vhost.h> 16f5188211SFan Zhang #include <rte_cryptodev.h> 17f5188211SFan Zhang #include <rte_vhost_crypto.h> 18709521f4SFan Zhang #include <rte_string_fns.h> 19f5188211SFan Zhang 20f5188211SFan Zhang #include <cmdline_rdline.h> 21f5188211SFan Zhang #include <cmdline_parse.h> 22f5188211SFan Zhang #include <cmdline_parse_string.h> 23f5188211SFan Zhang #include <cmdline.h> 24f5188211SFan Zhang 25f5188211SFan Zhang #define NB_VIRTIO_QUEUES (1) 26f5188211SFan Zhang #define MAX_PKT_BURST (64) 27f5188211SFan Zhang #define MAX_IV_LEN (32) 28f5188211SFan Zhang #define NB_MEMPOOL_OBJS (8192) 29f5188211SFan Zhang #define NB_CRYPTO_DESCRIPTORS (4096) 30f5188211SFan Zhang #define NB_CACHE_OBJS (128) 31f5188211SFan Zhang #define SESSION_MAP_ENTRIES (1024) 32f5188211SFan Zhang #define REFRESH_TIME_SEC (3) 33f5188211SFan Zhang 34709521f4SFan Zhang #define MAX_NB_SOCKETS (4) 35709521f4SFan Zhang #define MAX_NB_WORKER_CORES (16) 36f5188211SFan Zhang 37709521f4SFan Zhang struct lcore_option { 38709521f4SFan Zhang uint32_t lcore_id; 39f5188211SFan Zhang char *socket_files[MAX_NB_SOCKETS]; 40f5188211SFan Zhang uint32_t nb_sockets; 41f5188211SFan Zhang uint8_t cid; 42f5188211SFan Zhang uint16_t qid; 43709521f4SFan Zhang }; 44709521f4SFan Zhang 45709521f4SFan Zhang struct vhost_crypto_info { 46709521f4SFan Zhang int vids[MAX_NB_SOCKETS]; 47709521f4SFan Zhang uint32_t nb_vids; 48709521f4SFan Zhang struct rte_mempool *sess_pool; 49ac5e42daSFan Zhang struct rte_mempool *sess_priv_pool; 50709521f4SFan Zhang struct rte_mempool *cop_pool; 51709521f4SFan Zhang uint8_t cid; 52709521f4SFan Zhang uint32_t qid; 53709521f4SFan Zhang uint32_t nb_inflight_ops; 54709521f4SFan Zhang volatile uint32_t initialized[MAX_NB_SOCKETS]; 55709521f4SFan Zhang } __rte_cache_aligned; 56709521f4SFan Zhang 57709521f4SFan Zhang struct vhost_crypto_options { 58709521f4SFan Zhang struct lcore_option los[MAX_NB_WORKER_CORES]; 59709521f4SFan Zhang struct vhost_crypto_info *infos[MAX_NB_WORKER_CORES]; 60709521f4SFan Zhang uint32_t nb_los; 61f5188211SFan Zhang uint32_t zero_copy; 62f5188211SFan Zhang uint32_t guest_polling; 63f5188211SFan Zhang } options; 64f5188211SFan Zhang 65709521f4SFan Zhang #define CONFIG_KEYWORD "config" 66f5188211SFan Zhang #define SOCKET_FILE_KEYWORD "socket-file" 67f5188211SFan Zhang #define ZERO_COPY_KEYWORD "zero-copy" 68f5188211SFan Zhang #define POLLING_KEYWORD "guest-polling" 69f5188211SFan Zhang 70709521f4SFan Zhang #define NB_SOCKET_FIELDS (2) 71709521f4SFan Zhang 72709521f4SFan Zhang static uint32_t 73709521f4SFan Zhang find_lo(uint32_t lcore_id) 74709521f4SFan Zhang { 75709521f4SFan Zhang uint32_t i; 76709521f4SFan Zhang 77709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) 78709521f4SFan Zhang if (options.los[i].lcore_id == lcore_id) 79709521f4SFan Zhang return i; 80709521f4SFan Zhang 81709521f4SFan Zhang return UINT32_MAX; 82709521f4SFan Zhang } 83f5188211SFan Zhang 84f5188211SFan Zhang /** support *SOCKET_FILE_PATH:CRYPTODEV_ID* format */ 85f5188211SFan Zhang static int 86f5188211SFan Zhang parse_socket_arg(char *arg) 87f5188211SFan Zhang { 88709521f4SFan Zhang uint32_t nb_sockets; 89709521f4SFan Zhang uint32_t lcore_id; 90709521f4SFan Zhang char *str_fld[NB_SOCKET_FIELDS]; 91709521f4SFan Zhang struct lcore_option *lo; 92709521f4SFan Zhang uint32_t idx; 93709521f4SFan Zhang char *end; 94709521f4SFan Zhang 95709521f4SFan Zhang if (rte_strsplit(arg, strlen(arg), str_fld, NB_SOCKET_FIELDS, ',') != 96709521f4SFan Zhang NB_SOCKET_FIELDS) { 97709521f4SFan Zhang RTE_LOG(ERR, USER1, "Invalid socket parameter '%s'\n", arg); 98709521f4SFan Zhang return -EINVAL; 99709521f4SFan Zhang } 100709521f4SFan Zhang 101709521f4SFan Zhang errno = 0; 102709521f4SFan Zhang lcore_id = strtoul(str_fld[0], &end, 0); 103709521f4SFan Zhang if (errno != 0 || end == str_fld[0] || lcore_id > 255) 104709521f4SFan Zhang return -EINVAL; 105709521f4SFan Zhang 106709521f4SFan Zhang idx = find_lo(lcore_id); 107709521f4SFan Zhang if (idx == UINT32_MAX) { 108709521f4SFan Zhang if (options.nb_los == MAX_NB_WORKER_CORES) 109709521f4SFan Zhang return -ENOMEM; 110709521f4SFan Zhang lo = &options.los[options.nb_los]; 111709521f4SFan Zhang lo->lcore_id = lcore_id; 112709521f4SFan Zhang options.nb_los++; 113709521f4SFan Zhang } else 114709521f4SFan Zhang lo = &options.los[idx]; 115709521f4SFan Zhang 116709521f4SFan Zhang nb_sockets = lo->nb_sockets; 117f5188211SFan Zhang 118f5188211SFan Zhang if (nb_sockets >= MAX_NB_SOCKETS) { 119f5188211SFan Zhang RTE_LOG(ERR, USER1, "Too many socket files!\n"); 120f5188211SFan Zhang return -ENOMEM; 121f5188211SFan Zhang } 122f5188211SFan Zhang 123709521f4SFan Zhang lo->socket_files[nb_sockets] = strdup(str_fld[1]); 124709521f4SFan Zhang if (!lo->socket_files[nb_sockets]) { 125f5188211SFan Zhang RTE_LOG(ERR, USER1, "Insufficient memory\n"); 126f5188211SFan Zhang return -ENOMEM; 127f5188211SFan Zhang } 128f5188211SFan Zhang 129709521f4SFan Zhang lo->nb_sockets++; 130f5188211SFan Zhang 131f5188211SFan Zhang return 0; 132f5188211SFan Zhang } 133f5188211SFan Zhang 134f5188211SFan Zhang static int 135709521f4SFan Zhang parse_config(char *q_arg) 136f5188211SFan Zhang { 137709521f4SFan Zhang struct lcore_option *lo; 138709521f4SFan Zhang char s[256]; 139709521f4SFan Zhang const char *p, *p0 = q_arg; 140709521f4SFan Zhang char *end; 141709521f4SFan Zhang enum fieldnames { 142709521f4SFan Zhang FLD_LCORE = 0, 143709521f4SFan Zhang FLD_CID, 144709521f4SFan Zhang FLD_QID, 145709521f4SFan Zhang _NUM_FLD 146709521f4SFan Zhang }; 147709521f4SFan Zhang uint32_t flds[_NUM_FLD]; 148709521f4SFan Zhang char *str_fld[_NUM_FLD]; 149709521f4SFan Zhang uint32_t i; 150709521f4SFan Zhang uint32_t size; 151f5188211SFan Zhang 152709521f4SFan Zhang while ((p = strchr(p0, '(')) != NULL) { 153709521f4SFan Zhang ++p; 154709521f4SFan Zhang p0 = strchr(p, ')'); 155709521f4SFan Zhang if (p0 == NULL) 156f5188211SFan Zhang return -1; 157f5188211SFan Zhang 158709521f4SFan Zhang size = p0 - p; 159709521f4SFan Zhang if (size >= sizeof(s)) 160f5188211SFan Zhang return -1; 161709521f4SFan Zhang 162709521f4SFan Zhang snprintf(s, sizeof(s), "%.*s", size, p); 163709521f4SFan Zhang if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != 164709521f4SFan Zhang _NUM_FLD) 165709521f4SFan Zhang return -1; 166709521f4SFan Zhang for (i = 0; i < _NUM_FLD; i++) { 167709521f4SFan Zhang errno = 0; 168709521f4SFan Zhang flds[i] = strtoul(str_fld[i], &end, 0); 169709521f4SFan Zhang if (errno != 0 || end == str_fld[i] || flds[i] > 255) 170709521f4SFan Zhang return -EINVAL; 171f5188211SFan Zhang } 172f5188211SFan Zhang 173709521f4SFan Zhang if (flds[FLD_LCORE] > RTE_MAX_LCORE) 174709521f4SFan Zhang return -EINVAL; 175709521f4SFan Zhang 176709521f4SFan Zhang i = find_lo(flds[FLD_LCORE]); 177709521f4SFan Zhang if (i == UINT32_MAX) { 178709521f4SFan Zhang if (options.nb_los == MAX_NB_WORKER_CORES) 179709521f4SFan Zhang return -ENOMEM; 180709521f4SFan Zhang lo = &options.los[options.nb_los]; 181709521f4SFan Zhang options.nb_los++; 182709521f4SFan Zhang } else 183709521f4SFan Zhang lo = &options.los[i]; 184709521f4SFan Zhang 185709521f4SFan Zhang lo->lcore_id = flds[FLD_LCORE]; 186709521f4SFan Zhang lo->cid = flds[FLD_CID]; 187709521f4SFan Zhang lo->qid = flds[FLD_QID]; 188709521f4SFan Zhang } 189f5188211SFan Zhang 190f5188211SFan Zhang return 0; 191f5188211SFan Zhang } 192f5188211SFan Zhang 193f5188211SFan Zhang static void 194f5188211SFan Zhang vhost_crypto_usage(const char *prgname) 195f5188211SFan Zhang { 196f5188211SFan Zhang printf("%s [EAL options] --\n" 197709521f4SFan Zhang " --%s <lcore>,SOCKET-FILE-PATH\n" 198*854dbee2SIbtisam Tariq " --%s (lcore,cdev_id,queue_id)[,(lcore,cdev_id,queue_id)]\n" 199f5188211SFan Zhang " --%s: zero copy\n" 200f5188211SFan Zhang " --%s: guest polling\n", 201709521f4SFan Zhang prgname, SOCKET_FILE_KEYWORD, CONFIG_KEYWORD, 202709521f4SFan Zhang ZERO_COPY_KEYWORD, POLLING_KEYWORD); 203f5188211SFan Zhang } 204f5188211SFan Zhang 205f5188211SFan Zhang static int 206f5188211SFan Zhang vhost_crypto_parse_args(int argc, char **argv) 207f5188211SFan Zhang { 208f5188211SFan Zhang int opt, ret; 209f5188211SFan Zhang char *prgname = argv[0]; 210f5188211SFan Zhang char **argvopt; 211f5188211SFan Zhang int option_index; 212f5188211SFan Zhang struct option lgopts[] = { 213f5188211SFan Zhang {SOCKET_FILE_KEYWORD, required_argument, 0, 0}, 214709521f4SFan Zhang {CONFIG_KEYWORD, required_argument, 0, 0}, 215f5188211SFan Zhang {ZERO_COPY_KEYWORD, no_argument, 0, 0}, 216f5188211SFan Zhang {POLLING_KEYWORD, no_argument, 0, 0}, 217f5188211SFan Zhang {NULL, 0, 0, 0} 218f5188211SFan Zhang }; 219f5188211SFan Zhang 220f5188211SFan Zhang argvopt = argv; 221f5188211SFan Zhang 222f5188211SFan Zhang while ((opt = getopt_long(argc, argvopt, "s:", 223f5188211SFan Zhang lgopts, &option_index)) != EOF) { 224f5188211SFan Zhang 225f5188211SFan Zhang switch (opt) { 226f5188211SFan Zhang case 0: 227f5188211SFan Zhang if (strcmp(lgopts[option_index].name, 228f5188211SFan Zhang SOCKET_FILE_KEYWORD) == 0) { 229f5188211SFan Zhang ret = parse_socket_arg(optarg); 230f5188211SFan Zhang if (ret < 0) { 231f5188211SFan Zhang vhost_crypto_usage(prgname); 232f5188211SFan Zhang return ret; 233f5188211SFan Zhang } 234f5188211SFan Zhang } else if (strcmp(lgopts[option_index].name, 235709521f4SFan Zhang CONFIG_KEYWORD) == 0) { 236709521f4SFan Zhang ret = parse_config(optarg); 237f5188211SFan Zhang if (ret < 0) { 238f5188211SFan Zhang vhost_crypto_usage(prgname); 239f5188211SFan Zhang return ret; 240f5188211SFan Zhang } 241f5188211SFan Zhang } else if (strcmp(lgopts[option_index].name, 242f5188211SFan Zhang ZERO_COPY_KEYWORD) == 0) { 243f5188211SFan Zhang options.zero_copy = 244f5188211SFan Zhang RTE_VHOST_CRYPTO_ZERO_COPY_ENABLE; 245f5188211SFan Zhang } else if (strcmp(lgopts[option_index].name, 246f5188211SFan Zhang POLLING_KEYWORD) == 0) { 247f5188211SFan Zhang options.guest_polling = 1; 248f5188211SFan Zhang } else { 249f5188211SFan Zhang vhost_crypto_usage(prgname); 250f5188211SFan Zhang return -EINVAL; 251f5188211SFan Zhang } 252f5188211SFan Zhang break; 253f5188211SFan Zhang default: 254f5188211SFan Zhang return -1; 255f5188211SFan Zhang } 256f5188211SFan Zhang } 257f5188211SFan Zhang 258f5188211SFan Zhang return 0; 259f5188211SFan Zhang } 260f5188211SFan Zhang 261f5188211SFan Zhang static int 262f5188211SFan Zhang new_device(int vid) 263f5188211SFan Zhang { 264709521f4SFan Zhang struct vhost_crypto_info *info = NULL; 265f5188211SFan Zhang char path[PATH_MAX]; 266709521f4SFan Zhang uint32_t i, j; 267f5188211SFan Zhang int ret; 268f5188211SFan Zhang 269f5188211SFan Zhang ret = rte_vhost_get_ifname(vid, path, PATH_MAX); 270f5188211SFan Zhang if (ret) { 271f5188211SFan Zhang RTE_LOG(ERR, USER1, "Cannot find matched socket\n"); 272f5188211SFan Zhang return ret; 273f5188211SFan Zhang } 274f5188211SFan Zhang 275709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) { 276709521f4SFan Zhang for (j = 0; j < options.los[i].nb_sockets; j++) { 277709521f4SFan Zhang if (strcmp(path, options.los[i].socket_files[j]) == 0) { 278709521f4SFan Zhang info = options.infos[i]; 279709521f4SFan Zhang break; 280709521f4SFan Zhang } 281709521f4SFan Zhang } 282709521f4SFan Zhang 283709521f4SFan Zhang if (info) 284f5188211SFan Zhang break; 285f5188211SFan Zhang } 286f5188211SFan Zhang 287709521f4SFan Zhang if (!info) { 288f5188211SFan Zhang RTE_LOG(ERR, USER1, "Cannot find recorded socket\n"); 289f5188211SFan Zhang return -ENOENT; 290f5188211SFan Zhang } 291f5188211SFan Zhang 292709521f4SFan Zhang ret = rte_vhost_crypto_create(vid, info->cid, info->sess_pool, 293ac5e42daSFan Zhang info->sess_priv_pool, 294709521f4SFan Zhang rte_lcore_to_socket_id(options.los[i].lcore_id)); 295f5188211SFan Zhang if (ret) { 296f5188211SFan Zhang RTE_LOG(ERR, USER1, "Cannot create vhost crypto\n"); 297f5188211SFan Zhang return ret; 298f5188211SFan Zhang } 299f5188211SFan Zhang 300f5188211SFan Zhang ret = rte_vhost_crypto_set_zero_copy(vid, options.zero_copy); 301f5188211SFan Zhang if (ret) { 302f5188211SFan Zhang RTE_LOG(ERR, USER1, "Cannot %s zero copy feature\n", 303f5188211SFan Zhang options.zero_copy == 1 ? "enable" : "disable"); 304f5188211SFan Zhang return ret; 305f5188211SFan Zhang } 306f5188211SFan Zhang 307709521f4SFan Zhang info->vids[j] = vid; 308709521f4SFan Zhang info->initialized[j] = 1; 309f5188211SFan Zhang 310f5188211SFan Zhang rte_wmb(); 311f5188211SFan Zhang 312f5188211SFan Zhang RTE_LOG(INFO, USER1, "New Vhost-crypto Device %s, Device ID %d\n", path, 313f5188211SFan Zhang vid); 314f5188211SFan Zhang return 0; 315f5188211SFan Zhang } 316f5188211SFan Zhang 317f5188211SFan Zhang static void 318f5188211SFan Zhang destroy_device(int vid) 319f5188211SFan Zhang { 320709521f4SFan Zhang struct vhost_crypto_info *info = NULL; 321709521f4SFan Zhang uint32_t i, j; 322f5188211SFan Zhang 323709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) { 324709521f4SFan Zhang for (j = 0; j < options.los[i].nb_sockets; j++) { 325709521f4SFan Zhang if (options.infos[i]->vids[j] == vid) { 326709521f4SFan Zhang info = options.infos[i]; 327709521f4SFan Zhang break; 328709521f4SFan Zhang } 329709521f4SFan Zhang } 330709521f4SFan Zhang if (info) 331f5188211SFan Zhang break; 332f5188211SFan Zhang } 333f5188211SFan Zhang 334709521f4SFan Zhang if (!info) { 335f5188211SFan Zhang RTE_LOG(ERR, USER1, "Cannot find socket file from list\n"); 336f5188211SFan Zhang return; 337f5188211SFan Zhang } 338f5188211SFan Zhang 339709521f4SFan Zhang do { 340709521f4SFan Zhang 341709521f4SFan Zhang } while (info->nb_inflight_ops); 342709521f4SFan Zhang 343709521f4SFan Zhang info->initialized[j] = 0; 344f5188211SFan Zhang 345f5188211SFan Zhang rte_wmb(); 346f5188211SFan Zhang 347f5188211SFan Zhang rte_vhost_crypto_free(vid); 348f5188211SFan Zhang 349f5188211SFan Zhang RTE_LOG(INFO, USER1, "Vhost Crypto Device %i Removed\n", vid); 350f5188211SFan Zhang } 351f5188211SFan Zhang 352f5188211SFan Zhang static const struct vhost_device_ops virtio_crypto_device_ops = { 353f5188211SFan Zhang .new_device = new_device, 354f5188211SFan Zhang .destroy_device = destroy_device, 355f5188211SFan Zhang }; 356f5188211SFan Zhang 357f5188211SFan Zhang static int 358709521f4SFan Zhang vhost_crypto_worker(void *arg) 359f5188211SFan Zhang { 360f5188211SFan Zhang struct rte_crypto_op *ops[NB_VIRTIO_QUEUES][MAX_PKT_BURST + 1]; 361f5188211SFan Zhang struct rte_crypto_op *ops_deq[NB_VIRTIO_QUEUES][MAX_PKT_BURST + 1]; 362709521f4SFan Zhang struct vhost_crypto_info *info = arg; 363f5188211SFan Zhang uint16_t nb_callfds; 364f5188211SFan Zhang int callfds[VIRTIO_CRYPTO_MAX_NUM_BURST_VQS]; 365f5188211SFan Zhang uint32_t lcore_id = rte_lcore_id(); 366f5188211SFan Zhang uint32_t burst_size = MAX_PKT_BURST; 367f5188211SFan Zhang uint32_t i, j, k; 368f5188211SFan Zhang uint32_t to_fetch, fetched; 369f5188211SFan Zhang 370f5188211SFan Zhang int ret = 0; 371f5188211SFan Zhang 372f5188211SFan Zhang RTE_LOG(INFO, USER1, "Processing on Core %u started\n", lcore_id); 373f5188211SFan Zhang 374f5188211SFan Zhang for (i = 0; i < NB_VIRTIO_QUEUES; i++) { 375709521f4SFan Zhang if (rte_crypto_op_bulk_alloc(info->cop_pool, 376f5188211SFan Zhang RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops[i], 377f5188211SFan Zhang burst_size) < burst_size) { 378f5188211SFan Zhang RTE_LOG(ERR, USER1, "Failed to alloc cops\n"); 379f5188211SFan Zhang ret = -1; 380f5188211SFan Zhang goto exit; 381f5188211SFan Zhang } 382f5188211SFan Zhang } 383f5188211SFan Zhang 384f5188211SFan Zhang while (1) { 385709521f4SFan Zhang for (i = 0; i < info->nb_vids; i++) { 386709521f4SFan Zhang if (unlikely(info->initialized[i] == 0)) 387f5188211SFan Zhang continue; 388f5188211SFan Zhang 389f5188211SFan Zhang for (j = 0; j < NB_VIRTIO_QUEUES; j++) { 390f5188211SFan Zhang to_fetch = RTE_MIN(burst_size, 391f5188211SFan Zhang (NB_CRYPTO_DESCRIPTORS - 392709521f4SFan Zhang info->nb_inflight_ops)); 393f5188211SFan Zhang fetched = rte_vhost_crypto_fetch_requests( 394709521f4SFan Zhang info->vids[i], j, ops[j], 395f5188211SFan Zhang to_fetch); 396709521f4SFan Zhang info->nb_inflight_ops += 397709521f4SFan Zhang rte_cryptodev_enqueue_burst( 398709521f4SFan Zhang info->cid, info->qid, ops[j], 399f5188211SFan Zhang fetched); 400f5188211SFan Zhang if (unlikely(rte_crypto_op_bulk_alloc( 401709521f4SFan Zhang info->cop_pool, 402f5188211SFan Zhang RTE_CRYPTO_OP_TYPE_SYMMETRIC, 403f5188211SFan Zhang ops[j], fetched) < fetched)) { 404f5188211SFan Zhang RTE_LOG(ERR, USER1, "Failed realloc\n"); 405f5188211SFan Zhang return -1; 406f5188211SFan Zhang } 407f5188211SFan Zhang 408f5188211SFan Zhang fetched = rte_cryptodev_dequeue_burst( 409709521f4SFan Zhang info->cid, info->qid, 410f5188211SFan Zhang ops_deq[j], RTE_MIN(burst_size, 411709521f4SFan Zhang info->nb_inflight_ops)); 412f5188211SFan Zhang fetched = rte_vhost_crypto_finalize_requests( 413f5188211SFan Zhang ops_deq[j], fetched, callfds, 414f5188211SFan Zhang &nb_callfds); 415f5188211SFan Zhang 416709521f4SFan Zhang info->nb_inflight_ops -= fetched; 417f5188211SFan Zhang 418f5188211SFan Zhang if (!options.guest_polling) { 419f5188211SFan Zhang for (k = 0; k < nb_callfds; k++) 420f5188211SFan Zhang eventfd_write(callfds[k], 421f5188211SFan Zhang (eventfd_t)1); 422f5188211SFan Zhang } 423f5188211SFan Zhang 424709521f4SFan Zhang rte_mempool_put_bulk(info->cop_pool, 425f5188211SFan Zhang (void **)ops_deq[j], fetched); 426f5188211SFan Zhang } 427f5188211SFan Zhang } 428f5188211SFan Zhang } 429f5188211SFan Zhang exit: 430f5188211SFan Zhang return ret; 431f5188211SFan Zhang } 432f5188211SFan Zhang 433f5188211SFan Zhang static void 434709521f4SFan Zhang free_resource(void) 435f5188211SFan Zhang { 436709521f4SFan Zhang uint32_t i, j; 437f5188211SFan Zhang 438709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) { 439709521f4SFan Zhang struct lcore_option *lo = &options.los[i]; 440709521f4SFan Zhang struct vhost_crypto_info *info = options.infos[i]; 441709521f4SFan Zhang 442e1d90eaaSFan Zhang if (!info) 443e1d90eaaSFan Zhang continue; 444e1d90eaaSFan Zhang 445709521f4SFan Zhang rte_mempool_free(info->cop_pool); 446709521f4SFan Zhang rte_mempool_free(info->sess_pool); 447ac5e42daSFan Zhang rte_mempool_free(info->sess_priv_pool); 448709521f4SFan Zhang 449709521f4SFan Zhang for (j = 0; j < lo->nb_sockets; j++) { 450709521f4SFan Zhang rte_vhost_driver_unregister(lo->socket_files[i]); 451709521f4SFan Zhang free(lo->socket_files[i]); 452709521f4SFan Zhang } 453709521f4SFan Zhang 454709521f4SFan Zhang rte_free(info); 455709521f4SFan Zhang } 456709521f4SFan Zhang 457709521f4SFan Zhang memset(&options, 0, sizeof(options)); 458f5188211SFan Zhang } 459f5188211SFan Zhang 460f5188211SFan Zhang int 461f5188211SFan Zhang main(int argc, char *argv[]) 462f5188211SFan Zhang { 463725d2a7fSFan Zhang struct rte_cryptodev_qp_conf qp_conf; 464f5188211SFan Zhang struct rte_cryptodev_config config; 465f5188211SFan Zhang struct rte_cryptodev_info dev_info; 466f5188211SFan Zhang char name[128]; 467709521f4SFan Zhang uint32_t i, j, lcore; 468f5188211SFan Zhang int ret; 469f5188211SFan Zhang 470f5188211SFan Zhang ret = rte_eal_init(argc, argv); 471f5188211SFan Zhang if (ret < 0) 472f5188211SFan Zhang return -1; 473f5188211SFan Zhang argc -= ret; 474f5188211SFan Zhang argv += ret; 475f5188211SFan Zhang 476f5188211SFan Zhang ret = vhost_crypto_parse_args(argc, argv); 477f5188211SFan Zhang if (ret < 0) 478f5188211SFan Zhang rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n"); 479f5188211SFan Zhang 480709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) { 481709521f4SFan Zhang struct lcore_option *lo = &options.los[i]; 482709521f4SFan Zhang struct vhost_crypto_info *info; 483f5188211SFan Zhang 484709521f4SFan Zhang info = rte_zmalloc_socket(NULL, sizeof(*info), 485709521f4SFan Zhang RTE_CACHE_LINE_SIZE, rte_lcore_to_socket_id( 486709521f4SFan Zhang lo->lcore_id)); 487709521f4SFan Zhang if (!info) { 488709521f4SFan Zhang ret = -ENOMEM; 489709521f4SFan Zhang goto error_exit; 490709521f4SFan Zhang } 491f5188211SFan Zhang 492709521f4SFan Zhang info->cid = lo->cid; 493709521f4SFan Zhang info->qid = lo->qid; 494709521f4SFan Zhang info->nb_vids = lo->nb_sockets; 495709521f4SFan Zhang 496709521f4SFan Zhang rte_cryptodev_info_get(info->cid, &dev_info); 497e1d90eaaSFan Zhang if (options.zero_copy == RTE_VHOST_CRYPTO_ZERO_COPY_ENABLE) { 498e1d90eaaSFan Zhang #define VHOST_CRYPTO_CDEV_NAME_AESNI_MB_PMD crypto_aesni_mb 499e1d90eaaSFan Zhang #define VHOST_CRYPTO_CDEV_NAME_AESNI_GCM_PMD crypto_aesni_gcm 500e1d90eaaSFan Zhang if (strstr(dev_info.driver_name, 501e1d90eaaSFan Zhang RTE_STR(VHOST_CRYPTO_CDEV_NAME_AESNI_MB_PMD)) || 502e1d90eaaSFan Zhang strstr(dev_info.driver_name, 50357f9a9fcSFan Zhang RTE_STR(VHOST_CRYPTO_CDEV_NAME_AESNI_GCM_PMD))) { 504e1d90eaaSFan Zhang RTE_LOG(ERR, USER1, "Cannot enable zero-copy in %s\n", 505e1d90eaaSFan Zhang dev_info.driver_name); 506e1d90eaaSFan Zhang ret = -EPERM; 507e1d90eaaSFan Zhang goto error_exit; 508e1d90eaaSFan Zhang } 50957f9a9fcSFan Zhang } 510e1d90eaaSFan Zhang 511709521f4SFan Zhang if (dev_info.max_nb_queue_pairs < info->qid + 1) { 512f5188211SFan Zhang RTE_LOG(ERR, USER1, "Number of queues cannot over %u", 513f5188211SFan Zhang dev_info.max_nb_queue_pairs); 514f5188211SFan Zhang goto error_exit; 515f5188211SFan Zhang } 516f5188211SFan Zhang 517f5188211SFan Zhang config.nb_queue_pairs = dev_info.max_nb_queue_pairs; 518709521f4SFan Zhang config.socket_id = rte_lcore_to_socket_id(lo->lcore_id); 519c9030ae3SAnoob Joseph config.ff_disable = RTE_CRYPTODEV_FF_SECURITY; 520f5188211SFan Zhang 521709521f4SFan Zhang ret = rte_cryptodev_configure(info->cid, &config); 522f5188211SFan Zhang if (ret < 0) { 523f5188211SFan Zhang RTE_LOG(ERR, USER1, "Failed to configure cryptodev %u", 524709521f4SFan Zhang info->cid); 525f5188211SFan Zhang goto error_exit; 526f5188211SFan Zhang } 527f5188211SFan Zhang 528709521f4SFan Zhang snprintf(name, 127, "SESS_POOL_%u", lo->lcore_id); 529ac5e42daSFan Zhang info->sess_pool = rte_cryptodev_sym_session_pool_create(name, 530ac5e42daSFan Zhang SESSION_MAP_ENTRIES, 0, 0, 0, 531ac5e42daSFan Zhang rte_lcore_to_socket_id(lo->lcore_id)); 532ac5e42daSFan Zhang 533ac5e42daSFan Zhang snprintf(name, 127, "SESS_POOL_PRIV_%u", lo->lcore_id); 534ac5e42daSFan Zhang info->sess_priv_pool = rte_mempool_create(name, 535ac5e42daSFan Zhang SESSION_MAP_ENTRIES, 536a106fcceSPablo de Lara rte_cryptodev_sym_get_private_session_size( 537709521f4SFan Zhang info->cid), 64, 0, NULL, NULL, NULL, NULL, 538709521f4SFan Zhang rte_lcore_to_socket_id(lo->lcore_id), 0); 53900479d9cSFan Zhang if (!info->sess_priv_pool || !info->sess_pool) { 540f5188211SFan Zhang RTE_LOG(ERR, USER1, "Failed to create mempool"); 541f5188211SFan Zhang goto error_exit; 542f5188211SFan Zhang } 543f5188211SFan Zhang 544709521f4SFan Zhang snprintf(name, 127, "COPPOOL_%u", lo->lcore_id); 545709521f4SFan Zhang info->cop_pool = rte_crypto_op_pool_create(name, 546f5188211SFan Zhang RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MEMPOOL_OBJS, 54757680e34SFan Zhang NB_CACHE_OBJS, VHOST_CRYPTO_MAX_IV_LEN, 548709521f4SFan Zhang rte_lcore_to_socket_id(lo->lcore_id)); 549f5188211SFan Zhang 550709521f4SFan Zhang if (!info->cop_pool) { 551709521f4SFan Zhang RTE_LOG(ERR, USER1, "Failed to create crypto pool"); 552709521f4SFan Zhang ret = -ENOMEM; 553f5188211SFan Zhang goto error_exit; 554f5188211SFan Zhang } 555f5188211SFan Zhang 556709521f4SFan Zhang options.infos[i] = info; 557f5188211SFan Zhang 558725d2a7fSFan Zhang qp_conf.nb_descriptors = NB_CRYPTO_DESCRIPTORS; 559725d2a7fSFan Zhang qp_conf.mp_session = info->sess_pool; 56000479d9cSFan Zhang qp_conf.mp_session_private = info->sess_priv_pool; 561725d2a7fSFan Zhang 562709521f4SFan Zhang for (j = 0; j < dev_info.max_nb_queue_pairs; j++) { 563709521f4SFan Zhang ret = rte_cryptodev_queue_pair_setup(info->cid, j, 564709521f4SFan Zhang &qp_conf, rte_lcore_to_socket_id( 565725d2a7fSFan Zhang lo->lcore_id)); 566f5188211SFan Zhang if (ret < 0) { 567709521f4SFan Zhang RTE_LOG(ERR, USER1, "Failed to configure qp\n"); 568f5188211SFan Zhang goto error_exit; 569f5188211SFan Zhang } 570f5188211SFan Zhang } 571709521f4SFan Zhang } 572f5188211SFan Zhang 573709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) { 574709521f4SFan Zhang struct lcore_option *lo = &options.los[i]; 575709521f4SFan Zhang struct vhost_crypto_info *info = options.infos[i]; 576709521f4SFan Zhang 577709521f4SFan Zhang ret = rte_cryptodev_start(lo->cid); 578f5188211SFan Zhang if (ret < 0) { 579709521f4SFan Zhang RTE_LOG(ERR, USER1, "Failed to start cryptodev\n"); 580f5188211SFan Zhang goto error_exit; 581f5188211SFan Zhang } 582f5188211SFan Zhang 583709521f4SFan Zhang if (rte_eal_remote_launch(vhost_crypto_worker, info, 584709521f4SFan Zhang lo->lcore_id) < 0) { 585f5188211SFan Zhang RTE_LOG(ERR, USER1, "Failed to start worker lcore"); 586f5188211SFan Zhang goto error_exit; 587f5188211SFan Zhang } 588f5188211SFan Zhang 589709521f4SFan Zhang for (j = 0; j < lo->nb_sockets; j++) { 590709521f4SFan Zhang ret = rte_vhost_driver_register(lo->socket_files[j], 591c08736b3SMaxime Coquelin RTE_VHOST_USER_ASYNC_COPY); 592709521f4SFan Zhang if (ret < 0) { 593f5188211SFan Zhang RTE_LOG(ERR, USER1, "socket %s already exists\n", 594709521f4SFan Zhang lo->socket_files[j]); 595f5188211SFan Zhang goto error_exit; 596f5188211SFan Zhang } 597f5188211SFan Zhang 598709521f4SFan Zhang rte_vhost_driver_callback_register(lo->socket_files[j], 599f5188211SFan Zhang &virtio_crypto_device_ops); 600f5188211SFan Zhang 601ea1b835aSFan Zhang ret = rte_vhost_crypto_driver_start( 602ea1b835aSFan Zhang lo->socket_files[j]); 603709521f4SFan Zhang if (ret < 0) { 604709521f4SFan Zhang RTE_LOG(ERR, USER1, "failed to start vhost.\n"); 605f5188211SFan Zhang goto error_exit; 606f5188211SFan Zhang } 607f5188211SFan Zhang } 608709521f4SFan Zhang } 609f5188211SFan Zhang 610709521f4SFan Zhang RTE_LCORE_FOREACH(lcore) 611709521f4SFan Zhang rte_eal_wait_lcore(lcore); 612f5188211SFan Zhang 613709521f4SFan Zhang free_resource(); 614f5188211SFan Zhang 615f5188211SFan Zhang return 0; 616f5188211SFan Zhang 617f5188211SFan Zhang error_exit: 618f5188211SFan Zhang 619709521f4SFan Zhang free_resource(); 620f5188211SFan Zhang 621f5188211SFan Zhang return -1; 622f5188211SFan Zhang } 623