get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 29121,
    "url": "http://patches.dpdk.org/api/patches/29121/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20170922075519.28342-7-pablo.de.lara.guarch@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": "<20170922075519.28342-7-pablo.de.lara.guarch@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20170922075519.28342-7-pablo.de.lara.guarch@intel.com",
    "date": "2017-09-22T07:55:18",
    "name": "[dpdk-dev,v3,6/7] app/crypto-perf: support multiple queue pairs",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "6cb32e05b1d512fde6f5bb1591d8a3343939ac42",
    "submitter": {
        "id": 9,
        "url": "http://patches.dpdk.org/api/people/9/?format=api",
        "name": "De Lara Guarch, Pablo",
        "email": "pablo.de.lara.guarch@intel.com"
    },
    "delegate": {
        "id": 22,
        "url": "http://patches.dpdk.org/api/users/22/?format=api",
        "username": "pdelarag",
        "first_name": "Pablo",
        "last_name": "de Lara Guarch",
        "email": "pablo.de.lara.guarch@intel.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20170922075519.28342-7-pablo.de.lara.guarch@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/29121/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/29121/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 69BE71B1AB;\n\tFri, 22 Sep 2017 17:55:42 +0200 (CEST)",
            "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby dpdk.org (Postfix) with ESMTP id A821E1B1AA\n\tfor <dev@dpdk.org>; Fri, 22 Sep 2017 17:55:33 +0200 (CEST)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n\tby orsmga105.jf.intel.com with ESMTP; 22 Sep 2017 08:55:33 -0700",
            "from silpixa00399464.ir.intel.com (HELO\n\tsilpixa00399464.ger.corp.intel.com) ([10.237.222.157])\n\tby fmsmga005.fm.intel.com with ESMTP; 22 Sep 2017 08:55:31 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.42,427,1500966000\"; d=\"scan'208\";a=\"154396020\"",
        "From": "Pablo de Lara <pablo.de.lara.guarch@intel.com>",
        "To": "declan.doherty@intel.com,\n\takhil.goyal@nxp.com",
        "Cc": "dev@dpdk.org,\n\tPablo de Lara <pablo.de.lara.guarch@intel.com>",
        "Date": "Fri, 22 Sep 2017 08:55:18 +0100",
        "Message-Id": "<20170922075519.28342-7-pablo.de.lara.guarch@intel.com>",
        "X-Mailer": "git-send-email 2.9.4",
        "In-Reply-To": "<20170922075519.28342-1-pablo.de.lara.guarch@intel.com>",
        "References": "<20170913072026.29734-1-pablo.de.lara.guarch@intel.com>\n\t<20170922075519.28342-1-pablo.de.lara.guarch@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v3 6/7] app/crypto-perf: support multiple queue\n\tpairs",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add parameter \"qps\" in crypto performance app,\nto create multiple queue pairs per device.\n\nThis new parameter is useful to have multiple logical\ncores using a single crypto device, without needing\nto initialize a crypto device per core.\n\nSigned-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>\n---\n app/test-crypto-perf/cperf_options.h             |  2 +\n app/test-crypto-perf/cperf_options_parsing.c     | 22 ++++++++++\n app/test-crypto-perf/cperf_test_latency.c        | 14 +++---\n app/test-crypto-perf/cperf_test_pmd_cyclecount.c |  7 +--\n app/test-crypto-perf/cperf_test_throughput.c     | 14 +++---\n app/test-crypto-perf/cperf_test_verify.c         | 14 +++---\n app/test-crypto-perf/main.c                      | 56 ++++++++++++++----------\n doc/guides/tools/cryptoperf.rst                  |  4 ++\n 8 files changed, 84 insertions(+), 49 deletions(-)",
    "diff": "diff --git a/app/test-crypto-perf/cperf_options.h b/app/test-crypto-perf/cperf_options.h\nindex 6d339f4..468d5e2 100644\n--- a/app/test-crypto-perf/cperf_options.h\n+++ b/app/test-crypto-perf/cperf_options.h\n@@ -15,6 +15,7 @@\n #define CPERF_DESC_NB\t\t(\"desc-nb\")\n \n #define CPERF_DEVTYPE\t\t(\"devtype\")\n+#define CPERF_QP_NB\t\t(\"qp-nb\")\n #define CPERF_OPTYPE\t\t(\"optype\")\n #define CPERF_SESSIONLESS\t(\"sessionless\")\n #define CPERF_OUT_OF_PLACE\t(\"out-of-place\")\n@@ -74,6 +75,7 @@ struct cperf_options {\n \tuint32_t segment_sz;\n \tuint32_t test_buffer_size;\n \tuint32_t nb_descriptors;\n+\tuint32_t nb_qps;\n \n \tuint32_t sessionless:1;\n \tuint32_t out_of_place:1;\ndiff --git a/app/test-crypto-perf/cperf_options_parsing.c b/app/test-crypto-perf/cperf_options_parsing.c\nindex 89f86a2..441cd61 100644\n--- a/app/test-crypto-perf/cperf_options_parsing.c\n+++ b/app/test-crypto-perf/cperf_options_parsing.c\n@@ -364,6 +364,24 @@ parse_desc_nb(struct cperf_options *opts, const char *arg)\n }\n \n static int\n+parse_qp_nb(struct cperf_options *opts, const char *arg)\n+{\n+\tint ret = parse_uint32_t(&opts->nb_qps, arg);\n+\n+\tif (ret) {\n+\t\tRTE_LOG(ERR, USER1, \"failed to parse number of queue pairs\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tif ((opts->nb_qps == 0) || (opts->nb_qps > 256)) {\n+\t\tRTE_LOG(ERR, USER1, \"invalid number of queue pairs specified\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n parse_device_type(struct cperf_options *opts, const char *arg)\n {\n \tif (strlen(arg) > (sizeof(opts->device_type) - 1))\n@@ -680,6 +698,7 @@ static struct option lgopts[] = {\n \t{ CPERF_BUFFER_SIZE, required_argument, 0, 0 },\n \t{ CPERF_SEGMENT_SIZE, required_argument, 0, 0 },\n \t{ CPERF_DESC_NB, required_argument, 0, 0 },\n+\t{ CPERF_QP_NB, required_argument, 0, 0 },\n \n \t{ CPERF_DEVTYPE, required_argument, 0, 0 },\n \t{ CPERF_OPTYPE, required_argument, 0, 0 },\n@@ -747,6 +766,7 @@ cperf_options_default(struct cperf_options *opts)\n \n \tstrncpy(opts->device_type, \"crypto_aesni_mb\",\n \t\t\tsizeof(opts->device_type));\n+\topts->nb_qps = 1;\n \n \topts->op_type = CPERF_CIPHER_THEN_AUTH;\n \n@@ -789,6 +809,7 @@ cperf_opts_parse_long(int opt_idx, struct cperf_options *opts)\n \t\t{ CPERF_BUFFER_SIZE,\tparse_buffer_sz },\n \t\t{ CPERF_SEGMENT_SIZE,\tparse_segment_sz },\n \t\t{ CPERF_DESC_NB,\tparse_desc_nb },\n+\t\t{ CPERF_QP_NB,\t\tparse_qp_nb },\n \t\t{ CPERF_DEVTYPE,\tparse_device_type },\n \t\t{ CPERF_OPTYPE,\t\tparse_op_type },\n \t\t{ CPERF_SESSIONLESS,\tparse_sessionless },\n@@ -1032,6 +1053,7 @@ cperf_options_dump(struct cperf_options *opts)\n \tprintf(\"#\\n\");\n \tprintf(\"# cryptodev type: %s\\n\", opts->device_type);\n \tprintf(\"#\\n\");\n+\tprintf(\"# number of queue pairs per device: %u\\n\", opts->nb_qps);\n \tprintf(\"# crypto operation: %s\\n\", cperf_op_type_strs[opts->op_type]);\n \tprintf(\"# sessionless: %s\\n\", opts->sessionless ? \"yes\" : \"no\");\n \tprintf(\"# out of place: %s\\n\", opts->out_of_place ? \"yes\" : \"no\");\ndiff --git a/app/test-crypto-perf/cperf_test_latency.c b/app/test-crypto-perf/cperf_test_latency.c\nindex acd8545..99b92d3 100644\n--- a/app/test-crypto-perf/cperf_test_latency.c\n+++ b/app/test-crypto-perf/cperf_test_latency.c\n@@ -218,8 +218,8 @@ cperf_latency_test_constructor(struct rte_mempool *sess_mp,\n \tif (ctx->sess == NULL)\n \t\tgoto err;\n \n-\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_in_cdev_%d\",\n-\t\t\t\tdev_id);\n+\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_in_cdev_%d_qp_%d\",\n+\t\t\tdev_id, qp_id);\n \n \tuint32_t max_size = options->max_buffer_size + options->digest_sz;\n \tuint16_t segments_nb = (max_size % options->segment_sz) ?\n@@ -252,8 +252,8 @@ cperf_latency_test_constructor(struct rte_mempool *sess_mp,\n \tif (options->out_of_place == 1)\t{\n \n \t\tsnprintf(pool_name, sizeof(pool_name),\n-\t\t\t\t\"cperf_pool_out_cdev_%d\",\n-\t\t\t\tdev_id);\n+\t\t\t\t\"cperf_pool_out_cdev_%d_qp_%d\",\n+\t\t\t\tdev_id, qp_id);\n \n \t\tctx->pkt_mbuf_pool_out = rte_pktmbuf_pool_create(\n \t\t\t\tpool_name, options->pool_sz, 0, 0,\n@@ -281,8 +281,8 @@ cperf_latency_test_constructor(struct rte_mempool *sess_mp,\n \t\t}\n \t}\n \n-\tsnprintf(pool_name, sizeof(pool_name), \"cperf_op_pool_cdev_%d\",\n-\t\t\tdev_id);\n+\tsnprintf(pool_name, sizeof(pool_name), \"cperf_op_pool_cdev_%d_qp_%d\",\n+\t\t\tdev_id, qp_id);\n \n \tuint16_t priv_size = RTE_ALIGN_CEIL(sizeof(struct priv_op_data) +\n \t\t\ttest_vector->cipher_iv.length +\n@@ -583,7 +583,5 @@ cperf_latency_test_destructor(void *arg)\n \tif (ctx == NULL)\n \t\treturn;\n \n-\trte_cryptodev_stop(ctx->dev_id);\n-\n \tcperf_latency_test_free(ctx, ctx->options->pool_sz);\n }\ndiff --git a/app/test-crypto-perf/cperf_test_pmd_cyclecount.c b/app/test-crypto-perf/cperf_test_pmd_cyclecount.c\nindex 962dc69..5940836 100644\n--- a/app/test-crypto-perf/cperf_test_pmd_cyclecount.c\n+++ b/app/test-crypto-perf/cperf_test_pmd_cyclecount.c\n@@ -239,7 +239,8 @@ cperf_pmd_cyclecount_test_constructor(struct rte_mempool *sess_mp,\n \tif (ctx->sess == NULL)\n \t\tgoto err;\n \n-\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_in_cdev_%d\", dev_id);\n+\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_in_cdev_%d_qp_%d\",\n+\t\t\tdev_id, qp_id);\n \n \tuint32_t max_size = options->max_buffer_size + options->digest_sz;\n \tuint16_t segments_nb = (max_size % options->segment_sz) ?\n@@ -267,8 +268,8 @@ cperf_pmd_cyclecount_test_constructor(struct rte_mempool *sess_mp,\n \t}\n \n \tif (options->out_of_place == 1) {\n-\t\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_out_cdev_%d\",\n-\t\t\t\tdev_id);\n+\t\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_out_cdev_%d_qp_%d\",\n+\t\t\t\tdev_id, qp_id);\n \n \t\tctx->pkt_mbuf_pool_out = rte_pktmbuf_pool_create(pool_name,\n \t\t\t\toptions->pool_sz, 0, 0,\ndiff --git a/app/test-crypto-perf/cperf_test_throughput.c b/app/test-crypto-perf/cperf_test_throughput.c\nindex e4da0d5..9255915 100644\n--- a/app/test-crypto-perf/cperf_test_throughput.c\n+++ b/app/test-crypto-perf/cperf_test_throughput.c\n@@ -201,8 +201,8 @@ cperf_throughput_test_constructor(struct rte_mempool *sess_mp,\n \tif (ctx->sess == NULL)\n \t\tgoto err;\n \n-\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_in_cdev_%d\",\n-\t\t\tdev_id);\n+\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_in_cdev_%d_qp_%d\",\n+\t\t\tdev_id, qp_id);\n \n \tuint32_t max_size = options->max_buffer_size + options->digest_sz;\n \tuint16_t segments_nb = (max_size % options->segment_sz) ?\n@@ -233,8 +233,8 @@ cperf_throughput_test_constructor(struct rte_mempool *sess_mp,\n \n \tif (options->out_of_place == 1)\t{\n \n-\t\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_out_cdev_%d\",\n-\t\t\t\tdev_id);\n+\t\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_out_cdev_%d_qp_%d\",\n+\t\t\t\tdev_id, qp_id);\n \n \t\tctx->pkt_mbuf_pool_out = rte_pktmbuf_pool_create(\n \t\t\t\tpool_name, options->pool_sz, 0, 0,\n@@ -262,8 +262,8 @@ cperf_throughput_test_constructor(struct rte_mempool *sess_mp,\n \t\t}\n \t}\n \n-\tsnprintf(pool_name, sizeof(pool_name), \"cperf_op_pool_cdev_%d\",\n-\t\t\tdev_id);\n+\tsnprintf(pool_name, sizeof(pool_name), \"cperf_op_pool_cdev_%d_qp_%d\",\n+\t\t\tdev_id, qp_id);\n \n \tuint16_t priv_size = RTE_ALIGN_CEIL(test_vector->cipher_iv.length +\n \t\ttest_vector->auth_iv.length + test_vector->aead_iv.length, 16) +\n@@ -530,7 +530,5 @@ cperf_throughput_test_destructor(void *arg)\n \tif (ctx == NULL)\n \t\treturn;\n \n-\trte_cryptodev_stop(ctx->dev_id);\n-\n \tcperf_throughput_test_free(ctx, ctx->options->pool_sz);\n }\ndiff --git a/app/test-crypto-perf/cperf_test_verify.c b/app/test-crypto-perf/cperf_test_verify.c\nindex 3159361..dd97354 100644\n--- a/app/test-crypto-perf/cperf_test_verify.c\n+++ b/app/test-crypto-perf/cperf_test_verify.c\n@@ -233,8 +233,8 @@ cperf_verify_test_constructor(struct rte_mempool *sess_mp,\n \tif (ctx->sess == NULL)\n \t\tgoto err;\n \n-\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_in_cdev_%d\",\n-\t\t\tdev_id);\n+\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_in_cdev_%d_qp_%d\",\n+\t\t\tdev_id, qp_id);\n \n \tuint32_t max_size = options->max_buffer_size + options->digest_sz;\n \tuint16_t segments_nb = (max_size % options->segment_sz) ?\n@@ -265,8 +265,8 @@ cperf_verify_test_constructor(struct rte_mempool *sess_mp,\n \n \tif (options->out_of_place == 1)\t{\n \n-\t\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_out_cdev_%d\",\n-\t\t\t\tdev_id);\n+\t\tsnprintf(pool_name, sizeof(pool_name), \"cperf_pool_out_cdev_%d_qp_%d\",\n+\t\t\t\tdev_id, qp_id);\n \n \t\tctx->pkt_mbuf_pool_out = rte_pktmbuf_pool_create(\n \t\t\t\tpool_name, options->pool_sz, 0, 0,\n@@ -294,8 +294,8 @@ cperf_verify_test_constructor(struct rte_mempool *sess_mp,\n \t\t}\n \t}\n \n-\tsnprintf(pool_name, sizeof(pool_name), \"cperf_op_pool_cdev_%d\",\n-\t\t\tdev_id);\n+\tsnprintf(pool_name, sizeof(pool_name), \"cperf_op_pool_cdev_%d_qp_%d\",\n+\t\t\tdev_id, qp_id);\n \n \tuint16_t priv_size = RTE_ALIGN_CEIL(test_vector->cipher_iv.length +\n \t\ttest_vector->auth_iv.length + test_vector->aead_iv.length, 16) +\n@@ -626,7 +626,5 @@ cperf_verify_test_destructor(void *arg)\n \tif (ctx == NULL)\n \t\treturn;\n \n-\trte_cryptodev_stop(ctx->dev_id);\n-\n \tcperf_verify_test_free(ctx, ctx->options->pool_sz);\n }\ndiff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c\nindex ffa7180..97dc19c 100644\n--- a/app/test-crypto-perf/main.c\n+++ b/app/test-crypto-perf/main.c\n@@ -90,7 +90,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,\n \t\t\tstruct rte_mempool *session_pool_socket[])\n {\n \tuint8_t enabled_cdev_count = 0, nb_lcores, cdev_id;\n-\tunsigned int i;\n+\tunsigned int i, j;\n \tint ret;\n \n \tenabled_cdev_count = rte_cryptodev_devices_get(opts->device_type,\n@@ -125,8 +125,8 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,\n \t\tuint8_t socket_id = rte_cryptodev_socket_id(cdev_id);\n \n \t\tstruct rte_cryptodev_config conf = {\n-\t\t\t\t.nb_queue_pairs = 1,\n-\t\t\t\t.socket_id = socket_id\n+\t\t\t.nb_queue_pairs = opts->nb_qps,\n+\t\t\t.socket_id = socket_id\n \t\t};\n \n \t\tstruct rte_cryptodev_qp_conf qp_conf = {\n@@ -165,14 +165,16 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,\n \t\t\treturn -EINVAL;\n \t\t}\n \n-\t\tret = rte_cryptodev_queue_pair_setup(cdev_id, 0,\n+\t\tfor (j = 0; j < opts->nb_qps; j++) {\n+\t\t\tret = rte_cryptodev_queue_pair_setup(cdev_id, j,\n \t\t\t\t&qp_conf, socket_id,\n \t\t\t\tsession_pool_socket[socket_id]);\n \t\t\tif (ret < 0) {\n \t\t\t\tprintf(\"Failed to setup queue pair %u on \"\n-\t\t\t\t\t\"cryptodev %u\",\t0, cdev_id);\n+\t\t\t\t\t\"cryptodev %u\",\tj, cdev_id);\n \t\t\t\treturn -EINVAL;\n \t\t\t}\n+\t\t}\n \n \t\tret = rte_cryptodev_start(cdev_id);\n \t\tif (ret < 0) {\n@@ -471,23 +473,29 @@ main(int argc, char **argv)\n \tif (!opts.silent)\n \t\tshow_test_vector(t_vec);\n \n+\tuint16_t total_nb_qps = nb_cryptodevs * opts.nb_qps;\n+\n \ti = 0;\n+\tuint8_t qp_id = 0, cdev_index = 0;\n \tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n \n-\t\tif (i == nb_cryptodevs)\n+\t\tif (i == total_nb_qps)\n \t\t\tbreak;\n \n-\t\tcdev_id = enabled_cdevs[i];\n+\t\tcdev_id = enabled_cdevs[cdev_index];\n \n \t\tuint8_t socket_id = rte_cryptodev_socket_id(cdev_id);\n \n-\t\tctx[cdev_id] = cperf_testmap[opts.test].constructor(\n-\t\t\t\tsession_pool_socket[socket_id], cdev_id, 0,\n+\t\tctx[i] = cperf_testmap[opts.test].constructor(\n+\t\t\t\tsession_pool_socket[socket_id], cdev_id, qp_id,\n \t\t\t\t&opts, t_vec, &op_fns);\n-\t\tif (ctx[cdev_id] == NULL) {\n+\t\tif (ctx[i] == NULL) {\n \t\t\tRTE_LOG(ERR, USER1, \"Test run constructor failed\\n\");\n \t\t\tgoto err;\n \t\t}\n+\t\tqp_id = (qp_id + 1) % opts.nb_qps;\n+\t\tif (qp_id == 0)\n+\t\t\tcdev_index++;\n \t\ti++;\n \t}\n \n@@ -501,19 +509,17 @@ main(int argc, char **argv)\n \t\ti = 0;\n \t\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n \n-\t\t\tif (i == nb_cryptodevs)\n+\t\t\tif (i == total_nb_qps)\n \t\t\t\tbreak;\n \n-\t\t\tcdev_id = enabled_cdevs[i];\n-\n \t\t\trte_eal_remote_launch(cperf_testmap[opts.test].runner,\n-\t\t\t\tctx[cdev_id], lcore_id);\n+\t\t\t\tctx[i], lcore_id);\n \t\t\ti++;\n \t\t}\n \t\ti = 0;\n \t\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n \n-\t\t\tif (i == nb_cryptodevs)\n+\t\t\tif (i == total_nb_qps)\n \t\t\t\tbreak;\n \t\t\trte_eal_wait_lcore(lcore_id);\n \t\t\ti++;\n@@ -532,15 +538,17 @@ main(int argc, char **argv)\n \ti = 0;\n \tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n \n-\t\tif (i == nb_cryptodevs)\n+\t\tif (i == total_nb_qps)\n \t\t\tbreak;\n \n-\t\tcdev_id = enabled_cdevs[i];\n-\n-\t\tcperf_testmap[opts.test].destructor(ctx[cdev_id]);\n+\t\tcperf_testmap[opts.test].destructor(ctx[i]);\n \t\ti++;\n \t}\n \n+\tfor (i = 0; i < nb_cryptodevs &&\n+\t\t\ti < RTE_CRYPTO_MAX_DEVS; i++)\n+\t\trte_cryptodev_stop(enabled_cdevs[i]);\n+\n \tfree_test_vector(t_vec, &opts);\n \n \tprintf(\"\\n\");\n@@ -549,16 +557,20 @@ main(int argc, char **argv)\n err:\n \ti = 0;\n \tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n-\t\tif (i == nb_cryptodevs)\n+\t\tif (i == total_nb_qps)\n \t\t\tbreak;\n \n \t\tcdev_id = enabled_cdevs[i];\n \n-\t\tif (ctx[cdev_id] && cperf_testmap[opts.test].destructor)\n-\t\t\tcperf_testmap[opts.test].destructor(ctx[cdev_id]);\n+\t\tif (ctx[i] && cperf_testmap[opts.test].destructor)\n+\t\t\tcperf_testmap[opts.test].destructor(ctx[i]);\n \t\ti++;\n \t}\n \n+\tfor (i = 0; i < nb_cryptodevs &&\n+\t\t\ti < RTE_CRYPTO_MAX_DEVS; i++)\n+\t\trte_cryptodev_stop(enabled_cdevs[i]);\n+\n \tfree_test_vector(t_vec, &opts);\n \n \tprintf(\"\\n\");\ndiff --git a/doc/guides/tools/cryptoperf.rst b/doc/guides/tools/cryptoperf.rst\nindex d587c20..b114b15 100644\n--- a/doc/guides/tools/cryptoperf.rst\n+++ b/doc/guides/tools/cryptoperf.rst\n@@ -194,6 +194,10 @@ The following are the appication command-line options:\n            crypto_armv8\n            crypto_scheduler\n \n+* ``--qp-nb <n>``\n+\n+       Set the number of queue pairs per device (1 by default).\n+\n * ``--optype <name>``\n \n         Set operation type, where ``name`` is one of the following::\n",
    "prefixes": [
        "dpdk-dev",
        "v3",
        "6/7"
    ]
}