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 65270054edSIbtisam Tariq enum { 66270054edSIbtisam Tariq #define OPT_CONFIG "config" 67270054edSIbtisam Tariq OPT_CONFIG_NUM = 256, 68270054edSIbtisam Tariq #define OPT_SOCKET_FILE "socket-file" 69270054edSIbtisam Tariq OPT_SOCKET_FILE_NUM, 70270054edSIbtisam Tariq #define OPT_ZERO_COPY "zero-copy" 71270054edSIbtisam Tariq OPT_ZERO_COPY_NUM, 72270054edSIbtisam Tariq #define OPT_POLLING "guest-polling" 73270054edSIbtisam Tariq OPT_POLLING_NUM, 74270054edSIbtisam Tariq }; 75f5188211SFan Zhang 76709521f4SFan Zhang #define NB_SOCKET_FIELDS (2) 77709521f4SFan Zhang 78709521f4SFan Zhang static uint32_t 79709521f4SFan Zhang find_lo(uint32_t lcore_id) 80709521f4SFan Zhang { 81709521f4SFan Zhang uint32_t i; 82709521f4SFan Zhang 83709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) 84709521f4SFan Zhang if (options.los[i].lcore_id == lcore_id) 85709521f4SFan Zhang return i; 86709521f4SFan Zhang 87709521f4SFan Zhang return UINT32_MAX; 88709521f4SFan Zhang } 89f5188211SFan Zhang 90f5188211SFan Zhang /** support *SOCKET_FILE_PATH:CRYPTODEV_ID* format */ 91f5188211SFan Zhang static int 92f5188211SFan Zhang parse_socket_arg(char *arg) 93f5188211SFan Zhang { 94709521f4SFan Zhang uint32_t nb_sockets; 95709521f4SFan Zhang uint32_t lcore_id; 96709521f4SFan Zhang char *str_fld[NB_SOCKET_FIELDS]; 97709521f4SFan Zhang struct lcore_option *lo; 98709521f4SFan Zhang uint32_t idx; 99709521f4SFan Zhang char *end; 100709521f4SFan Zhang 101709521f4SFan Zhang if (rte_strsplit(arg, strlen(arg), str_fld, NB_SOCKET_FIELDS, ',') != 102709521f4SFan Zhang NB_SOCKET_FIELDS) { 103709521f4SFan Zhang RTE_LOG(ERR, USER1, "Invalid socket parameter '%s'\n", arg); 104709521f4SFan Zhang return -EINVAL; 105709521f4SFan Zhang } 106709521f4SFan Zhang 107709521f4SFan Zhang errno = 0; 108709521f4SFan Zhang lcore_id = strtoul(str_fld[0], &end, 0); 109709521f4SFan Zhang if (errno != 0 || end == str_fld[0] || lcore_id > 255) 110709521f4SFan Zhang return -EINVAL; 111709521f4SFan Zhang 112709521f4SFan Zhang idx = find_lo(lcore_id); 113709521f4SFan Zhang if (idx == UINT32_MAX) { 114709521f4SFan Zhang if (options.nb_los == MAX_NB_WORKER_CORES) 115709521f4SFan Zhang return -ENOMEM; 116709521f4SFan Zhang lo = &options.los[options.nb_los]; 117709521f4SFan Zhang lo->lcore_id = lcore_id; 118709521f4SFan Zhang options.nb_los++; 119709521f4SFan Zhang } else 120709521f4SFan Zhang lo = &options.los[idx]; 121709521f4SFan Zhang 122709521f4SFan Zhang nb_sockets = lo->nb_sockets; 123f5188211SFan Zhang 124f5188211SFan Zhang if (nb_sockets >= MAX_NB_SOCKETS) { 125f5188211SFan Zhang RTE_LOG(ERR, USER1, "Too many socket files!\n"); 126f5188211SFan Zhang return -ENOMEM; 127f5188211SFan Zhang } 128f5188211SFan Zhang 129709521f4SFan Zhang lo->socket_files[nb_sockets] = strdup(str_fld[1]); 130709521f4SFan Zhang if (!lo->socket_files[nb_sockets]) { 131f5188211SFan Zhang RTE_LOG(ERR, USER1, "Insufficient memory\n"); 132f5188211SFan Zhang return -ENOMEM; 133f5188211SFan Zhang } 134f5188211SFan Zhang 135709521f4SFan Zhang lo->nb_sockets++; 136f5188211SFan Zhang 137f5188211SFan Zhang return 0; 138f5188211SFan Zhang } 139f5188211SFan Zhang 140f5188211SFan Zhang static int 141709521f4SFan Zhang parse_config(char *q_arg) 142f5188211SFan Zhang { 143709521f4SFan Zhang struct lcore_option *lo; 144709521f4SFan Zhang char s[256]; 145709521f4SFan Zhang const char *p, *p0 = q_arg; 146709521f4SFan Zhang char *end; 147709521f4SFan Zhang enum fieldnames { 148709521f4SFan Zhang FLD_LCORE = 0, 149709521f4SFan Zhang FLD_CID, 150709521f4SFan Zhang FLD_QID, 151709521f4SFan Zhang _NUM_FLD 152709521f4SFan Zhang }; 153709521f4SFan Zhang uint32_t flds[_NUM_FLD]; 154709521f4SFan Zhang char *str_fld[_NUM_FLD]; 155709521f4SFan Zhang uint32_t i; 156709521f4SFan Zhang uint32_t size; 157f5188211SFan Zhang 158709521f4SFan Zhang while ((p = strchr(p0, '(')) != NULL) { 159709521f4SFan Zhang ++p; 160709521f4SFan Zhang p0 = strchr(p, ')'); 161709521f4SFan Zhang if (p0 == NULL) 162f5188211SFan Zhang return -1; 163f5188211SFan Zhang 164709521f4SFan Zhang size = p0 - p; 165709521f4SFan Zhang if (size >= sizeof(s)) 166f5188211SFan Zhang return -1; 167709521f4SFan Zhang 168709521f4SFan Zhang snprintf(s, sizeof(s), "%.*s", size, p); 169709521f4SFan Zhang if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != 170709521f4SFan Zhang _NUM_FLD) 171709521f4SFan Zhang return -1; 172709521f4SFan Zhang for (i = 0; i < _NUM_FLD; i++) { 173709521f4SFan Zhang errno = 0; 174709521f4SFan Zhang flds[i] = strtoul(str_fld[i], &end, 0); 175709521f4SFan Zhang if (errno != 0 || end == str_fld[i] || flds[i] > 255) 176709521f4SFan Zhang return -EINVAL; 177f5188211SFan Zhang } 178f5188211SFan Zhang 179709521f4SFan Zhang if (flds[FLD_LCORE] > RTE_MAX_LCORE) 180709521f4SFan Zhang return -EINVAL; 181709521f4SFan Zhang 182709521f4SFan Zhang i = find_lo(flds[FLD_LCORE]); 183709521f4SFan Zhang if (i == UINT32_MAX) { 184709521f4SFan Zhang if (options.nb_los == MAX_NB_WORKER_CORES) 185709521f4SFan Zhang return -ENOMEM; 186709521f4SFan Zhang lo = &options.los[options.nb_los]; 187709521f4SFan Zhang options.nb_los++; 188709521f4SFan Zhang } else 189709521f4SFan Zhang lo = &options.los[i]; 190709521f4SFan Zhang 191709521f4SFan Zhang lo->lcore_id = flds[FLD_LCORE]; 192709521f4SFan Zhang lo->cid = flds[FLD_CID]; 193709521f4SFan Zhang lo->qid = flds[FLD_QID]; 194709521f4SFan Zhang } 195f5188211SFan Zhang 196f5188211SFan Zhang return 0; 197f5188211SFan Zhang } 198f5188211SFan Zhang 199f5188211SFan Zhang static void 200f5188211SFan Zhang vhost_crypto_usage(const char *prgname) 201f5188211SFan Zhang { 202f5188211SFan Zhang printf("%s [EAL options] --\n" 203709521f4SFan Zhang " --%s <lcore>,SOCKET-FILE-PATH\n" 204854dbee2SIbtisam Tariq " --%s (lcore,cdev_id,queue_id)[,(lcore,cdev_id,queue_id)]\n" 205f5188211SFan Zhang " --%s: zero copy\n" 206f5188211SFan Zhang " --%s: guest polling\n", 207270054edSIbtisam Tariq prgname, OPT_SOCKET_FILE, OPT_CONFIG, 208270054edSIbtisam Tariq OPT_ZERO_COPY, OPT_POLLING); 209f5188211SFan Zhang } 210f5188211SFan Zhang 211f5188211SFan Zhang static int 212f5188211SFan Zhang vhost_crypto_parse_args(int argc, char **argv) 213f5188211SFan Zhang { 214f5188211SFan Zhang int opt, ret; 215f5188211SFan Zhang char *prgname = argv[0]; 216f5188211SFan Zhang char **argvopt; 217f5188211SFan Zhang int option_index; 218f5188211SFan Zhang struct option lgopts[] = { 219270054edSIbtisam Tariq {OPT_SOCKET_FILE, required_argument, 220270054edSIbtisam Tariq NULL, OPT_SOCKET_FILE_NUM}, 221270054edSIbtisam Tariq {OPT_CONFIG, required_argument, 222270054edSIbtisam Tariq NULL, OPT_CONFIG_NUM}, 223270054edSIbtisam Tariq {OPT_ZERO_COPY, no_argument, 224270054edSIbtisam Tariq NULL, OPT_ZERO_COPY_NUM}, 225270054edSIbtisam Tariq {OPT_POLLING, no_argument, 226270054edSIbtisam Tariq NULL, OPT_POLLING_NUM}, 227f5188211SFan Zhang {NULL, 0, 0, 0} 228f5188211SFan Zhang }; 229f5188211SFan Zhang 230f5188211SFan Zhang argvopt = argv; 231f5188211SFan Zhang 232dd0946f9SIbtisam Tariq while ((opt = getopt_long(argc, argvopt, "", 233f5188211SFan Zhang lgopts, &option_index)) != EOF) { 234f5188211SFan Zhang 235270054edSIbtisam Tariq if (opt == '?') { 236270054edSIbtisam Tariq vhost_crypto_usage(prgname); 237270054edSIbtisam Tariq return -1; 238270054edSIbtisam Tariq } 239270054edSIbtisam Tariq 240f5188211SFan Zhang switch (opt) { 241270054edSIbtisam Tariq case OPT_SOCKET_FILE_NUM: 242f5188211SFan Zhang ret = parse_socket_arg(optarg); 243f5188211SFan Zhang if (ret < 0) { 244f5188211SFan Zhang vhost_crypto_usage(prgname); 245f5188211SFan Zhang return ret; 246f5188211SFan Zhang } 247270054edSIbtisam Tariq break; 248270054edSIbtisam Tariq 249270054edSIbtisam Tariq case OPT_CONFIG_NUM: 250709521f4SFan Zhang ret = parse_config(optarg); 251f5188211SFan Zhang if (ret < 0) { 252f5188211SFan Zhang vhost_crypto_usage(prgname); 253f5188211SFan Zhang return ret; 254f5188211SFan Zhang } 255270054edSIbtisam Tariq break; 256270054edSIbtisam Tariq 257270054edSIbtisam Tariq case OPT_ZERO_COPY_NUM: 258f5188211SFan Zhang options.zero_copy = 259f5188211SFan Zhang RTE_VHOST_CRYPTO_ZERO_COPY_ENABLE; 260270054edSIbtisam Tariq break; 261270054edSIbtisam Tariq 262270054edSIbtisam Tariq case OPT_POLLING_NUM: 263f5188211SFan Zhang options.guest_polling = 1; 264270054edSIbtisam Tariq break; 265270054edSIbtisam Tariq 266270054edSIbtisam Tariq default: 267f5188211SFan Zhang vhost_crypto_usage(prgname); 268f5188211SFan Zhang return -EINVAL; 269f5188211SFan Zhang } 270f5188211SFan Zhang } 271f5188211SFan Zhang 272f5188211SFan Zhang return 0; 273f5188211SFan Zhang } 274f5188211SFan Zhang 275f5188211SFan Zhang static int 276f5188211SFan Zhang new_device(int vid) 277f5188211SFan Zhang { 278709521f4SFan Zhang struct vhost_crypto_info *info = NULL; 279f5188211SFan Zhang char path[PATH_MAX]; 280709521f4SFan Zhang uint32_t i, j; 281f5188211SFan Zhang int ret; 282f5188211SFan Zhang 283f5188211SFan Zhang ret = rte_vhost_get_ifname(vid, path, PATH_MAX); 284f5188211SFan Zhang if (ret) { 285f5188211SFan Zhang RTE_LOG(ERR, USER1, "Cannot find matched socket\n"); 286f5188211SFan Zhang return ret; 287f5188211SFan Zhang } 288f5188211SFan Zhang 289709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) { 290709521f4SFan Zhang for (j = 0; j < options.los[i].nb_sockets; j++) { 291709521f4SFan Zhang if (strcmp(path, options.los[i].socket_files[j]) == 0) { 292709521f4SFan Zhang info = options.infos[i]; 293709521f4SFan Zhang break; 294709521f4SFan Zhang } 295709521f4SFan Zhang } 296709521f4SFan Zhang 297709521f4SFan Zhang if (info) 298f5188211SFan Zhang break; 299f5188211SFan Zhang } 300f5188211SFan Zhang 301709521f4SFan Zhang if (!info) { 302f5188211SFan Zhang RTE_LOG(ERR, USER1, "Cannot find recorded socket\n"); 303f5188211SFan Zhang return -ENOENT; 304f5188211SFan Zhang } 305f5188211SFan Zhang 306709521f4SFan Zhang ret = rte_vhost_crypto_create(vid, info->cid, info->sess_pool, 307ac5e42daSFan Zhang info->sess_priv_pool, 308709521f4SFan Zhang rte_lcore_to_socket_id(options.los[i].lcore_id)); 309f5188211SFan Zhang if (ret) { 310f5188211SFan Zhang RTE_LOG(ERR, USER1, "Cannot create vhost crypto\n"); 311f5188211SFan Zhang return ret; 312f5188211SFan Zhang } 313f5188211SFan Zhang 314f5188211SFan Zhang ret = rte_vhost_crypto_set_zero_copy(vid, options.zero_copy); 315f5188211SFan Zhang if (ret) { 316f5188211SFan Zhang RTE_LOG(ERR, USER1, "Cannot %s zero copy feature\n", 317f5188211SFan Zhang options.zero_copy == 1 ? "enable" : "disable"); 318f5188211SFan Zhang return ret; 319f5188211SFan Zhang } 320f5188211SFan Zhang 321709521f4SFan Zhang info->vids[j] = vid; 322709521f4SFan Zhang info->initialized[j] = 1; 323f5188211SFan Zhang 324f5188211SFan Zhang rte_wmb(); 325f5188211SFan Zhang 326f5188211SFan Zhang RTE_LOG(INFO, USER1, "New Vhost-crypto Device %s, Device ID %d\n", path, 327f5188211SFan Zhang vid); 328f5188211SFan Zhang return 0; 329f5188211SFan Zhang } 330f5188211SFan Zhang 331f5188211SFan Zhang static void 332f5188211SFan Zhang destroy_device(int vid) 333f5188211SFan Zhang { 334709521f4SFan Zhang struct vhost_crypto_info *info = NULL; 335709521f4SFan Zhang uint32_t i, j; 336f5188211SFan Zhang 337709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) { 338709521f4SFan Zhang for (j = 0; j < options.los[i].nb_sockets; j++) { 339709521f4SFan Zhang if (options.infos[i]->vids[j] == vid) { 340709521f4SFan Zhang info = options.infos[i]; 341709521f4SFan Zhang break; 342709521f4SFan Zhang } 343709521f4SFan Zhang } 344709521f4SFan Zhang if (info) 345f5188211SFan Zhang break; 346f5188211SFan Zhang } 347f5188211SFan Zhang 348709521f4SFan Zhang if (!info) { 349f5188211SFan Zhang RTE_LOG(ERR, USER1, "Cannot find socket file from list\n"); 350f5188211SFan Zhang return; 351f5188211SFan Zhang } 352f5188211SFan Zhang 353709521f4SFan Zhang do { 354709521f4SFan Zhang 355709521f4SFan Zhang } while (info->nb_inflight_ops); 356709521f4SFan Zhang 357709521f4SFan Zhang info->initialized[j] = 0; 358f5188211SFan Zhang 359f5188211SFan Zhang rte_wmb(); 360f5188211SFan Zhang 361f5188211SFan Zhang rte_vhost_crypto_free(vid); 362f5188211SFan Zhang 363f5188211SFan Zhang RTE_LOG(INFO, USER1, "Vhost Crypto Device %i Removed\n", vid); 364f5188211SFan Zhang } 365f5188211SFan Zhang 366*ab4bb424SMaxime Coquelin static const struct rte_vhost_device_ops virtio_crypto_device_ops = { 367f5188211SFan Zhang .new_device = new_device, 368f5188211SFan Zhang .destroy_device = destroy_device, 369f5188211SFan Zhang }; 370f5188211SFan Zhang 371f5188211SFan Zhang static int 372709521f4SFan Zhang vhost_crypto_worker(void *arg) 373f5188211SFan Zhang { 374f5188211SFan Zhang struct rte_crypto_op *ops[NB_VIRTIO_QUEUES][MAX_PKT_BURST + 1]; 375f5188211SFan Zhang struct rte_crypto_op *ops_deq[NB_VIRTIO_QUEUES][MAX_PKT_BURST + 1]; 376709521f4SFan Zhang struct vhost_crypto_info *info = arg; 377f5188211SFan Zhang uint16_t nb_callfds; 378f5188211SFan Zhang int callfds[VIRTIO_CRYPTO_MAX_NUM_BURST_VQS]; 379f5188211SFan Zhang uint32_t lcore_id = rte_lcore_id(); 380f5188211SFan Zhang uint32_t burst_size = MAX_PKT_BURST; 381f5188211SFan Zhang uint32_t i, j, k; 382f5188211SFan Zhang uint32_t to_fetch, fetched; 383f5188211SFan Zhang 384f5188211SFan Zhang int ret = 0; 385f5188211SFan Zhang 386f5188211SFan Zhang RTE_LOG(INFO, USER1, "Processing on Core %u started\n", lcore_id); 387f5188211SFan Zhang 388f5188211SFan Zhang for (i = 0; i < NB_VIRTIO_QUEUES; i++) { 389709521f4SFan Zhang if (rte_crypto_op_bulk_alloc(info->cop_pool, 390f5188211SFan Zhang RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops[i], 391f5188211SFan Zhang burst_size) < burst_size) { 392f5188211SFan Zhang RTE_LOG(ERR, USER1, "Failed to alloc cops\n"); 393f5188211SFan Zhang ret = -1; 394f5188211SFan Zhang goto exit; 395f5188211SFan Zhang } 396f5188211SFan Zhang } 397f5188211SFan Zhang 398f5188211SFan Zhang while (1) { 399709521f4SFan Zhang for (i = 0; i < info->nb_vids; i++) { 400709521f4SFan Zhang if (unlikely(info->initialized[i] == 0)) 401f5188211SFan Zhang continue; 402f5188211SFan Zhang 403f5188211SFan Zhang for (j = 0; j < NB_VIRTIO_QUEUES; j++) { 404f5188211SFan Zhang to_fetch = RTE_MIN(burst_size, 405f5188211SFan Zhang (NB_CRYPTO_DESCRIPTORS - 406709521f4SFan Zhang info->nb_inflight_ops)); 407f5188211SFan Zhang fetched = rte_vhost_crypto_fetch_requests( 408709521f4SFan Zhang info->vids[i], j, ops[j], 409f5188211SFan Zhang to_fetch); 410709521f4SFan Zhang info->nb_inflight_ops += 411709521f4SFan Zhang rte_cryptodev_enqueue_burst( 412709521f4SFan Zhang info->cid, info->qid, ops[j], 413f5188211SFan Zhang fetched); 414f5188211SFan Zhang if (unlikely(rte_crypto_op_bulk_alloc( 415709521f4SFan Zhang info->cop_pool, 416f5188211SFan Zhang RTE_CRYPTO_OP_TYPE_SYMMETRIC, 417f5188211SFan Zhang ops[j], fetched) < fetched)) { 418f5188211SFan Zhang RTE_LOG(ERR, USER1, "Failed realloc\n"); 419f5188211SFan Zhang return -1; 420f5188211SFan Zhang } 421f5188211SFan Zhang 422f5188211SFan Zhang fetched = rte_cryptodev_dequeue_burst( 423709521f4SFan Zhang info->cid, info->qid, 424f5188211SFan Zhang ops_deq[j], RTE_MIN(burst_size, 425709521f4SFan Zhang info->nb_inflight_ops)); 426f5188211SFan Zhang fetched = rte_vhost_crypto_finalize_requests( 427f5188211SFan Zhang ops_deq[j], fetched, callfds, 428f5188211SFan Zhang &nb_callfds); 429f5188211SFan Zhang 430709521f4SFan Zhang info->nb_inflight_ops -= fetched; 431f5188211SFan Zhang 432f5188211SFan Zhang if (!options.guest_polling) { 433f5188211SFan Zhang for (k = 0; k < nb_callfds; k++) 434f5188211SFan Zhang eventfd_write(callfds[k], 435f5188211SFan Zhang (eventfd_t)1); 436f5188211SFan Zhang } 437f5188211SFan Zhang 438709521f4SFan Zhang rte_mempool_put_bulk(info->cop_pool, 439f5188211SFan Zhang (void **)ops_deq[j], fetched); 440f5188211SFan Zhang } 441f5188211SFan Zhang } 442f5188211SFan Zhang } 443f5188211SFan Zhang exit: 444f5188211SFan Zhang return ret; 445f5188211SFan Zhang } 446f5188211SFan Zhang 447f5188211SFan Zhang static void 448709521f4SFan Zhang free_resource(void) 449f5188211SFan Zhang { 450709521f4SFan Zhang uint32_t i, j; 451f5188211SFan Zhang 452709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) { 453709521f4SFan Zhang struct lcore_option *lo = &options.los[i]; 454709521f4SFan Zhang struct vhost_crypto_info *info = options.infos[i]; 455709521f4SFan Zhang 456e1d90eaaSFan Zhang if (!info) 457e1d90eaaSFan Zhang continue; 458e1d90eaaSFan Zhang 459709521f4SFan Zhang rte_mempool_free(info->cop_pool); 460709521f4SFan Zhang rte_mempool_free(info->sess_pool); 461ac5e42daSFan Zhang rte_mempool_free(info->sess_priv_pool); 462709521f4SFan Zhang 463709521f4SFan Zhang for (j = 0; j < lo->nb_sockets; j++) { 464709521f4SFan Zhang rte_vhost_driver_unregister(lo->socket_files[i]); 465709521f4SFan Zhang free(lo->socket_files[i]); 466709521f4SFan Zhang } 467709521f4SFan Zhang 468709521f4SFan Zhang rte_free(info); 469709521f4SFan Zhang } 470709521f4SFan Zhang 471709521f4SFan Zhang memset(&options, 0, sizeof(options)); 47210aa3757SChengchang Tang 47310aa3757SChengchang Tang /* clean up the EAL */ 47410aa3757SChengchang Tang rte_eal_cleanup(); 475f5188211SFan Zhang } 476f5188211SFan Zhang 477f5188211SFan Zhang int 478f5188211SFan Zhang main(int argc, char *argv[]) 479f5188211SFan Zhang { 480725d2a7fSFan Zhang struct rte_cryptodev_qp_conf qp_conf; 481f5188211SFan Zhang struct rte_cryptodev_config config; 482f5188211SFan Zhang struct rte_cryptodev_info dev_info; 483f5188211SFan Zhang char name[128]; 484709521f4SFan Zhang uint32_t i, j, lcore; 485f5188211SFan Zhang int ret; 486f5188211SFan Zhang 487f5188211SFan Zhang ret = rte_eal_init(argc, argv); 488f5188211SFan Zhang if (ret < 0) 489f5188211SFan Zhang return -1; 490f5188211SFan Zhang argc -= ret; 491f5188211SFan Zhang argv += ret; 492f5188211SFan Zhang 493f5188211SFan Zhang ret = vhost_crypto_parse_args(argc, argv); 494f5188211SFan Zhang if (ret < 0) 495f5188211SFan Zhang rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n"); 496f5188211SFan Zhang 497709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) { 498709521f4SFan Zhang struct lcore_option *lo = &options.los[i]; 499709521f4SFan Zhang struct vhost_crypto_info *info; 500f5188211SFan Zhang 501709521f4SFan Zhang info = rte_zmalloc_socket(NULL, sizeof(*info), 502709521f4SFan Zhang RTE_CACHE_LINE_SIZE, rte_lcore_to_socket_id( 503709521f4SFan Zhang lo->lcore_id)); 504709521f4SFan Zhang if (!info) { 505709521f4SFan Zhang ret = -ENOMEM; 506709521f4SFan Zhang goto error_exit; 507709521f4SFan Zhang } 508f5188211SFan Zhang 509709521f4SFan Zhang info->cid = lo->cid; 510709521f4SFan Zhang info->qid = lo->qid; 511709521f4SFan Zhang info->nb_vids = lo->nb_sockets; 512709521f4SFan Zhang 513709521f4SFan Zhang rte_cryptodev_info_get(info->cid, &dev_info); 514e1d90eaaSFan Zhang if (options.zero_copy == RTE_VHOST_CRYPTO_ZERO_COPY_ENABLE) { 515e1d90eaaSFan Zhang #define VHOST_CRYPTO_CDEV_NAME_AESNI_MB_PMD crypto_aesni_mb 516e1d90eaaSFan Zhang #define VHOST_CRYPTO_CDEV_NAME_AESNI_GCM_PMD crypto_aesni_gcm 517e1d90eaaSFan Zhang if (strstr(dev_info.driver_name, 518e1d90eaaSFan Zhang RTE_STR(VHOST_CRYPTO_CDEV_NAME_AESNI_MB_PMD)) || 519e1d90eaaSFan Zhang strstr(dev_info.driver_name, 52057f9a9fcSFan Zhang RTE_STR(VHOST_CRYPTO_CDEV_NAME_AESNI_GCM_PMD))) { 521e1d90eaaSFan Zhang RTE_LOG(ERR, USER1, "Cannot enable zero-copy in %s\n", 522e1d90eaaSFan Zhang dev_info.driver_name); 523e1d90eaaSFan Zhang ret = -EPERM; 524e1d90eaaSFan Zhang goto error_exit; 525e1d90eaaSFan Zhang } 52657f9a9fcSFan Zhang } 527e1d90eaaSFan Zhang 528709521f4SFan Zhang if (dev_info.max_nb_queue_pairs < info->qid + 1) { 529f5188211SFan Zhang RTE_LOG(ERR, USER1, "Number of queues cannot over %u", 530f5188211SFan Zhang dev_info.max_nb_queue_pairs); 531f5188211SFan Zhang goto error_exit; 532f5188211SFan Zhang } 533f5188211SFan Zhang 534f5188211SFan Zhang config.nb_queue_pairs = dev_info.max_nb_queue_pairs; 535709521f4SFan Zhang config.socket_id = rte_lcore_to_socket_id(lo->lcore_id); 536c9030ae3SAnoob Joseph config.ff_disable = RTE_CRYPTODEV_FF_SECURITY; 537f5188211SFan Zhang 538709521f4SFan Zhang ret = rte_cryptodev_configure(info->cid, &config); 539f5188211SFan Zhang if (ret < 0) { 540f5188211SFan Zhang RTE_LOG(ERR, USER1, "Failed to configure cryptodev %u", 541709521f4SFan Zhang info->cid); 542f5188211SFan Zhang goto error_exit; 543f5188211SFan Zhang } 544f5188211SFan Zhang 545709521f4SFan Zhang snprintf(name, 127, "SESS_POOL_%u", lo->lcore_id); 546ac5e42daSFan Zhang info->sess_pool = rte_cryptodev_sym_session_pool_create(name, 547ac5e42daSFan Zhang SESSION_MAP_ENTRIES, 0, 0, 0, 548ac5e42daSFan Zhang rte_lcore_to_socket_id(lo->lcore_id)); 549ac5e42daSFan Zhang 550ac5e42daSFan Zhang snprintf(name, 127, "SESS_POOL_PRIV_%u", lo->lcore_id); 551ac5e42daSFan Zhang info->sess_priv_pool = rte_mempool_create(name, 552ac5e42daSFan Zhang SESSION_MAP_ENTRIES, 553a106fcceSPablo de Lara rte_cryptodev_sym_get_private_session_size( 554709521f4SFan Zhang info->cid), 64, 0, NULL, NULL, NULL, NULL, 555709521f4SFan Zhang rte_lcore_to_socket_id(lo->lcore_id), 0); 55600479d9cSFan Zhang if (!info->sess_priv_pool || !info->sess_pool) { 557f5188211SFan Zhang RTE_LOG(ERR, USER1, "Failed to create mempool"); 558f5188211SFan Zhang goto error_exit; 559f5188211SFan Zhang } 560f5188211SFan Zhang 561709521f4SFan Zhang snprintf(name, 127, "COPPOOL_%u", lo->lcore_id); 562709521f4SFan Zhang info->cop_pool = rte_crypto_op_pool_create(name, 563f5188211SFan Zhang RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MEMPOOL_OBJS, 56457680e34SFan Zhang NB_CACHE_OBJS, VHOST_CRYPTO_MAX_IV_LEN, 565709521f4SFan Zhang rte_lcore_to_socket_id(lo->lcore_id)); 566f5188211SFan Zhang 567709521f4SFan Zhang if (!info->cop_pool) { 568709521f4SFan Zhang RTE_LOG(ERR, USER1, "Failed to create crypto pool"); 569709521f4SFan Zhang ret = -ENOMEM; 570f5188211SFan Zhang goto error_exit; 571f5188211SFan Zhang } 572f5188211SFan Zhang 573709521f4SFan Zhang options.infos[i] = info; 574f5188211SFan Zhang 575725d2a7fSFan Zhang qp_conf.nb_descriptors = NB_CRYPTO_DESCRIPTORS; 576725d2a7fSFan Zhang qp_conf.mp_session = info->sess_pool; 57700479d9cSFan Zhang qp_conf.mp_session_private = info->sess_priv_pool; 578725d2a7fSFan Zhang 579709521f4SFan Zhang for (j = 0; j < dev_info.max_nb_queue_pairs; j++) { 580709521f4SFan Zhang ret = rte_cryptodev_queue_pair_setup(info->cid, j, 581709521f4SFan Zhang &qp_conf, rte_lcore_to_socket_id( 582725d2a7fSFan Zhang lo->lcore_id)); 583f5188211SFan Zhang if (ret < 0) { 584709521f4SFan Zhang RTE_LOG(ERR, USER1, "Failed to configure qp\n"); 585f5188211SFan Zhang goto error_exit; 586f5188211SFan Zhang } 587f5188211SFan Zhang } 588709521f4SFan Zhang } 589f5188211SFan Zhang 590709521f4SFan Zhang for (i = 0; i < options.nb_los; i++) { 591709521f4SFan Zhang struct lcore_option *lo = &options.los[i]; 592709521f4SFan Zhang struct vhost_crypto_info *info = options.infos[i]; 593709521f4SFan Zhang 594709521f4SFan Zhang ret = rte_cryptodev_start(lo->cid); 595f5188211SFan Zhang if (ret < 0) { 596709521f4SFan Zhang RTE_LOG(ERR, USER1, "Failed to start cryptodev\n"); 597f5188211SFan Zhang goto error_exit; 598f5188211SFan Zhang } 599f5188211SFan Zhang 600709521f4SFan Zhang if (rte_eal_remote_launch(vhost_crypto_worker, info, 601709521f4SFan Zhang lo->lcore_id) < 0) { 602f5188211SFan Zhang RTE_LOG(ERR, USER1, "Failed to start worker lcore"); 603f5188211SFan Zhang goto error_exit; 604f5188211SFan Zhang } 605f5188211SFan Zhang 606709521f4SFan Zhang for (j = 0; j < lo->nb_sockets; j++) { 607709521f4SFan Zhang ret = rte_vhost_driver_register(lo->socket_files[j], 608c08736b3SMaxime Coquelin RTE_VHOST_USER_ASYNC_COPY); 609709521f4SFan Zhang if (ret < 0) { 610f5188211SFan Zhang RTE_LOG(ERR, USER1, "socket %s already exists\n", 611709521f4SFan Zhang lo->socket_files[j]); 612f5188211SFan Zhang goto error_exit; 613f5188211SFan Zhang } 614f5188211SFan Zhang 615709521f4SFan Zhang rte_vhost_driver_callback_register(lo->socket_files[j], 616f5188211SFan Zhang &virtio_crypto_device_ops); 617f5188211SFan Zhang 618ea1b835aSFan Zhang ret = rte_vhost_crypto_driver_start( 619ea1b835aSFan Zhang lo->socket_files[j]); 620709521f4SFan Zhang if (ret < 0) { 621709521f4SFan Zhang RTE_LOG(ERR, USER1, "failed to start vhost.\n"); 622f5188211SFan Zhang goto error_exit; 623f5188211SFan Zhang } 624f5188211SFan Zhang } 625709521f4SFan Zhang } 626f5188211SFan Zhang 627709521f4SFan Zhang RTE_LCORE_FOREACH(lcore) 628709521f4SFan Zhang rte_eal_wait_lcore(lcore); 629f5188211SFan Zhang 630709521f4SFan Zhang free_resource(); 631f5188211SFan Zhang 632f5188211SFan Zhang return 0; 633f5188211SFan Zhang 634f5188211SFan Zhang error_exit: 635f5188211SFan Zhang 636709521f4SFan Zhang free_resource(); 637f5188211SFan Zhang 638f5188211SFan Zhang return -1; 639f5188211SFan Zhang } 640