get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 74117,
    "url": "http://patches.dpdk.org/api/patches/74117/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200715155043.12476-2-arkadiuszx.kusztal@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.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": "<20200715155043.12476-2-arkadiuszx.kusztal@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200715155043.12476-2-arkadiuszx.kusztal@intel.com",
    "date": "2020-07-15T15:50:39",
    "name": "[v3,1/5] app: add muli process crypto application",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "f5a2a11cb50472befac1a9e109a910b8ecf6ba02",
    "submitter": {
        "id": 452,
        "url": "http://patches.dpdk.org/api/people/452/?format=api",
        "name": "Arkadiusz Kusztal",
        "email": "arkadiuszx.kusztal@intel.com"
    },
    "delegate": {
        "id": 6690,
        "url": "http://patches.dpdk.org/api/users/6690/?format=api",
        "username": "akhil",
        "first_name": "akhil",
        "last_name": "goyal",
        "email": "gakhil@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20200715155043.12476-2-arkadiuszx.kusztal@intel.com/mbox/",
    "series": [
        {
            "id": 11057,
            "url": "http://patches.dpdk.org/api/series/11057/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=11057",
            "date": "2020-07-15T15:50:38",
            "name": "app: add multi process crypto application",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/11057/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/74117/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/74117/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id BC79FA0547;\n\tWed, 15 Jul 2020 17:50:56 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 8E33D1B1D5;\n\tWed, 15 Jul 2020 17:50:53 +0200 (CEST)",
            "from mga01.intel.com (mga01.intel.com [192.55.52.88])\n by dpdk.org (Postfix) with ESMTP id C189A199BC\n for <dev@dpdk.org>; Wed, 15 Jul 2020 17:50:50 +0200 (CEST)",
            "from fmsmga002.fm.intel.com ([10.253.24.26])\n by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 15 Jul 2020 08:50:50 -0700",
            "from akusztax-mobl.ger.corp.intel.com ([10.104.121.32])\n by fmsmga002.fm.intel.com with ESMTP; 15 Jul 2020 08:50:48 -0700"
        ],
        "IronPort-SDR": [
            "\n nExPyfHMIDb9zAyCGa2cOZ6M0W+9Tc/gXh7Mg3YPcT9UDJwXSx1HoYkn4VY2cGGqke6oN8/NbO\n Db3A2oxIsXwg==",
            "\n LGzJCEfXRJOOLmr6OAA59doE4PfoaCLLIJJGfXOl8oZFhbFXJOEbwVkpVcRH/5MIQmkPCeBcRU\n uT6Htvqx3bLw=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9683\"; a=\"167303473\"",
            "E=Sophos;i=\"5.75,355,1589266800\"; d=\"scan'208\";a=\"167303473\"",
            "E=Sophos;i=\"5.75,355,1589266800\"; d=\"scan'208\";a=\"318102530\""
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "From": "Arek Kusztal <arkadiuszx.kusztal@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "akhil.goyal@nxp.com, fiona.trahe@intel.com,\n Arek Kusztal <arkadiuszx.kusztal@intel.com>",
        "Date": "Wed, 15 Jul 2020 17:50:39 +0200",
        "Message-Id": "<20200715155043.12476-2-arkadiuszx.kusztal@intel.com>",
        "X-Mailer": "git-send-email 2.19.1.windows.1",
        "In-Reply-To": "<20200715155043.12476-1-arkadiuszx.kusztal@intel.com>",
        "References": "<20200715155043.12476-1-arkadiuszx.kusztal@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v3 1/5] app: add muli process crypto application",
        "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 <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This patch adds test application that can show\nusage of cryptodev in multi process environment.\nMore can be found in mp_crypto.rst in tools guides.\n\nSigned-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>\n---\n app/Makefile                          |   1 +\n app/meson.build                       |   3 +-\n app/test-mp-crypto/Makefile           |  15 ++\n app/test-mp-crypto/main.c             | 169 ++++++++++++\n app/test-mp-crypto/meson.build        |   8 +\n app/test-mp-crypto/mp_crypto.c        |  26 ++\n app/test-mp-crypto/mp_crypto.h        | 178 ++++++++++++\n app/test-mp-crypto/mp_crypto_ipc.c    |  32 +++\n app/test-mp-crypto/mp_crypto_parser.c | 493 ++++++++++++++++++++++++++++++++++\n app/test-mp-crypto/mp_crypto_parser.h | 148 ++++++++++\n 10 files changed, 1072 insertions(+), 1 deletion(-)\n create mode 100644 app/test-mp-crypto/Makefile\n create mode 100644 app/test-mp-crypto/main.c\n create mode 100644 app/test-mp-crypto/meson.build\n create mode 100644 app/test-mp-crypto/mp_crypto.c\n create mode 100644 app/test-mp-crypto/mp_crypto.h\n create mode 100644 app/test-mp-crypto/mp_crypto_ipc.c\n create mode 100644 app/test-mp-crypto/mp_crypto_parser.c\n create mode 100644 app/test-mp-crypto/mp_crypto_parser.h",
    "diff": "diff --git a/app/Makefile b/app/Makefile\nindex 0392a7d..abacadf 100644\n--- a/app/Makefile\n+++ b/app/Makefile\n@@ -13,6 +13,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_FIB) += test-fib\n DIRS-$(CONFIG_RTE_TEST_FLOW_PERF) += test-flow-perf\n DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += test-pipeline\n DIRS-$(CONFIG_RTE_LIBRTE_IPSEC) += test-sad\n+DIRS-$(CONFIG_RTE_LIBRTE_IPSEC) += test-mp-crypto\n \n ifeq ($(CONFIG_RTE_LIBRTE_BBDEV),y)\n DIRS-$(CONFIG_RTE_TEST_BBDEV) += test-bbdev\ndiff --git a/app/meson.build b/app/meson.build\nindex 585b908..d6ec4e8 100644\n--- a/app/meson.build\n+++ b/app/meson.build\n@@ -18,7 +18,8 @@ apps = [\n \t'test-flow-perf',\n \t'test-pipeline',\n \t'test-pmd',\n-\t'test-sad']\n+\t'test-sad',\n+\t'test-mp-crypto']\n \n # for BSD only\n lib_execinfo = cc.find_library('execinfo', required: false)\ndiff --git a/app/test-mp-crypto/Makefile b/app/test-mp-crypto/Makefile\nnew file mode 100644\nindex 0000000..9fc1f3c\n--- /dev/null\n+++ b/app/test-mp-crypto/Makefile\n@@ -0,0 +1,15 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2020 Intel Corporation\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+\n+APP = dpdk-test-mp-crypto\n+\n+CFLAGS += $(WERROR_FLAGS)\n+CFLAGS += -O3\n+\n+# all source are stored in SRCS-y\n+SRCS-y := main.c mp_crypto.c mp_crypto_parser.c mp_crypto_ipc.c\n+\n+include $(RTE_SDK)/mk/rte.app.mk\ndiff --git a/app/test-mp-crypto/main.c b/app/test-mp-crypto/main.c\nnew file mode 100644\nindex 0000000..ce150b5\n--- /dev/null\n+++ b/app/test-mp-crypto/main.c\n@@ -0,0 +1,169 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+\n+#include <rte_hexdump.h>\n+#include <rte_memory.h>\n+#include <rte_memcpy.h>\n+#include <rte_mempool.h>\n+#include <rte_mbuf.h>\n+#include <rte_malloc.h>\n+#include <rte_cryptodev.h>\n+#include <rte_cycles.h>\n+#include <rte_atomic.h>\n+#include <signal.h>\n+#include <inttypes.h>\n+\n+#include \"mp_crypto_parser.h\"\n+#include \"mp_crypto.h\"\n+\n+static void sigkill_handler(int __rte_unused sig,\n+\t\t\t\tsiginfo_t *siginfo __rte_unused,\n+\t\t\t\tvoid *context __rte_unused)\n+{\n+\tmp_crypto_exit_flag = 1;\n+\tprintf(\"\\nInterrupted, finalizing...\");\n+}\n+\n+static int\n+mp_app_init(int argc, char *argv[])\n+{\n+\t/* init EAL */\n+\tint ret = rte_eal_init(argc, argv)\n+;\n+\tif (ret < 0)\n+\t\trte_exit(-1, \"Invalid EAL arguments!\\n\");\n+\n+\targc -= ret;\n+\targv += ret;\n+\n+\tstruct sigaction sigkill_action;\n+\n+\tmemset(&sigkill_action, 0, sizeof(sigkill_action));\n+\tsigkill_action.sa_sigaction = sigkill_handler;\n+\tsigkill_action.sa_flags = SA_SIGINFO;\n+\n+\tif (sigaction(SIGINT, &sigkill_action, NULL) < 0) {\n+\t\tMP_APP_LOG_2(ERR, COL_RED, \"Cannot init sigation\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (get_options(argc, argv) != 0) {\n+\t\tMP_APP_LOG_2(ERR, COL_RED,\n+\t\t\t\"Get cmdln options returned an error\\n\");\n+\t\treturn -1;\n+\t};\n+\n+\t/* Set driver id for this process */\n+\tmp_app_driver_id =\n+\t\trte_cryptodev_driver_id_get(mp_app_params->devtype_name);\n+\tMP_APP_LOG(INFO, COL_BLUE, \"- Setting driver %d for this process\",\n+\t\tmp_app_driver_id);\n+\n+\t/* Register IPC and allocate memzones */\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n+\t\tMP_APP_LOG_2(INFO, COL_NORM, \"- Starting PRIMARY process\");\n+\t\tif (rte_mp_action_register(MP_APP_IPC_NAME,\n+\t\t\tmp_crypto_primary_handler)) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Cannot register IPC callback\");\n+\t\t\treturn -1;\n+\t\t}\n+\t\t/* Setup memzone for shared data */\n+\t\tmp_app_process_mz = rte_memzone_reserve(MP_APP_PROC_SHARED_NAME,\n+\t\t\t\tsizeof(struct mp_app_process_data), 0, 0);\n+\t\tif (mp_app_process_mz == NULL) {\n+\t\t\tRTE_LOG(ERR, USER1,\n+\t\t\t\t\"%s: cannot create memzone for process\",\n+\t\t\t\t__func__);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tmp_shared_data = mp_app_process_mz->addr;\n+\t\trte_spinlock_init(&mp_shared_data->sessions.lock);\n+\t} else {\n+\t\tMP_APP_LOG_2(INFO, COL_NORM, \"- Starting SECONDARY process\");\n+\t\tif (rte_mp_action_register(MP_APP_IPC_NAME,\n+\t\t\tmp_crypto_secondary_handler)) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Cannot register IPC callback\");\n+\t\t\treturn -1;\n+\t\t}\n+\t\t/* Setup memzone for shared data */\n+\t\tmp_app_process_mz =\n+\t\t\trte_memzone_lookup(MP_APP_PROC_SHARED_NAME);\n+\t\tif (mp_app_process_mz == NULL) {\n+\t\t\tMP_APP_LOG(ERR, COL_RED,\n+\t\t\t\t\"Cannot find memzone by name %s\",\n+\t\t\tMP_APP_PROC_SHARED_NAME);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tmp_shared_data = mp_app_process_mz->addr;\n+\t}\n+\n+\tmp_shared_data->proc_counter++;\n+\tmp_shared_data->proc_counter_total++;\n+\tMP_APP_LOG(INFO, COL_GREEN, \"Number of processes = %d\",\n+\t\tmp_shared_data->proc_counter);\n+\n+\treturn 0;\n+}\n+\n+void mp_crypto_exit_app(void)\n+{\n+\tconst int timeout = 10;\n+\tint counter = 0;\n+\tstruct rte_mp_msg icp_msg;\n+\n+\tmemset(&icp_msg, 0, sizeof(MP_APP_IPC_NAME));\n+\tmp_crypto_exit_flag = 1;\n+\tif (mp_shared_data == NULL)\n+\t\treturn;\n+\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n+\t\t/* Inform of exit intention,\n+\t\t * wait until all processes finish\n+\t\t */\n+\n+\t\tmemcpy(icp_msg.name, MP_APP_IPC_NAME, sizeof(MP_APP_IPC_NAME));\n+\t\tmemcpy(icp_msg.param, PRIMARY_PROC_EXIT,\n+\t\t\tsizeof(PRIMARY_PROC_EXIT));\n+\t\ticp_msg.len_param = sizeof(PRIMARY_PROC_EXIT);\n+\t\ticp_msg.num_fds = 0;\n+\t\tif (rte_mp_sendmsg(&icp_msg) < 0) {\n+\t\t\tMP_APP_LOG_2(ERR, COL_RED,\n+\t\t\t\"Error when sending IPC to secondary processes\");\n+\t\t\treturn;\n+\t\t}\n+\t\twhile (mp_shared_data->proc_counter > 1 && counter++\n+\t\t\t\t< timeout) {\n+\t\t\trte_delay_ms(1000);\n+\t\t\tMP_APP_LOG(INFO, COL_NORM,\n+\t\t\t\"Waiting for %d out of %d seconds\", counter, timeout);\n+\t\t}\n+\t\tif (counter < timeout) {\n+\t\t\tMP_APP_LOG_2(INFO, COL_GREEN,\n+\t\t\t\"All secondary processes exited normally\");\n+\t\t} else {\n+\t\t\tMP_APP_LOG_2(ERR, COL_RED,\n+\t\t\t\"One or more processes did not exit normally\");\n+\t\t}\n+\n+\t\tmp_shared_data->proc_counter = 0;\n+\t} else {\n+\t\t/* Inform primary of exiting */\n+\t\tmp_shared_data->proc_counter--;\n+\t}\n+}\n+\n+int main(int argc, char *argv[])\n+{\n+\tif (mp_app_init(argc, argv) < 0) {\n+\t\tMP_APP_LOG_2(ERR, COL_RED, \"Error when initializing\");\n+\t\tgoto err;\n+\t};\n+\n+\tmp_crypto_exit_app();\n+\treturn 0;\n+err:\n+\tmp_crypto_exit_app();\n+\n+\treturn 1;\n+}\ndiff --git a/app/test-mp-crypto/meson.build b/app/test-mp-crypto/meson.build\nnew file mode 100644\nindex 0000000..12a6d49\n--- /dev/null\n+++ b/app/test-mp-crypto/meson.build\n@@ -0,0 +1,8 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2020 Intel Corporation\n+\n+sources = files('mp_crypto.c',\n+\t\t'mp_crypto_parser.c',\n+\t\t'mp_crypto_ipc.c',\n+\t\t'main.c')\n+deps += ['cryptodev']\n\\ No newline at end of file\ndiff --git a/app/test-mp-crypto/mp_crypto.c b/app/test-mp-crypto/mp_crypto.c\nnew file mode 100644\nindex 0000000..3437397\n--- /dev/null\n+++ b/app/test-mp-crypto/mp_crypto.c\n@@ -0,0 +1,26 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+#include \"mp_crypto.h\"\n+#include \"mp_crypto_parser.h\"\n+\n+int\t\t\tmp_app_driver_id;\n+/* Global driver id, one per mp_app */\n+int\t\t\tmp_app_device_id;\n+/* For now we use only one device type, so for session\n+ * init only one need to be provided\n+ */\n+struct mp_app_dev\tmp_app_devs[MP_APP_MAX_DEVS];\n+/* Global devices list */\n+uint16_t\t\tmp_app_devs_cnt;\n+/* Global device counter */\n+uint8_t\t\t\tmp_app_max_queues;\n+/* Per process queue counter */\n+const struct rte_memzone *mp_app_process_mz;\n+struct mp_app_process_data *mp_shared_data;\n+/* Data shared across processes\n+ * memzone name = MP_PROC_SHARED_MZ\n+ */\n+\n+int mp_crypto_exit_flag;\n+/* Global exit flag */\ndiff --git a/app/test-mp-crypto/mp_crypto.h b/app/test-mp-crypto/mp_crypto.h\nnew file mode 100644\nindex 0000000..da89501\n--- /dev/null\n+++ b/app/test-mp-crypto/mp_crypto.h\n@@ -0,0 +1,178 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+#ifndef _MP_CRYPTO_SAMPLE_APP_\n+#define _MP_CRYPTO_SAMPLE_APP_\n+\n+#include <stdint.h>\n+#include <rte_hexdump.h>\n+#include <rte_cryptodev.h>\n+\n+/* Intel QuickAssist Technology Symmetric service PMD name */\n+#define CRYPTODEV_NAME_QAT_SYM_PMD\t\"crypto_qat\"\n+/* Maximum number of devices to configure with this app */\n+#define MP_APP_MAX_DEVS\t\t\t64\n+/* Maximum number of queue pairs per device */\n+#define MP_APP_QUEUE_PAIRS_NUM\t\t8\n+\n+#define MP_APP_PROC_SHARED_NAME\t\t\"MP_PROC_SHARED_MZ\"\n+/* Memzone name for shared data across processes */\n+#define MP_APP_IPC_NAME\t\t\t\"MP_APP_IPC_NAME\"\n+\n+/* Session pool information */\n+#define MP_APP_SESSION_POOL_NAME\t\"MP_APP_SESSION_POOL_NAME\"\n+#define MP_APP_PRIV_SESSION_POOL_NAME\t\"MP_APP_PRIV_SESSPOL_NAME\"\n+\n+#define MP_APP_SESSION_POOL_NAME_LOC\t\t\"MP_APP_SESSP_NAME_LOC\"\n+#define MP_APP_PRIV_SESSION_POOL_NAME_LOC\t\"MP_APP_PRIV_SPOL_NLOC\"\n+\n+#define MAX_NUM_OF_SESSIONS\t\t(16)\n+\n+/* Crypto op information */\n+#define MP_APP_CRYPTO_OP_POOL_NAME\t\"MP_APP_OP_NAME\"\n+/* Mbuf information */\n+#define MP_APP_MBUFPOOL_NAME\t\t\"MP_APP_MBUF_NAME\"\n+\n+extern int mp_crypto_exit_flag;\n+/* Global exit flag */\n+\n+/*\n+ * IPC COMMANDS\n+ */\n+#define PRIMARY_PROC_EXIT\t\t\"PRIMARY_EXIT\"\n+#define SECONDARY_PROC_EXIT\t\t\"SECONDARY_EXIT\"\n+\n+#define MP_APP_DEV_NAME_LEN\t64\n+/* Max name length */\n+\n+/* Op pool constants */\n+#define MP_APP_NUM_MBUFS\t\t\t\t\t(4096)\n+/* Same number as default/max ops */\n+#define MP_APP_MBUF_CACHE_SIZE\t\t\t\t(256)\n+#define MP_APP_DEFAULT_NUM_XFORMS\t\t\t(2)\n+#define MP_APP_MAXIMUM_IV_LENGTH\t\t\t(16)\n+/* Mbuf constants */\n+#define MP_APP_MBUF_SIZE\t\t\t(sizeof(struct rte_mbuf) + \\\n+\t\tRTE_PKTMBUF_HEADROOM + MBUF_DATAPAYLOAD_SIZE)\n+/* qps constants */\n+#define MP_CRYPTO_QP_DESC_NUM\t\t(4096)\n+#define NP_CRYPTO_OPS_TO_ENQ\t\t(160000)\n+#define NP_CRYPTO_OPS_TO_DEQ\t\t(160000)\n+/* Enqueue constants */\n+#define MP_CRYPTO_BURST_NUM\t\t(64)\n+#define MP_CRYPTO_OPS_NUM\t\t(MP_APP_NUM_MBUFS)\n+/* Device information */\n+#define MP_CRYPTO_MAX_DEVS\t\t(64)\n+\n+extern struct rte_crypto_op *mp_crypto_ops[];\n+/* Per process set of rte crypto ops */\n+extern struct rte_crypto_op *mp_crypto_ops_ret[];\n+/* Per process set of return rte crypto ops */\n+extern struct rte_mbuf *mp_crypto_mbufs[];\n+/* Per process set of rte mbufs */\n+\n+/* Name of the device */\n+struct mp_app_dev_name {\n+\tchar name[MP_APP_DEV_NAME_LEN];\n+};\n+\n+extern struct rte_cryptodev_sym_session *mp_crypto_local_sessions[];\n+/* Array of private sessions */\n+\n+/* Symmetric session + ref count*/\n+struct mp_app_shared_sym_session {\n+\tstruct rte_cryptodev_sym_session *session;\n+\t/* Pointer to symmetric session */\n+\tint refcnt;\n+\t/* Reference count, process that created this session\n+\t * does not increment this value\n+\t */\n+};\n+\n+/* Data for session array to be shared */\n+struct mp_app_session_array {\n+\tstruct mp_app_shared_sym_session sym_sessions[MAX_NUM_OF_SESSIONS];\n+\t/* Array of pointers to sessions */\n+\tint sym_session_counter;\n+\t/* Counter of allocated sessions */\n+\trte_spinlock_t lock;\n+\t/* Spinlock guarding this array */\n+};\n+\n+/* Data to be shared across processes */\n+struct mp_app_process_data {\n+\tuint16_t proc_counter;\n+\t/* Counter of processes */\n+\tuint16_t proc_counter_total;\n+\t/* Number of processes that joined, not decremented\n+\t * can be used for naming in particular processes\n+\t */\n+\tuint16_t devices_number;\n+\t/* Number of devices probed by primary process */\n+\tstruct mp_app_dev_name prim_dev_name[MP_APP_MAX_DEVS];\n+\t/* Names of devices probed by primary process */\n+\tstruct mp_app_session_array sessions;\n+\t/* Array of sessions to be visible by all processes */\n+};\n+\n+extern const struct rte_memzone *mp_app_process_mz;\n+extern struct mp_app_process_data *mp_shared_data;\n+/* Data shared across processes\n+ * memzone name = MP_PROC_SHARED_MZ\n+ */\n+\n+struct mp_app_dev {\n+\tint8_t id;\n+\t/* Cryptodev id of this dev */\n+\tint queue_pair_flag[MP_APP_QUEUE_PAIRS_NUM];\n+\t/* 1 means qp was configured for this device,\n+\t * 0 not configured by this process, but still\n+\t * could be initialized by another\n+\t * -2 means this qp is to be configured\n+\t */\n+\tuint16_t max_queue_pairs;\n+\t/* Per device info */\n+\tuint8_t probed;\n+\t/* If device was probed by EAL */\n+\tuint8_t configured;\n+\t/* Was this device configured */\n+\tconst struct rte_memzone *shared_data;\n+\t/* This data is shared across processes\n+\t * memzone name = MZ_DEV_SHARED_DATA_DEV_[ID]\n+\t */\n+};\n+\n+extern int\t\t\tmp_app_driver_id;\n+/* Global driver id, one per mp_app */\n+extern int\t\t\tmp_app_device_id;\n+/* For now we use only one device type, so for session\n+ * init only one need to be provided\n+ */\n+extern struct mp_app_dev\tmp_app_devs[];\n+/* Global devices list */\n+extern uint16_t\t\t\tmp_app_devs_cnt;\n+/* Global device counter */\n+extern uint8_t\t\t\tmp_app_max_queues;\n+/* Per process queue counter */\n+\n+void mp_crypto_exit_app(void);\n+/* Exit function for both primary and secondary */\n+\n+/*\n+ * Primary process IPC handler\n+ */\n+int\n+mp_crypto_primary_handler(const struct rte_mp_msg *mp_msg,\n+\t\t  const void *peer);\n+int\n+mp_crypto_secondary_handler(const struct rte_mp_msg *mp_msg,\n+\t\t  const void *peer);\n+\n+#define IV_OFFSET\t\t\t(sizeof(struct rte_crypto_op) + \\\n+\t\tsizeof(struct rte_crypto_sym_op) + DEFAULT_NUM_XFORMS * \\\n+\t\tsizeof(struct rte_crypto_sym_xform))\n+\n+#define MBUF_DATAPAYLOAD_SIZE\t\t(2048)\n+#define DEFAULT_NUM_XFORMS\t\t\t(2)\n+\n+#endif\ndiff --git a/app/test-mp-crypto/mp_crypto_ipc.c b/app/test-mp-crypto/mp_crypto_ipc.c\nnew file mode 100644\nindex 0000000..9d5a8cb\n--- /dev/null\n+++ b/app/test-mp-crypto/mp_crypto_ipc.c\n@@ -0,0 +1,32 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+#include \"mp_crypto.h\"\n+\n+/*\n+ * Primary process IPC handler\n+ */\n+int\n+mp_crypto_primary_handler(const struct rte_mp_msg *mp_msg,\n+\t\t  const void *peer)\n+{\n+\t(void)peer;\n+\tif (!memcmp(SECONDARY_PROC_EXIT, (const char *)mp_msg->param,\n+\t\tsizeof(SECONDARY_PROC_EXIT))) {\n+\t\tRTE_LOG(ERR, USER1, \"One of secondary processes exiting...\");\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+mp_crypto_secondary_handler(const struct rte_mp_msg *mp_msg,\n+\t\t  const void *peer)\n+{\n+\t(void)peer;\n+\tif (!memcmp(PRIMARY_PROC_EXIT, (const char *)mp_msg->param,\n+\t\tsizeof(PRIMARY_PROC_EXIT)))\t{\n+\t\tRTE_LOG(ERR, USER1, \"Primary process exiting...\");\n+\t\tmp_crypto_exit_flag = 1;\n+\t}\n+\treturn 0;\n+}\ndiff --git a/app/test-mp-crypto/mp_crypto_parser.c b/app/test-mp-crypto/mp_crypto_parser.c\nnew file mode 100644\nindex 0000000..8edae17\n--- /dev/null\n+++ b/app/test-mp-crypto/mp_crypto_parser.c\n@@ -0,0 +1,493 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+\n+#include <getopt.h>\n+#include <stdint.h>\n+#include <stdio.h>\n+#include <string.h>\n+#include <inttypes.h>\n+#include <stdlib.h>\n+#include <errno.h>\n+\n+#include <rte_string_fns.h>\n+#include \"mp_crypto_parser.h\"\n+#include \"mp_crypto.h\"\n+\n+struct mp_crypto_app_parameters *mp_app_params;\n+\n+static void\n+usage(char *progname)\n+{\n+\t/* TODO, find better way of formatting columns... */\n+\tprintf(\"%s [EAL options] -- [options]\"\n+\t\"\\noptions:\"\n+\t\"\\n  --devtype [device name]: \\t\\t\\tdevice name, the same name need to be used\"\n+\t\" across all processes.\\n\\t\\t\\t\\t\\t\\t--Example: --devtype=crypto_qat\"\n+\t\"\\n  --config-dev [dev_id,]: \\t\\t\\tid of device that should be\"\n+\t\" configured by this process. Note that order of ids depends on the\"\n+\t\" Cryptodev\\n\\t\\t\\t\\t\\t\\tglobal array placement so BDF of smaller numbers will come\"\n+\t\" first.\\n\\t\\t\\t\\t\\t\\t--Example: -w 03:01.2 -w 03:01.1 -w 03:01.3 --config-dev 0,2\"\n+\t\" will configure devices 03:01.1 and 03:01.3.\"\n+\t\"\\n  --qp-config=[dev_id]:[qp_id,];...: \\t\\tqueue_pairs qp_id's to be configured dev_id's\"\n+\t\"\\n\\t\\t\\t\\t\\t\\t--Example: --qp-config=0:0,1;1:1;0:1; - will configure qp's 0,1 on device 0\"\n+\t\"' 1 on device 1, 0,1 on device 2.'\"\n+\t\"\\n  --session-mask=[mask]\\t\\t\\t\\tsession to be shared for all processes, session list is in\"\n+\t\" mp_crypto_vectors.c file.\\n\\t\\t\\t\\t\\t\\tIf session mask will not be set it still can be configured\"\n+\t\" interactively by user for certain process and the used by this process only\"\n+\t\"\\n\\t\\t\\t\\t\\t\\t--Example --sesion-mask=0x3 will configure session 0 and 1.\"\n+\t\"\\n  --enq=[dev_id]:[qp_id]:[ops]:[vector_id]:\\tEnqueue operation for this process\"\n+\t\"\\n\\t\\t\\t\\t\\t\\t- dev_id: device selected the same way as in --config-dev option\"\n+\t\"\\n\\t\\t\\t\\t\\t\\t- qp_id: queue pair to bu used for enqueue operation\"\n+\t\"\\n\\t\\t\\t\\t\\t\\t- ops: 0 means it will run in infinite loop (ctrl-c will inform other processes),\"\n+\t\"other than that any positive number\"\n+\t\"\\n\\t\\t\\t\\t\\t\\t- vector_id: vector id to be used, vector array can be found\"\n+\t\" in mp_crypto_vectors.c file. \"\n+\t\"\\n\\t\\t\\t\\t\\t\\t- Only one can be specified by process\"\n+\t\"\\n  --deq=[dev_id]:[qp_id]:[ops]:[vector_id]:\\tDequeue operation for this process\"\n+\t\"\\n\\t\\t\\t\\t\\t\\t- dev_id: device selected the same way as in --config-dev option\"\n+\t\"\\n\\t\\t\\t\\t\\t\\t- qp_id: queue pair to bu used for dequeue operation\"\n+\t\"\\n\\t\\t\\t\\t\\t\\t- ops: 0 means it will run in infinite loop (ctrl-c will inform other processes),\"\n+\t\"other than that any positive number\"\n+\t\"\\n\\t\\t\\t\\t\\t\\t- vector_id: vector id to be used, vector array can be found\"\n+\t\" in mp_crypto_vectors.c file. \"\n+\t\"\\n\\t\\t\\t\\t\\t\\t- Only one can be specified by process\"\n+\t\"\\n  --print-stats: \\t\\t\\t\\tPrint stats at then end of program.\"\n+\t\"\\n\",\n+\tprogname);\n+}\n+\n+static struct option lgopts[] = {\n+\t{ MP_DEV_CONFIGURE, required_argument, 0, 0 },\n+\t{ MP_QP_CONFIGURE, required_argument, 0, 0 },\n+\t{ MP_ENQ, required_argument, 0, 0 },\n+\t{ MP_DEQ, required_argument, 0, 0 },\n+\t{ MP_SESSION_MASK, required_argument, 0, 0 },\n+\t{ MP_PRINT_STATS, 0, 0, 0 },\n+\t{ MP_DEVTYPE_NAME, required_argument, 0, 0 },\n+\t{ NULL, 0, 0, 0 }\n+};\n+\n+int16_t\n+get_options(int argc, char *argv[])\n+{\n+\tmp_app_params = rte_zmalloc_socket(NULL,\n+\t\t\t\t\tsizeof(struct mp_crypto_app_parameters),\n+\t\t\t\t\t0, rte_socket_id());\n+\n+\tif (mp_app_params == NULL) {\n+\t\tRTE_LOG(ERR, USER1,\n+\t\t\t\"Failed to allocate for test data\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\toptions_default(mp_app_params);\n+\n+\tif (options_parse(mp_app_params, argc, argv) != 0) {\n+\t\tMP_APP_LOG_2(ERR, COL_RED,\n+\t\t\t\"Parsing one or more user options failed\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+parse_config_dev(struct mp_crypto_app_parameters *mp_params,\n+\t\t\t\t\tconst char *arg)\n+{\n+\tchar *end = NULL;\n+\tconst char *start = arg;\n+\tuint64_t num;\n+\tchar str[32];\n+\n+\twhile (1) {\n+\t\tmemset(str, 0, sizeof(str));\n+\t\tend = strchr(start, ',');\n+\t\tif (end) {\n+\t\t\tmemcpy(str, start, end - start);\n+\t\t\terrno = 0;\n+\t\t\tnum = strtoull(str, NULL, 10);\n+\t\t\tif (errno) {\n+\t\t\t\tMP_APP_LOG(ERR, COL_RED,\n+\t\t\t\t\"Invalid device provided '%s'\", str);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tif (num >= MP_CRYPTO_MAX_DEVS) {\n+\t\t\t\tMP_APP_LOG(ERR, COL_RED,\n+\t\t\t\t\"Device number not supported %\"PRIu64\"\", num);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\t/* Sanity check, unfortunately c standard does not\n+\t\t\t * force errno to be set when no conversion\n+\t\t\t * can by performed (except for ERANGE)\n+\t\t\t */\n+\t\t\tif (num == 0) {\n+\t\t\t\tif (start[0] != '0') {\n+\t\t\t\t\tMP_APP_LOG(ERR, COL_RED,\n+\t\t\t\t\t\"Invalid device provided '%s'\", str);\n+\t\t\t\t\treturn -1;\n+\t\t\t\t}\n+\t\t\t\tif (start[1] != ',') {\n+\t\t\t\t\tMP_APP_LOG(ERR, COL_RED,\n+\t\t\t\t\t\"Invalid device provided '%s'\", str);\n+\t\t\t\t\treturn -1;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tmp_params->dev_to_configure_mask |= 1LU << (num);\n+\t\t\tstart = end + 1;\n+\t\t\tif (*start == 0)\n+\t\t\t\tbreak;\n+\t\t} else {\n+\t\t\tend = strchr(start, '\\0');\n+\t\t\tmemcpy(str, start, end - start);\n+\t\t\terrno = 0;\n+\t\t\tnum = strtoull(str, NULL, 10);\n+\t\t\tif (errno) {\n+\t\t\t\tMP_APP_LOG(ERR, COL_RED,\n+\t\t\t\t\"Invalid device provided '%s'\", str);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tif (num >= 64) {\n+\t\t\t\tMP_APP_LOG(ERR, COL_RED,\n+\t\t\t\t\"Device number not supported %\"PRIu64\"\", num);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\t/* Sanity check, unfortunately c standard does not force\n+\t\t\t * errno to be set when no conversion can by performed\n+\t\t\t * (except for ERANGE)\n+\t\t\t */\n+\t\t\tif (num == 0) {\n+\t\t\t\tif (start[0] != '0') {\n+\t\t\t\t\tMP_APP_LOG(ERR, COL_RED,\n+\t\t\t\t\t\"Invalid device provided '%s'\", str);\n+\t\t\t\t\treturn -1;\n+\t\t\t\t}\n+\t\t\t\tif (start[1] != '\\0') {\n+\t\t\t\t\tMP_APP_LOG(ERR, COL_RED,\n+\t\t\t\t\t\"Invalid device provided '%s'\", str);\n+\t\t\t\t\treturn -1;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tmp_params->dev_to_configure_mask |= 1LU << (num);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* Veeeery simple parser */\n+static int mp_parse_qps(const char *arg)\n+{\n+\tchar str[64] = { };\n+\tint dev_id = -1;\n+\tconst char *start = arg;\n+\tconst char *end;\n+\tint finish = 0;\n+\n+\twhile (1) {\n+\t\tend = strchr(start, ':');\n+\t\tif (end == NULL)\n+\t\t\treturn 0;\n+\t\tmemcpy(str, start, end - start);\n+\t\tdev_id = strtol(str, NULL, 10);\n+\t\tstart = end + 1;\n+\t\tif (*start == '\\0') {\n+\t\t\tMP_APP_LOG_2(ERR, COL_RED,\n+\t\t\t\t\"Parsing queue pairs: error parsing\");\n+\t\t\treturn -1;\n+\t\t}\n+\t\tconst char *curr = start;\n+\n+\t\twhile (1) {\n+\t\t\tmemset(str, 0, sizeof(str));\n+\t\t\tif (*curr == ',' || *curr == ';' || *curr == '\\0') {\n+\t\t\t\tmemcpy(str, start, curr - start);\n+\t\t\t\tint qp_id = strtol(str, NULL, 10);\n+\n+\t\t\t\tif (qp_id > (MP_APP_QUEUE_PAIRS_NUM - 1)) {\n+\t\t\t\t\tMP_APP_LOG(WARNING, COL_YEL,\n+\t\t\t\t\t\"Cannot create qp: %d, maximum qp number allowed %d (%d queues)\",\n+\t\t\t\t\tqp_id, MP_APP_QUEUE_PAIRS_NUM - 1,\n+\t\t\t\t\tMP_APP_QUEUE_PAIRS_NUM);\n+\t\t\t\t}\n+\n+\t\t\t\tmp_app_devs[dev_id].queue_pair_flag[qp_id] =\n+\t\t\t\t\t\tQP_TO_CONFIGURE;\n+\t\t\t}\n+\t\t\tif (*curr == ',') {\n+\t\t\t\tstart = curr + 1;\n+\t\t\t\tcurr++;\n+\t\t\t\tcontinue;\n+\t\t\t} else if (*curr == ';') {\n+\t\t\t\tstart = curr + 1;\n+\t\t\t\tbreak;\n+\t\t\t} else if (*curr == '\\0') {\n+\t\t\t\tfinish = 1;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tcurr++;\n+\t\t}\n+\t\tif (finish)\n+\t\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+parse_qp_config(struct mp_crypto_app_parameters *mp_params, const char *arg)\n+{\n+\tstrncpy(mp_params->qp_config, arg, MP_APP_QP_PARAM_LEN - 1);\n+\tif (mp_parse_qps(arg)) {\n+\t\tMP_APP_LOG_2(ERR, COL_RED, \"- Parsing error, qpairs string\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+parse_enq(struct mp_crypto_app_parameters *mp_params, const char *arg)\n+{\n+\tchar str[64] = { };\n+\tconst char *start = arg;\n+\t/* dev id */\n+\tchar *end = strchr(start, ':');\n+\tint i = 0;\n+\n+\tif (end == NULL)\n+\t\tgoto err;\n+\tmemcpy(str, start, end - start);\n+\tmp_params->enq_param.dev_id = strtol(str, NULL, 10);\n+\t/* qp id */\n+\tmemset(str, 0, sizeof(str));\n+\tstart = end + 1;\n+\tend = strchr(start, ':');\n+\tif (end == NULL)\n+\t\tgoto err;\n+\tmemcpy(str, start, end - start);\n+\tmp_params->enq_param.qp_id = strtol(str, NULL, 10);\n+\t/* ops no */\n+\tmemset(str, 0, sizeof(str));\n+\tstart = end + 1;\n+\tend = strchr(start, ':');\n+\tif (end == NULL)\n+\t\tgoto err;\n+\tmemcpy(str, start, end - start);\n+\tmp_params->enq_param.ops_no = strtol(str, NULL, 10);\n+\t/* vector ids */\n+\tstart = end + 1;\n+\twhile ((end = strchr(start, ',')) != NULL) {\n+\t\tmemset(str, 0, sizeof(str));\n+\t\tmemcpy(str, start, end - start);\n+\t\tmp_params->enq_param.vector_number[i] = strtoul(str, NULL, 0);\n+\t\tstart = end + 1;\n+\t\ti++;\n+\t}\n+\tif (i == 0)\n+\t\tgoto err;\n+\n+\tMP_APP_LOG(INFO, COL_BLUE, \"Run enqueue on device %d\",\n+\t\t\tmp_params->enq_param.dev_id);\n+\tMP_APP_LOG(INFO, COL_BLUE, \"Run enqueue on qp %d\",\n+\t\t\tmp_params->enq_param.qp_id);\n+\ti = 0;\n+\twhile (mp_params->enq_param.vector_number[i] > 0 &&\n+\t\t\ti < MP_APP_MAX_VECTORS)\t{\n+\t\tMP_APP_LOG(INFO, COL_BLUE, \"Run enqueue vector %d\",\n+\t\t\tmp_params->enq_param.vector_number[i]);\n+\t\ti++;\n+\t}\n+\n+\tmp_params->enq_param.checkpoint = 1000000;\n+\n+\treturn 0;\n+err:\n+\tMP_APP_LOG_2(ERR, COL_RED, \"Error parsing enq\");\n+\treturn -1;\n+}\n+\n+static int\n+parse_deq(struct mp_crypto_app_parameters *mp_params, const char *arg)\n+{\n+\tchar str[64] = { };\n+\tconst char *start = arg;\n+\t/* Dev id */\n+\tchar *end = strchr(start, ':');\n+\tint i = 0;\n+\n+\tif (end == NULL)\n+\t\tgoto err;\n+\tmemcpy(str, start, end - start);\n+\tmp_params->deq_param.dev_id = strtol(str, NULL, 10);\n+\t/* qp id */\n+\tmemset(str, 0, sizeof(str));\n+\tstart = end + 1;\n+\tend = strchr(start, ':');\n+\tif (end == NULL)\n+\t\tgoto err;\n+\tmemcpy(str, start, end - start);\n+\tmp_params->deq_param.qp_id = strtol(str, NULL, 10);\n+\t/* ops no */\n+\tmemset(str, 0, sizeof(str));\n+\tstart = end + 1;\n+\tend = strchr(start, ':');\n+\tif (end == NULL)\n+\t\tgoto err;\n+\tmemcpy(str, start, end - start);\n+\tmp_params->deq_param.ops_no = strtol(str, NULL, 10);\n+\n+\t/* vector no */\n+\tstart = end + 1;\n+\twhile ((end = strchr(start, ',')) != NULL) {\n+\t\tmemset(str, 0, sizeof(str));\n+\t\tmemcpy(str, start, end - start);\n+\t\tmp_params->deq_param.vector_number[i] = strtoul(str, NULL, 0);\n+\t\tstart = end + 1;\n+\t\ti++;\n+\t}\n+\tif (i == 0)\n+\t\tgoto err;\n+\n+\tMP_APP_LOG(INFO, COL_BLUE, \"Run dequeue on device %d\",\n+\t\t\tmp_params->deq_param.dev_id);\n+\tMP_APP_LOG(INFO, COL_BLUE, \"Run dequeue on qp %d\",\n+\t\t\tmp_params->deq_param.qp_id);\n+\ti = 0;\n+\twhile (mp_params->deq_param.vector_number[i] > 0 &&\n+\t\t\ti < MP_APP_MAX_VECTORS)\t{\n+\t\tMP_APP_LOG(INFO, COL_BLUE, \"Run dequeue vector %d\",\n+\t\t\t\tmp_params->deq_param.vector_number[i]);\n+\t\ti++;\n+\t}\n+\n+\tmp_params->deq_param.checkpoint = 1000000;\n+\n+\treturn 0;\n+err:\n+\tMP_APP_LOG_2(ERR, COL_RED, \"Error parsing deq\");\n+\treturn -1;\n+}\n+\n+static int\n+parse_print_stats(struct mp_crypto_app_parameters *mp_params,\n+\t\t\tconst char *arg __rte_unused)\n+{\n+\tmp_params->print_stats = 1;\n+\treturn 0;\n+}\n+\n+static int\n+parse_session_mask(struct mp_crypto_app_parameters *mp_params,\n+\t\t\t\t\tconst char *arg)\n+{\n+\tchar *end = NULL;\n+\n+\tmp_params->session_mask = strtoull(arg, &end, 16);\n+\n+\treturn 0;\n+}\n+\n+static int\n+parse_devtype(struct mp_crypto_app_parameters *mp_params,\n+\t\t\t\t\tconst char *arg)\n+{\n+\tif (arg == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"--%s param argument is null\\n\",\n+\t\t\tMP_DEVTYPE_NAME);\n+\t}\n+\n+\tif (strlen(arg) > (sizeof(mp_params->devtype_name) - 1)) {\n+\t\tRTE_LOG(ERR, USER1, \"--%s different lengths\\n\",\n+\t\t\tMP_DEVTYPE_NAME);\n+\t\treturn 0;\n+\t}\n+\n+\tstrlcpy(mp_params->devtype_name, arg,\n+\t\t\tsizeof(mp_params->devtype_name));\n+\n+\treturn 0;\n+};\n+\n+typedef int (*option_parser_t)(struct mp_crypto_app_parameters\n+\t\t\t*mp_params,\tconst char *arg);\n+\n+struct long_opt_parser {\n+\tconst char *lgopt_name;\n+\toption_parser_t parser_fn;\n+};\n+\n+static int\n+opts_parse_long(int opt_idx, struct mp_crypto_app_parameters *mp_params)\n+{\n+\tstruct long_opt_parser parsermap[] = {\n+\t\t{ MP_DEV_CONFIGURE, parse_config_dev },\n+\t\t{ MP_QP_CONFIGURE, parse_qp_config },\n+\t\t{ MP_ENQ, parse_enq },\n+\t\t{ MP_DEQ, parse_deq },\n+\t\t{ MP_PRINT_STATS, parse_print_stats },\n+\t\t{ MP_SESSION_MASK, parse_session_mask },\n+\t\t{ MP_DEVTYPE_NAME, parse_devtype },\n+\t};\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < RTE_DIM(parsermap); i++) {\n+\t\tif (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,\n+\t\t\t\tstrlen(lgopts[opt_idx].name)) == 0) {\n+\t\t\treturn parsermap[i].parser_fn(mp_params, optarg);\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+options_parse(struct mp_crypto_app_parameters *mp_params,\n+\t\t\t\t\tint argc, char **argv)\n+{\n+\tint opt, retval;\n+\tint opt_idx;\n+\n+\twhile ((opt = getopt_long(argc, argv, \"h\", lgopts, &opt_idx))\n+\t\t\t!= EOF) {\n+\t\tswitch (opt) {\n+\t\tcase 'h':\n+\t\t\tusage(argv[0]);\n+\t\t\trte_exit(0, \"Select options as above.\\n\");\n+\t\t\tbreak;\n+\t\tcase 0:\n+\t\t\tretval = opts_parse_long(opt_idx, mp_params);\n+\t\t\tif (retval != 0)\n+\t\t\t\treturn retval;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tRTE_LOG(ERR, USER1, \"Parse error after %s\\n\",\n+\t\t\t\t\tlgopts[opt_idx].name);\n+\t\t\tusage(argv[0]);\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void\n+options_default(struct mp_crypto_app_parameters *mp_params)\n+{\n+\tint i = 0;\n+\n+\tfor (i = 0; i < MP_APP_MAX_VECTORS; i++) {\n+\t\tmp_params->enq_param.dev_id = -1;\n+\t\tmp_params->enq_param.qp_id = -1;\n+\t\tmp_params->enq_param.vector_number[i] = -1;\n+\t\tmp_params->deq_param.dev_id = -1;\n+\t\tmp_params->deq_param.qp_id = -1;\n+\t\tmp_params->deq_param.vector_number[i] = -1;\n+\t}\n+\n+\tmp_params->enq_param.ops_no = 0;\n+\tmp_params->deq_param.ops_no = 0;\n+\tmp_params->print_stats = 0;\n+}\ndiff --git a/app/test-mp-crypto/mp_crypto_parser.h b/app/test-mp-crypto/mp_crypto_parser.h\nnew file mode 100644\nindex 0000000..cf35e09\n--- /dev/null\n+++ b/app/test-mp-crypto/mp_crypto_parser.h\n@@ -0,0 +1,148 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+#ifndef _MP_CRYPTO_SAMPLE_APP_PARSER_\n+#define _MP_CRYPTO_SAMPLE_APP_PARSER_\n+\n+#include <rte_hexdump.h>\n+#include <rte_memory.h>\n+#include <rte_memcpy.h>\n+#include <rte_mempool.h>\n+#include <rte_mbuf.h>\n+#include <rte_malloc.h>\n+#include <rte_cryptodev.h>\n+\n+/* Make debug colorful! */\n+#define COL_NORM\t\"\\x1B[0m\"\n+#define COL_WHITE\t\"\\x1B[37m\"\n+#define COL_RED\t\t\"\\x1B[31m\"\n+#define COL_GREEN\t\"\\x1B[32m\"\n+#define COL_YEL\t\t\"\\x1B[33m\"\n+#define COL_BLUE\t\"\\x1B[34m\"\n+#define COL_MAG\t\t\"\\x1B[35m\"\n+\n+#define MP_APP_LOG(level, color, str, args...) \\\n+\tdo {\t\t\\\n+\t\tprintf(\"%s\", color);\t\t\t\\\n+\t\tRTE_LOG(level, USER1, str, args);\t\\\n+\t\tprintf(\"%s\\n\", COL_NORM);\t\\\n+\t} while (0)\n+\n+#define MP_APP_LOG_2(level, color, str) \\\n+\tdo {\t\t\\\n+\t\tprintf(\"%s\", color);\t\t\t\\\n+\t\tRTE_LOG(level, USER1, str);\t\\\n+\t\tprintf(\"%s\\n\", COL_NORM);\t\\\n+\t} while (0)\n+\n+#define MP_APP_LOG_NO_RET(level, color, str, args...) \\\n+\tdo {\t\t\\\n+\t\tprintf(\"\\r%s\", color);\t\t\t\\\n+\t\tRTE_LOG(level, USER1, str, args);\t\\\n+\t\tprintf(\"%s\", COL_NORM);\t\\\n+\t} while (0)\n+\n+#define MP_APP_QP_PARAM_LEN\t\t(64 * 4)\n+#define MP_APP_ENQ_PARAM_LEN\t1024\n+\n+#define EMPTY_FLAGS\t\t0\n+\n+#define MP_DEVTYPE_NAME\t\t(\"devtype\")\n+#define MP_DEV_CONFIGURE\t(\"config-dev\")\n+#define MP_QP_CONFIGURE\t\t(\"qp-config\")\n+#define MP_ENQ\t\t\t\t(\"enq\")\n+#define MP_DEQ\t\t\t\t(\"deq\")\n+#define MP_SESSION_MASK\t\t(\"session-mask\")\n+#define MP_PRINT_STATS\t\t(\"print-stats\")\n+\n+#define MP_APP_MAX_VECTORS\t64\n+\n+extern const char *comp_perf_test_type_strs[];\n+/* Command line parameters */\n+extern struct mp_crypto_app_parameters *mp_app_params;\n+/* Parser params */\n+\n+static const char livesign_print_char[4] = { '-', '\\\\', '|', '/'};\n+\n+int16_t\n+get_options(int argc, char *argv[]);\n+\n+struct mp_crypto_app_enqdeq {\n+\tint dev_id;\n+\tint qp_id;\n+\tint vector_number[MP_APP_MAX_VECTORS];\n+\tint ops_no;\n+\tint checkpoint;\n+};\n+\n+#define QP_TO_CONFIGURE\t\t(-2)\n+\n+struct mp_crypto_app_parameters {\n+\tchar devtype_name[RTE_DEV_NAME_MAX_LEN];\n+\t/* Driver to be used in this process */\n+\tchar qp_config[MP_APP_QP_PARAM_LEN];\n+\t/* Queue Pairs configuration per device in process\n+\t * in format q0,q1;q0,q1;, '-' means queue pair will not\n+\t * be configured\n+\t * Example: queue_pairs=\"0,1;0,-;-,1;\" means that\n+\t * device 0 will configure queue pairs 0 and 1,\n+\t * device 1 will configure queue pairs 0\n+\t * device 2 will configure queue pairs 1\n+\t * Devices are order dependent\n+\t */\n+\tchar flow_config[MP_APP_ENQ_PARAM_LEN];\n+\t/* Enqueue configuration per process\n+\t * Format \"[dev_id]=qp_id:[op,]\n+\t * Example: [0]=0:[enq, deq];[1]=0:[enq]\n+\t * Mean that for this process qp 0 on device 0 will be\n+\t * enqueuing and dequeuing in one queue pair,\n+\t * meanwhile device 0 will only enqueue data on qpair 0.\n+\t * Other process can then dequeue this data with\n+\t * [1]=0:[deq]\n+\t */\n+\tuint64_t dev_to_configure_mask;\n+\t/* Devices to configure, uint64 bitmask\n+\t * 1 means dev 0, 2 dev 1, 4 dev... etc\n+\t */\n+\tuint64_t session_mask;\n+\t/* Session to be created by this process,\n+\t * if session was already created this step will be ommited.\n+\t * Usage: session-mask=0x6 -> create session number 1 and 2.\n+\t * Number of session refer to predefined array of sessions\n+\t */\n+\tchar enq[MP_APP_ENQ_PARAM_LEN];\n+\tstruct mp_crypto_app_enqdeq enq_param;\n+\tchar deq[MP_APP_ENQ_PARAM_LEN];\n+\tstruct mp_crypto_app_enqdeq deq_param;\n+\t/* Enqueue/dequeue string used by this process.\n+\t * Usage: [dev_id]:[qp_id]:[crypto_vector],[crypto_vector]...\n+\t * Example 2:1:0,1,2, -> device no 2 on qp 1 enqueues ops from\n+\t * vectors 0, 1, 2 .note ',' comma needs to be put after last arg\n+\t */\n+\tint print_stats;\n+\t/* Print stats on the end on flow function */\n+\n+\tuint16_t qp_id;\n+\tuint16_t waiting_qp_id;\n+\n+\tint16_t configure_device;\n+\tint16_t setup_qp;\n+\tint16_t create_session_pool;\n+\tint16_t create_op_pool;\n+\tint16_t init_sessions;\n+\tint16_t build_ops;\n+\tint16_t dequeue;\n+\tint16_t enqueue;\n+\tint16_t dump_mempools;\n+};\n+\n+int\n+options_parse(struct mp_crypto_app_parameters *mp_params, int argc,\n+\t\t\tchar **argv);\n+void\n+options_default(struct mp_crypto_app_parameters *mp_params);\n+\n+int\n+options_check(struct mp_crypto_app_parameters *mp_params);\n+\n+#endif\n",
    "prefixes": [
        "v3",
        "1/5"
    ]
}