get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/41396/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 41396,
    "url": "http://patchwork.dpdk.org/api/patches/41396/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20180622123605.10241-1-roy.fan.zhang@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20180622123605.10241-1-roy.fan.zhang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180622123605.10241-1-roy.fan.zhang@intel.com",
    "date": "2018-06-22T12:36:05",
    "name": "examples/vhost_crypto: add multi-core support",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "76bfd1486c285d43a760cca37ea2c8f0bb3ebfbe",
    "submitter": {
        "id": 304,
        "url": "http://patchwork.dpdk.org/api/people/304/?format=api",
        "name": "Fan Zhang",
        "email": "roy.fan.zhang@intel.com"
    },
    "delegate": {
        "id": 2642,
        "url": "http://patchwork.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20180622123605.10241-1-roy.fan.zhang@intel.com/mbox/",
    "series": [
        {
            "id": 207,
            "url": "http://patchwork.dpdk.org/api/series/207/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=207",
            "date": "2018-06-22T12:36:05",
            "name": "examples/vhost_crypto: add multi-core support",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/207/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/41396/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/41396/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 4E37C1B5B5;\n\tFri, 22 Jun 2018 14:45:30 +0200 (CEST)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id DFC661B5B0\n\tfor <dev@dpdk.org>; Fri, 22 Jun 2018 14:45:27 +0200 (CEST)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n\tby fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t22 Jun 2018 05:45:26 -0700",
            "from silpixa00398673.ir.intel.com (HELO\n\tsilpixa00398673.ger.corp.intel.com) ([10.237.223.54])\n\tby fmsmga005.fm.intel.com with ESMTP; 22 Jun 2018 05:45:16 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.51,257,1526367600\"; d=\"scan'208\";a=\"239393424\"",
        "From": "Fan Zhang <roy.fan.zhang@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "maxime.coquelin@redhat.com",
        "Date": "Fri, 22 Jun 2018 13:36:05 +0100",
        "Message-Id": "<20180622123605.10241-1-roy.fan.zhang@intel.com>",
        "X-Mailer": "git-send-email 2.13.6",
        "Subject": "[dpdk-dev] [PATCH] examples/vhost_crypto: add multi-core support",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Originally vhost_crypto sample application only supports single\ncore. This patch adds the multi-core support with more flexible\noptions.\n\nSigned-off-by: Fan Zhang <roy.fan.zhang@intel.com>\n---\n doc/guides/sample_app_ug/vhost_crypto.rst |  26 +-\n examples/vhost_crypto/main.c              | 480 +++++++++++++++++-------------\n 2 files changed, 282 insertions(+), 224 deletions(-)",
    "diff": "diff --git a/doc/guides/sample_app_ug/vhost_crypto.rst b/doc/guides/sample_app_ug/vhost_crypto.rst\nindex 65c86a534..3db57eab9 100644\n--- a/doc/guides/sample_app_ug/vhost_crypto.rst\n+++ b/doc/guides/sample_app_ug/vhost_crypto.rst\n@@ -28,24 +28,22 @@ Start the vhost_crypto example\n \n .. code-block:: console\n \n-    ./vhost_crypto [EAL options] -- [--socket-file PATH]\n-        [--cdev-id ID] [--cdev-queue-id ID] [--zero-copy] [--guest-polling]\n+    ./vhost_crypto [EAL options] --\n+    \t\t--config (lcore,cdev-id,queue-id)[,(lcore,cdev-id,queue-id)]\n+    \t\t--socketfile lcore,PATH\n+    \t\t[--zero-copy]\n+    \t\t[--guest-polling]\n \n where,\n \n-* socket-file PATH: the path of UNIX socket file to be created, multiple\n-  instances of this config item is supported. Upon absence of this item,\n-  the default socket-file `/tmp/vhost_crypto1.socket` is used.\n+* config (lcore,cdev-id,queue-id): build the lcore-cryptodev id-queue id\n+  connection. Once specified, the specified lcore will only work with\n+  specified cryptodev's queue.\n \n-* cdev-id ID: the target DPDK Cryptodev's ID to process the actual crypto\n-  workload. Upon absence of this item the default value of `0` will be used.\n-  For details of DPDK Cryptodev, please refer to DPDK Cryptodev Library\n-  Programmers' Guide.\n-\n-* cdev-queue-id ID: the target DPDK Cryptodev's queue ID to process the\n-  actual crypto workload. Upon absence of this item the default value of `0`\n-  will be used. For details of DPDK Cryptodev, please refer to DPDK Cryptodev\n-  Library Programmers' Guide.\n+* socket-file lcore,PATH: the path of UNIX socket file to be created and\n+  the lcore id that will deal with the all workloads of the socket. Multiple\n+  instances of this config item is supported and one lcore supports processing\n+  multiple sockets.\n \n * zero-copy: the presence of this item means the ZERO-COPY feature will be\n   enabled. Otherwise it is disabled. PLEASE NOTE the ZERO-COPY feature is still\ndiff --git a/examples/vhost_crypto/main.c b/examples/vhost_crypto/main.c\nindex f334d7123..cbb5e49d2 100644\n--- a/examples/vhost_crypto/main.c\n+++ b/examples/vhost_crypto/main.c\n@@ -14,6 +14,7 @@\n #include <rte_vhost.h>\n #include <rte_cryptodev.h>\n #include <rte_vhost_crypto.h>\n+#include <rte_string_fns.h>\n \n #include <cmdline_rdline.h>\n #include <cmdline_parse.h>\n@@ -29,97 +30,161 @@\n #define SESSION_MAP_ENTRIES\t\t(1024)\n #define REFRESH_TIME_SEC\t\t(3)\n \n-#define MAX_NB_SOCKETS\t\t\t(32)\n-#define DEF_SOCKET_FILE\t\t\t\"/tmp/vhost_crypto1.socket\"\n+#define MAX_NB_SOCKETS\t\t\t(4)\n+#define MAX_NB_WORKER_CORES\t\t(16)\n \n-struct vhost_crypto_options {\n+struct lcore_option {\n+\tuint32_t lcore_id;\n \tchar *socket_files[MAX_NB_SOCKETS];\n \tuint32_t nb_sockets;\n \tuint8_t cid;\n \tuint16_t qid;\n-\tuint32_t zero_copy;\n-\tuint32_t guest_polling;\n-} options;\n+};\n \n struct vhost_crypto_info {\n \tint vids[MAX_NB_SOCKETS];\n+\tuint32_t nb_vids;\n \tstruct rte_mempool *sess_pool;\n \tstruct rte_mempool *cop_pool;\n-\tuint32_t lcore_id;\n \tuint8_t cid;\n \tuint32_t qid;\n-\tuint32_t nb_vids;\n+\tuint32_t nb_inflight_ops;\n \tvolatile uint32_t initialized[MAX_NB_SOCKETS];\n+} __rte_cache_aligned;\n \n-} info;\n+struct vhost_crypto_options {\n+\tstruct lcore_option los[MAX_NB_WORKER_CORES];\n+\tstruct vhost_crypto_info *infos[MAX_NB_WORKER_CORES];\n+\tuint32_t nb_los;\n+\tuint32_t zero_copy;\n+\tuint32_t guest_polling;\n+} options;\n \n+#define CONFIG_KEYWORD\t\t\"config\"\n #define SOCKET_FILE_KEYWORD\t\"socket-file\"\n-#define CRYPTODEV_ID_KEYWORD\t\"cdev-id\"\n-#define CRYPTODEV_QUEUE_KEYWORD\t\"cdev-queue-id\"\n #define ZERO_COPY_KEYWORD\t\"zero-copy\"\n #define POLLING_KEYWORD\t\t\"guest-polling\"\n \n-uint64_t vhost_cycles[2], last_v_cycles[2];\n-uint64_t outpkt_amount;\n+#define NB_SOCKET_FIELDS\t(2)\n+\n+static uint32_t\n+find_lo(uint32_t lcore_id)\n+{\n+\tuint32_t i;\n+\n+\tfor (i = 0; i < options.nb_los; i++)\n+\t\tif (options.los[i].lcore_id == lcore_id)\n+\t\t\treturn i;\n+\n+\treturn UINT32_MAX;\n+}\n \n /** support *SOCKET_FILE_PATH:CRYPTODEV_ID* format */\n static int\n parse_socket_arg(char *arg)\n {\n-\tuint32_t nb_sockets = options.nb_sockets;\n-\tsize_t len = strlen(arg);\n+\tuint32_t nb_sockets;\n+\tuint32_t lcore_id;\n+\tchar *str_fld[NB_SOCKET_FIELDS];\n+\tstruct lcore_option *lo;\n+\tuint32_t idx;\n+\tchar *end;\n+\n+\tif (rte_strsplit(arg, strlen(arg), str_fld, NB_SOCKET_FIELDS, ',') !=\n+\t\t\t\tNB_SOCKET_FIELDS) {\n+\t\tRTE_LOG(ERR, USER1, \"Invalid socket parameter '%s'\\n\", arg);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\terrno = 0;\n+\tlcore_id = strtoul(str_fld[0], &end, 0);\n+\tif (errno != 0 || end == str_fld[0] || lcore_id > 255)\n+\t\treturn -EINVAL;\n+\n+\tidx = find_lo(lcore_id);\n+\tif (idx == UINT32_MAX) {\n+\t\tif (options.nb_los == MAX_NB_WORKER_CORES)\n+\t\t\treturn -ENOMEM;\n+\t\tlo = &options.los[options.nb_los];\n+\t\tlo->lcore_id = lcore_id;\n+\t\toptions.nb_los++;\n+\t} else\n+\t\tlo = &options.los[idx];\n+\n+\tnb_sockets = lo->nb_sockets;\n \n \tif (nb_sockets >= MAX_NB_SOCKETS) {\n \t\tRTE_LOG(ERR, USER1, \"Too many socket files!\\n\");\n \t\treturn -ENOMEM;\n \t}\n \n-\toptions.socket_files[nb_sockets] = rte_malloc(NULL, len, 0);\n-\tif (!options.socket_files[nb_sockets]) {\n+\tlo->socket_files[nb_sockets] = strdup(str_fld[1]);\n+\tif (!lo->socket_files[nb_sockets]) {\n \t\tRTE_LOG(ERR, USER1, \"Insufficient memory\\n\");\n \t\treturn -ENOMEM;\n \t}\n \n-\trte_memcpy(options.socket_files[nb_sockets], arg, len);\n-\n-\toptions.nb_sockets++;\n+\tlo->nb_sockets++;\n \n \treturn 0;\n }\n \n static int\n-parse_cryptodev_id(const char *q_arg)\n+parse_config(char *q_arg)\n {\n-\tchar *end = NULL;\n-\tuint64_t pm;\n-\n-\t/* parse decimal string */\n-\tpm = strtoul(q_arg, &end, 10);\n-\tif (pm > rte_cryptodev_count()) {\n-\t\tRTE_LOG(ERR, USER1, \"Invalid Cryptodev ID %s\\n\", q_arg);\n-\t\treturn -1;\n-\t}\n+\tstruct lcore_option *lo;\n+\tchar s[256];\n+\tconst char *p, *p0 = q_arg;\n+\tchar *end;\n+\tenum fieldnames {\n+\t\tFLD_LCORE = 0,\n+\t\tFLD_CID,\n+\t\tFLD_QID,\n+\t\t_NUM_FLD\n+\t};\n+\tuint32_t flds[_NUM_FLD];\n+\tchar *str_fld[_NUM_FLD];\n+\tuint32_t i;\n+\tuint32_t size;\n \n-\toptions.cid = (uint8_t)pm;\n+\twhile ((p = strchr(p0, '(')) != NULL) {\n+\t\t++p;\n+\t\tp0 = strchr(p, ')');\n+\t\tif (p0 == NULL)\n+\t\t\treturn -1;\n \n-\treturn 0;\n-}\n+\t\tsize = p0 - p;\n+\t\tif (size >= sizeof(s))\n+\t\t\treturn -1;\n \n-static int\n-parse_cdev_queue_id(const char *q_arg)\n-{\n-\tchar *end = NULL;\n-\tuint64_t pm;\n+\t\tsnprintf(s, sizeof(s), \"%.*s\", size, p);\n+\t\tif (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') !=\n+\t\t\t\t_NUM_FLD)\n+\t\t\treturn -1;\n+\t\tfor (i = 0; i < _NUM_FLD; i++) {\n+\t\t\terrno = 0;\n+\t\t\tflds[i] = strtoul(str_fld[i], &end, 0);\n+\t\t\tif (errno != 0 || end == str_fld[i] || flds[i] > 255)\n+\t\t\t\treturn -EINVAL;\n+\t\t}\n \n-\t/* parse decimal string */\n-\tpm = strtoul(q_arg, &end, 10);\n-\tif (pm == UINT64_MAX) {\n-\t\tRTE_LOG(ERR, USER1, \"Invalid Cryptodev Queue ID %s\\n\", q_arg);\n-\t\treturn -1;\n+\t\tif (flds[FLD_LCORE] > RTE_MAX_LCORE)\n+\t\t\treturn -EINVAL;\n+\n+\t\ti = find_lo(flds[FLD_LCORE]);\n+\t\tif (i == UINT32_MAX) {\n+\t\t\tif (options.nb_los == MAX_NB_WORKER_CORES)\n+\t\t\t\treturn -ENOMEM;\n+\t\t\tlo = &options.los[options.nb_los];\n+\t\t\toptions.nb_los++;\n+\t\t} else\n+\t\t\tlo = &options.los[i];\n+\n+\t\tlo->lcore_id = flds[FLD_LCORE];\n+\t\tlo->cid = flds[FLD_CID];\n+\t\tlo->qid = flds[FLD_QID];\n \t}\n \n-\toptions.qid = (uint16_t)pm;\n-\n \treturn 0;\n }\n \n@@ -127,13 +192,12 @@ static void\n vhost_crypto_usage(const char *prgname)\n {\n \tprintf(\"%s [EAL options] --\\n\"\n-\t\t\"  --%s SOCKET-FILE-PATH\\n\"\n-\t\t\"  --%s CRYPTODEV_ID: crypto device id\\n\"\n-\t\t\"  --%s CDEV_QUEUE_ID: crypto device queue id\\n\"\n+\t\t\"  --%s <lcore>,SOCKET-FILE-PATH\\n\"\n+\t\t\"  --%s (lcore,cdev_id,queue_id)[,(lcore,cdev_id,queue_id)]\"\n \t\t\"  --%s: zero copy\\n\"\n \t\t\"  --%s: guest polling\\n\",\n-\t\tprgname, SOCKET_FILE_KEYWORD, CRYPTODEV_ID_KEYWORD,\n-\t\tCRYPTODEV_QUEUE_KEYWORD, ZERO_COPY_KEYWORD, POLLING_KEYWORD);\n+\t\tprgname, SOCKET_FILE_KEYWORD, CONFIG_KEYWORD,\n+\t\tZERO_COPY_KEYWORD, POLLING_KEYWORD);\n }\n \n static int\n@@ -145,19 +209,12 @@ vhost_crypto_parse_args(int argc, char **argv)\n \tint option_index;\n \tstruct option lgopts[] = {\n \t\t\t{SOCKET_FILE_KEYWORD, required_argument, 0, 0},\n-\t\t\t{CRYPTODEV_ID_KEYWORD, required_argument, 0, 0},\n-\t\t\t{CRYPTODEV_QUEUE_KEYWORD, required_argument, 0, 0},\n+\t\t\t{CONFIG_KEYWORD, required_argument, 0, 0},\n \t\t\t{ZERO_COPY_KEYWORD, no_argument, 0, 0},\n \t\t\t{POLLING_KEYWORD, no_argument, 0, 0},\n \t\t\t{NULL, 0, 0, 0}\n \t};\n \n-\toptions.cid = 0;\n-\toptions.qid = 0;\n-\toptions.nb_sockets = 0;\n-\toptions.guest_polling = 0;\n-\toptions.zero_copy = RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE;\n-\n \targvopt = argv;\n \n \twhile ((opt = getopt_long(argc, argvopt, \"s:\",\n@@ -173,15 +230,8 @@ vhost_crypto_parse_args(int argc, char **argv)\n \t\t\t\t\treturn ret;\n \t\t\t\t}\n \t\t\t} else if (strcmp(lgopts[option_index].name,\n-\t\t\t\t\tCRYPTODEV_ID_KEYWORD) == 0) {\n-\t\t\t\tret = parse_cryptodev_id(optarg);\n-\t\t\t\tif (ret < 0) {\n-\t\t\t\t\tvhost_crypto_usage(prgname);\n-\t\t\t\t\treturn ret;\n-\t\t\t\t}\n-\t\t\t} else if (strcmp(lgopts[option_index].name,\n-\t\t\t\t\tCRYPTODEV_QUEUE_KEYWORD) == 0) {\n-\t\t\t\tret = parse_cdev_queue_id(optarg);\n+\t\t\t\t\tCONFIG_KEYWORD) == 0) {\n+\t\t\t\tret = parse_config(optarg);\n \t\t\t\tif (ret < 0) {\n \t\t\t\t\tvhost_crypto_usage(prgname);\n \t\t\t\t\treturn ret;\n@@ -203,22 +253,15 @@ vhost_crypto_parse_args(int argc, char **argv)\n \t\t}\n \t}\n \n-\tif (options.nb_sockets == 0) {\n-\t\toptions.socket_files[0] = strdup(DEF_SOCKET_FILE);\n-\t\toptions.nb_sockets = 1;\n-\t\tRTE_LOG(INFO, USER1,\n-\t\t\t\t\"VHOST-CRYPTO: use default socket file %s\\n\",\n-\t\t\t\tDEF_SOCKET_FILE);\n-\t}\n-\n \treturn 0;\n }\n \n static int\n new_device(int vid)\n {\n+\tstruct vhost_crypto_info *info = NULL;\n \tchar path[PATH_MAX];\n-\tuint32_t idx, i;\n+\tuint32_t i, j;\n \tint ret;\n \n \tret = rte_vhost_get_ifname(vid, path, PATH_MAX);\n@@ -227,23 +270,25 @@ new_device(int vid)\n \t\treturn ret;\n \t}\n \n-\tfor (idx = 0; idx < options.nb_sockets; idx++) {\n-\t\tif (strcmp(path, options.socket_files[idx]) == 0)\n+\tfor (i = 0; i < options.nb_los; i++) {\n+\t\tfor (j = 0; j < options.los[i].nb_sockets; j++) {\n+\t\t\tif (strcmp(path, options.los[i].socket_files[j]) == 0) {\n+\t\t\t\tinfo = options.infos[i];\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (info)\n \t\t\tbreak;\n \t}\n \n-\tif (idx == options.nb_sockets) {\n+\tif (!info) {\n \t\tRTE_LOG(ERR, USER1, \"Cannot find recorded socket\\n\");\n \t\treturn -ENOENT;\n \t}\n \n-\tfor (i = 0; i < 2; i++) {\n-\t\tvhost_cycles[i] = 0;\n-\t\tlast_v_cycles[i] = 0;\n-\t}\n-\n-\tret = rte_vhost_crypto_create(vid, info.cid, info.sess_pool,\n-\t\t\trte_lcore_to_socket_id(info.lcore_id));\n+\tret = rte_vhost_crypto_create(vid, info->cid, info->sess_pool,\n+\t\t\trte_lcore_to_socket_id(options.los[i].lcore_id));\n \tif (ret) {\n \t\tRTE_LOG(ERR, USER1, \"Cannot create vhost crypto\\n\");\n \t\treturn ret;\n@@ -256,8 +301,8 @@ new_device(int vid)\n \t\treturn ret;\n \t}\n \n-\tinfo.vids[idx] = vid;\n-\tinfo.initialized[idx] = 1;\n+\tinfo->vids[j] = vid;\n+\tinfo->initialized[j] = 1;\n \n \trte_wmb();\n \n@@ -269,19 +314,30 @@ new_device(int vid)\n static void\n destroy_device(int vid)\n {\n-\tuint32_t i;\n-\n-\tfor (i = 0; i < info.nb_vids; i++) {\n-\t\tif (vid == info.vids[i])\n+\tstruct vhost_crypto_info *info = NULL;\n+\tuint32_t i, j;\n+\n+\tfor (i = 0; i < options.nb_los; i++) {\n+\t\tfor (j = 0; j < options.los[i].nb_sockets; j++) {\n+\t\t\tif (options.infos[i]->vids[j] == vid) {\n+\t\t\t\tinfo = options.infos[i];\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\tif (info)\n \t\t\tbreak;\n \t}\n \n-\tif (i == info.nb_vids) {\n+\tif (!info) {\n \t\tRTE_LOG(ERR, USER1, \"Cannot find socket file from list\\n\");\n \t\treturn;\n \t}\n \n-\tinfo.initialized[i] = 0;\n+\tdo {\n+\n+\t} while (info->nb_inflight_ops);\n+\n+\tinfo->initialized[j] = 0;\n \n \trte_wmb();\n \n@@ -302,25 +358,24 @@ static void clrscr(void)\n }\n \n static int\n-vhost_crypto_worker(__rte_unused void *arg)\n+vhost_crypto_worker(void *arg)\n {\n \tstruct rte_crypto_op *ops[NB_VIRTIO_QUEUES][MAX_PKT_BURST + 1];\n \tstruct rte_crypto_op *ops_deq[NB_VIRTIO_QUEUES][MAX_PKT_BURST + 1];\n-\tuint32_t nb_inflight_ops = 0;\n+\tstruct vhost_crypto_info *info = arg;\n \tuint16_t nb_callfds;\n \tint callfds[VIRTIO_CRYPTO_MAX_NUM_BURST_VQS];\n \tuint32_t lcore_id = rte_lcore_id();\n \tuint32_t burst_size = MAX_PKT_BURST;\n \tuint32_t i, j, k;\n \tuint32_t to_fetch, fetched;\n-\tuint64_t t_start, t_end, interval;\n \n \tint ret = 0;\n \n \tRTE_LOG(INFO, USER1, \"Processing on Core %u started\\n\", lcore_id);\n \n \tfor (i = 0; i < NB_VIRTIO_QUEUES; i++) {\n-\t\tif (rte_crypto_op_bulk_alloc(info.cop_pool,\n+\t\tif (rte_crypto_op_bulk_alloc(info->cop_pool,\n \t\t\t\tRTE_CRYPTO_OP_TYPE_SYMMETRIC, ops[i],\n \t\t\t\tburst_size) < burst_size) {\n \t\t\tRTE_LOG(ERR, USER1, \"Failed to alloc cops\\n\");\n@@ -330,45 +385,38 @@ vhost_crypto_worker(__rte_unused void *arg)\n \t}\n \n \twhile (1) {\n-\t\tfor (i = 0; i < info.nb_vids; i++) {\n-\t\t\tif (unlikely(info.initialized[i] == 0))\n+\t\tfor (i = 0; i < info->nb_vids; i++) {\n+\t\t\tif (unlikely(info->initialized[i] == 0))\n \t\t\t\tcontinue;\n \n \t\t\tfor (j = 0; j < NB_VIRTIO_QUEUES; j++) {\n-\t\t\t\tt_start = rte_rdtsc_precise();\n-\n \t\t\t\tto_fetch = RTE_MIN(burst_size,\n \t\t\t\t\t\t(NB_CRYPTO_DESCRIPTORS -\n-\t\t\t\t\t\tnb_inflight_ops));\n+\t\t\t\t\t\tinfo->nb_inflight_ops));\n \t\t\t\tfetched = rte_vhost_crypto_fetch_requests(\n-\t\t\t\t\t\tinfo.vids[i], j, ops[j],\n+\t\t\t\t\t\tinfo->vids[i], j, ops[j],\n \t\t\t\t\t\tto_fetch);\n-\t\t\t\tnb_inflight_ops += rte_cryptodev_enqueue_burst(\n-\t\t\t\t\t\tinfo.cid, info.qid, ops[j],\n+\t\t\t\tinfo->nb_inflight_ops +=\n+\t\t\t\t\t\trte_cryptodev_enqueue_burst(\n+\t\t\t\t\t\tinfo->cid, info->qid, ops[j],\n \t\t\t\t\t\tfetched);\n \t\t\t\tif (unlikely(rte_crypto_op_bulk_alloc(\n-\t\t\t\t\t\tinfo.cop_pool,\n+\t\t\t\t\t\tinfo->cop_pool,\n \t\t\t\t\t\tRTE_CRYPTO_OP_TYPE_SYMMETRIC,\n \t\t\t\t\t\tops[j], fetched) < fetched)) {\n \t\t\t\t\tRTE_LOG(ERR, USER1, \"Failed realloc\\n\");\n \t\t\t\t\treturn -1;\n \t\t\t\t}\n-\t\t\t\tt_end = rte_rdtsc_precise();\n-\t\t\t\tinterval = t_end - t_start;\n-\n-\t\t\t\tvhost_cycles[fetched > 0] += interval;\n \n-\t\t\t\tt_start = t_end;\n \t\t\t\tfetched = rte_cryptodev_dequeue_burst(\n-\t\t\t\t\t\tinfo.cid, info.qid,\n+\t\t\t\t\t\tinfo->cid, info->qid,\n \t\t\t\t\t\tops_deq[j], RTE_MIN(burst_size,\n-\t\t\t\t\t\tnb_inflight_ops));\n+\t\t\t\t\t\tinfo->nb_inflight_ops));\n \t\t\t\tfetched = rte_vhost_crypto_finalize_requests(\n \t\t\t\t\t\tops_deq[j], fetched, callfds,\n \t\t\t\t\t\t&nb_callfds);\n \n-\t\t\t\tnb_inflight_ops -= fetched;\n-\t\t\t\toutpkt_amount += fetched;\n+\t\t\t\tinfo->nb_inflight_ops -= fetched;\n \n \t\t\t\tif (!options.guest_polling) {\n \t\t\t\t\tfor (k = 0; k < nb_callfds; k++)\n@@ -376,11 +424,8 @@ vhost_crypto_worker(__rte_unused void *arg)\n \t\t\t\t\t\t\t\t(eventfd_t)1);\n \t\t\t\t}\n \n-\t\t\t\trte_mempool_put_bulk(info.cop_pool,\n+\t\t\t\trte_mempool_put_bulk(info->cop_pool,\n \t\t\t\t\t\t(void **)ops_deq[j], fetched);\n-\t\t\t\tinterval = rte_rdtsc_precise() - t_start;\n-\n-\t\t\t\tvhost_cycles[fetched > 0] += interval;\n \t\t\t}\n \t\t}\n \t}\n@@ -388,17 +433,27 @@ vhost_crypto_worker(__rte_unused void *arg)\n \treturn ret;\n }\n \n-\n static void\n-unregister_drivers(int socket_num)\n+free_resource(void)\n {\n-\tint ret;\n+\tuint32_t i, j;\n+\n+\tfor (i = 0; i < options.nb_los; i++) {\n+\t\tstruct lcore_option *lo = &options.los[i];\n+\t\tstruct vhost_crypto_info *info = options.infos[i];\n+\n+\t\trte_mempool_free(info->cop_pool);\n+\t\trte_mempool_free(info->sess_pool);\n+\n+\t\tfor (j = 0; j < lo->nb_sockets; j++) {\n+\t\t\trte_vhost_driver_unregister(lo->socket_files[i]);\n+\t\t\tfree(lo->socket_files[i]);\n+\t\t}\n+\n+\t\trte_free(info);\n+\t}\n \n-\tret = rte_vhost_driver_unregister(options.socket_files[socket_num]);\n-\tif (ret != 0)\n-\t\tRTE_LOG(ERR, USER1,\n-\t\t\t\"Fail to unregister vhost driver for %s.\\n\",\n-\t\t\toptions.socket_files[socket_num]);\n+\tmemset(&options, 0, sizeof(options));\n }\n \n int\n@@ -407,10 +462,8 @@ main(int argc, char *argv[])\n \tstruct rte_cryptodev_qp_conf qp_conf = {NB_CRYPTO_DESCRIPTORS};\n \tstruct rte_cryptodev_config config;\n \tstruct rte_cryptodev_info dev_info;\n-\tuint32_t cryptodev_id;\n-\tuint32_t worker_lcore;\n \tchar name[128];\n-\tuint32_t i = 0;\n+\tuint32_t i, j, lcore;\n \tint ret;\n \n \tret = rte_eal_init(argc, argv);\n@@ -423,114 +476,121 @@ main(int argc, char *argv[])\n \tif (ret < 0)\n \t\trte_exit(EXIT_FAILURE, \"Failed to parse arguments!\\n\");\n \n-\tinfo.cid = options.cid;\n-\tinfo.qid = options.qid;\n+\tfor (i = 0; i < options.nb_los; i++) {\n+\t\tstruct lcore_option *lo = &options.los[i];\n+\t\tstruct vhost_crypto_info *info;\n \n-\tworker_lcore = rte_get_next_lcore(0, 1, 0);\n-\tif (worker_lcore == RTE_MAX_LCORE)\n-\t\trte_exit(EXIT_FAILURE, \"Not enough lcore\\n\");\n-\n-\tcryptodev_id = info.cid;\n-\trte_cryptodev_info_get(cryptodev_id, &dev_info);\n-\tif (dev_info.max_nb_queue_pairs < info.qid + 1) {\n-\t\tRTE_LOG(ERR, USER1, \"Number of queues cannot over %u\",\n-\t\t\t\tdev_info.max_nb_queue_pairs);\n-\t\tgoto error_exit;\n-\t}\n+\t\tinfo = rte_zmalloc_socket(NULL, sizeof(*info),\n+\t\t\t\tRTE_CACHE_LINE_SIZE, rte_lcore_to_socket_id(\n+\t\t\t\t\t\tlo->lcore_id));\n+\t\tif (!info) {\n+\t\t\tret = -ENOMEM;\n+\t\t\tgoto error_exit;\n+\t\t}\n \n-\tconfig.nb_queue_pairs = dev_info.max_nb_queue_pairs;\n-\tconfig.socket_id = rte_lcore_to_socket_id(worker_lcore);\n+\t\tinfo->cid = lo->cid;\n+\t\tinfo->qid = lo->qid;\n+\t\tinfo->nb_vids = lo->nb_sockets;\n \n-\tret = rte_cryptodev_configure(cryptodev_id, &config);\n-\tif (ret < 0) {\n-\t\tRTE_LOG(ERR, USER1, \"Failed to configure cryptodev %u\",\n-\t\t\t\tcryptodev_id);\n-\t\tgoto error_exit;\n-\t}\n+\t\trte_cryptodev_info_get(info->cid, &dev_info);\n+\t\tif (dev_info.max_nb_queue_pairs < info->qid + 1) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Number of queues cannot over %u\",\n+\t\t\t\t\tdev_info.max_nb_queue_pairs);\n+\t\t\tgoto error_exit;\n+\t\t}\n \n-\tsnprintf(name, 127, \"SESS_POOL_%u\", worker_lcore);\n-\tinfo.sess_pool = rte_mempool_create(name, SESSION_MAP_ENTRIES,\n-\t\t\trte_cryptodev_sym_get_private_session_size(\n-\t\t\tcryptodev_id), 64, 0, NULL, NULL, NULL, NULL,\n-\t\t\trte_lcore_to_socket_id(worker_lcore), 0);\n-\tif (!info.sess_pool) {\n-\t\tRTE_LOG(ERR, USER1, \"Failed to create mempool\");\n-\t\tgoto error_exit;\n-\t}\n+\t\tconfig.nb_queue_pairs = dev_info.max_nb_queue_pairs;\n+\t\tconfig.socket_id = rte_lcore_to_socket_id(lo->lcore_id);\n \n-\tsnprintf(name, 127, \"COPPOOL_%u\", worker_lcore);\n-\tinfo.cop_pool = rte_crypto_op_pool_create(name,\n-\t\t\tRTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MEMPOOL_OBJS,\n-\t\t\tNB_CACHE_OBJS, 0, rte_lcore_to_socket_id(worker_lcore));\n+\t\tret = rte_cryptodev_configure(info->cid, &config);\n+\t\tif (ret < 0) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Failed to configure cryptodev %u\",\n+\t\t\t\t\tinfo->cid);\n+\t\t\tgoto error_exit;\n+\t\t}\n \n-\tif (!info.cop_pool) {\n-\t\tRTE_LOG(ERR, USER1, \"Lcore %u failed to create crypto pool\",\n-\t\t\t\tworker_lcore);\n-\t\tret = -1;\n-\t\tgoto error_exit;\n-\t}\n+\t\tsnprintf(name, 127, \"SESS_POOL_%u\", lo->lcore_id);\n+\t\tinfo->sess_pool = rte_mempool_create(name, SESSION_MAP_ENTRIES,\n+\t\t\t\trte_cryptodev_sym_get_private_session_size(\n+\t\t\t\tinfo->cid), 64, 0, NULL, NULL, NULL, NULL,\n+\t\t\t\trte_lcore_to_socket_id(lo->lcore_id), 0);\n+\t\tif (!info->sess_pool) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Failed to create mempool\");\n+\t\t\tgoto error_exit;\n+\t\t}\n \n-\tinfo.nb_vids = options.nb_sockets;\n-\tfor (i = 0; i < MAX_NB_SOCKETS; i++)\n-\t\tinfo.vids[i] = -1;\n+\t\tsnprintf(name, 127, \"COPPOOL_%u\", lo->lcore_id);\n+\t\tinfo->cop_pool = rte_crypto_op_pool_create(name,\n+\t\t\t\tRTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MEMPOOL_OBJS,\n+\t\t\t\tNB_CACHE_OBJS, 0,\n+\t\t\t\trte_lcore_to_socket_id(lo->lcore_id));\n \n-\tfor (i = 0; i < dev_info.max_nb_queue_pairs; i++) {\n-\t\tret = rte_cryptodev_queue_pair_setup(cryptodev_id, i,\n-\t\t\t\t&qp_conf, rte_lcore_to_socket_id(worker_lcore),\n-\t\t\t\tinfo.sess_pool);\n-\t\tif (ret < 0) {\n-\t\t\tRTE_LOG(ERR, USER1, \"Failed to configure qp %u\\n\",\n-\t\t\t\t\tinfo.cid);\n+\t\tif (!info->cop_pool) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Failed to create crypto pool\");\n+\t\t\tret = -ENOMEM;\n \t\t\tgoto error_exit;\n \t\t}\n-\t}\n \n-\tret = rte_cryptodev_start(cryptodev_id);\n-\tif (ret < 0) {\n-\t\tRTE_LOG(ERR, USER1, \"Failed to start cryptodev %u\\n\", info.cid);\n-\t\tgoto error_exit;\n+\t\toptions.infos[i] = info;\n+\n+\t\tfor (j = 0; j < dev_info.max_nb_queue_pairs; j++) {\n+\t\t\tret = rte_cryptodev_queue_pair_setup(info->cid, j,\n+\t\t\t\t\t&qp_conf, rte_lcore_to_socket_id(\n+\t\t\t\t\t\t\tlo->lcore_id),\n+\t\t\t\t\tinfo->sess_pool);\n+\t\t\tif (ret < 0) {\n+\t\t\t\tRTE_LOG(ERR, USER1, \"Failed to configure qp\\n\");\n+\t\t\t\tgoto error_exit;\n+\t\t\t}\n+\t\t}\n \t}\n \n-\tinfo.cid = cryptodev_id;\n-\tinfo.lcore_id = worker_lcore;\n+\tfor (i = 0; i < options.nb_los; i++) {\n+\t\tstruct lcore_option *lo = &options.los[i];\n+\t\tstruct vhost_crypto_info *info = options.infos[i];\n \n-\tif (rte_eal_remote_launch(vhost_crypto_worker, NULL, worker_lcore)\n-\t\t\t< 0) {\n-\t\tRTE_LOG(ERR, USER1, \"Failed to start worker lcore\");\n-\t\tgoto error_exit;\n-\t}\n+\t\tret = rte_cryptodev_start(lo->cid);\n+\t\tif (ret < 0) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Failed to start cryptodev\\n\");\n+\t\t\tgoto error_exit;\n+\t\t}\n \n-\tfor (i = 0; i < options.nb_sockets; i++) {\n-\t\tif (rte_vhost_driver_register(options.socket_files[i],\n-\t\t\t\tRTE_VHOST_USER_DEQUEUE_ZERO_COPY) < 0) {\n-\t\t\tRTE_LOG(ERR, USER1, \"socket %s already exists\\n\",\n-\t\t\t\t\toptions.socket_files[i]);\n+\t\tif (rte_eal_remote_launch(vhost_crypto_worker, info,\n+\t\t\t\tlo->lcore_id) < 0) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Failed to start worker lcore\");\n \t\t\tgoto error_exit;\n \t\t}\n \n-\t\trte_vhost_driver_callback_register(options.socket_files[i],\n+\t\tfor (j = 0; j < lo->nb_sockets; j++) {\n+\t\t\tret = rte_vhost_driver_register(lo->socket_files[j],\n+\t\t\t\tRTE_VHOST_USER_DEQUEUE_ZERO_COPY);\n+\t\t\tif (ret < 0) {\n+\t\t\t\tRTE_LOG(ERR, USER1, \"socket %s already exists\\n\",\n+\t\t\t\t\tlo->socket_files[j]);\n+\t\t\t\tgoto error_exit;\n+\t\t\t}\n+\n+\t\t\trte_vhost_driver_callback_register(lo->socket_files[j],\n \t\t\t\t&virtio_crypto_device_ops);\n \n-\t\tif (rte_vhost_driver_start(options.socket_files[i]) < 0) {\n-\t\t\tRTE_LOG(ERR, USER1, \"failed to start vhost driver.\\n\");\n-\t\t\tgoto error_exit;\n+\t\t\tret = rte_vhost_driver_start(lo->socket_files[j]);\n+\t\t\tif (ret < 0)  {\n+\t\t\t\tRTE_LOG(ERR, USER1, \"failed to start vhost.\\n\");\n+\t\t\t\tgoto error_exit;\n+\t\t\t}\n \t\t}\n \t}\n \n-\tRTE_LCORE_FOREACH(worker_lcore)\n-\t\trte_eal_wait_lcore(worker_lcore);\n+\tRTE_LCORE_FOREACH(lcore)\n+\t\trte_eal_wait_lcore(lcore);\n \n-\trte_mempool_free(info.sess_pool);\n-\trte_mempool_free(info.cop_pool);\n+\tfree_resource();\n \n \treturn 0;\n \n error_exit:\n-\tfor (i = 0; i < options.nb_sockets; i++)\n-\t\tunregister_drivers(i);\n \n-\trte_mempool_free(info.cop_pool);\n-\trte_mempool_free(info.sess_pool);\n+\tfree_resource();\n \n \treturn -1;\n }\n",
    "prefixes": []
}