get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 54570,
    "url": "http://patches.dpdk.org/api/patches/54570/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1560032553-15528-2-git-send-email-tjozwiakgm@gmail.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": "<1560032553-15528-2-git-send-email-tjozwiakgm@gmail.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1560032553-15528-2-git-send-email-tjozwiakgm@gmail.com",
    "date": "2019-06-08T22:22:27",
    "name": "[v2,1/7] app/test-compress-perf: add weak functions for multi-cores test",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "9a1eaaea9915e830a76902b2e10b9b7141be8dde",
    "submitter": {
        "id": 1263,
        "url": "http://patches.dpdk.org/api/people/1263/?format=api",
        "name": "Tomasz Jóźwiak",
        "email": "tjozwiakgm@gmail.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/1560032553-15528-2-git-send-email-tjozwiakgm@gmail.com/mbox/",
    "series": [
        {
            "id": 4958,
            "url": "http://patches.dpdk.org/api/series/4958/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=4958",
            "date": "2019-06-08T22:22:26",
            "name": "add multiple cores feature to test-compress-perf",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/4958/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/54570/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/54570/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 10C071BD2B;\n\tSun,  9 Jun 2019 00:22:46 +0200 (CEST)",
            "from mail-lj1-f196.google.com (mail-lj1-f196.google.com\n\t[209.85.208.196]) by dpdk.org (Postfix) with ESMTP id 9D5DC1BD25\n\tfor <dev@dpdk.org>; Sun,  9 Jun 2019 00:22:44 +0200 (CEST)",
            "by mail-lj1-f196.google.com with SMTP id 16so4695363ljv.10\n\tfor <dev@dpdk.org>; Sat, 08 Jun 2019 15:22:44 -0700 (PDT)",
            "from tj-idea-500s.lan (user-5-173-144-53.play-internet.pl.\n\t[5.173.144.53]) by smtp.gmail.com with ESMTPSA id\n\tw28sm1060597ljd.12.2019.06.08.15.22.41\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tSat, 08 Jun 2019 15:22:43 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=from:to:subject:date:message-id:in-reply-to:references;\n\tbh=UdXle5jAWPkYstQJqMJU12yxwJAXBib0T+TTEAybjoY=;\n\tb=XE1X6txdfrPZ1+E8yScnY6FrdRfCNEjJqLVT5WI7So9Y8MEQ7VzXApZcpsCQuf7EU1\n\tVAC9C78M3HErUWFut0Tza544VVq2kS5VQqxosekk7tY0AiOBHvZnlYukp2aBkBpI52Fj\n\t0B4l0epw6QhGE7FszAi/XaquSdKbHgD+Yf8z4Fqc0tyi5IdcTCPG2cpr7/GFn1F0/T2j\n\tgmgQiNtibh9233uyM2c4EYXPE1Cc40v2h+wji3O9FJ7N96CGndWk2LiJuYrp8JRBkGaK\n\tyaIVnSaPpa5TfT9199pRgdvjnQ+IS0sJffX/vmL256DF6Hm9QUTNLILrEBfK5ehYW6Gt\n\tWMsA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=UdXle5jAWPkYstQJqMJU12yxwJAXBib0T+TTEAybjoY=;\n\tb=mldbNge5VGrCZeZ0tcpovuw17sT9/ZnmxvFqu4hwfyCpFt7ozyFPXlxWZLBPdukZJi\n\tX9yetIx7b9PLYEmVIr44U+YvhZX8rG6/w6TeFm+KUjUfhGVPt10GulnfSMxdk+RvuV5w\n\t1qjvqNJXyRlIjQSDFihe0pmQmO99Vhhsl9Ux2EXTyiHXJQKKxRjXI7flepq+3o5LUOvn\n\tDsk2mNc9y7OEQKD/c+YS5sjnfVfdRRWD3Qdpq1GetIaqTbVeL+z3q1t6irfULWJgTunI\n\tUeHbu8VqQDNTBi7/qhwrx+GR0514xjA2SKaFBfZ4AxL0XzKnVpDWnMjTK58BkM1KRoqg\n\tzg7Q==",
        "X-Gm-Message-State": "APjAAAUaVJJseSEYtRRosNWu3XnhGGSbL7ruGz6LbdQiflh6omePHU2t\n\tAm0PvQkd9P6RFouAMVCocQhjFv+6kSk=",
        "X-Google-Smtp-Source": "APXvYqyD3iZzsJaDLGuvcVuvNsERCRAIqHih4U3YJGJyS+N2uq1PWs+FvKOEstBD7du8/eZ9TU56Og==",
        "X-Received": "by 2002:a2e:9a19:: with SMTP id\n\to25mr19559365lji.63.1560032563649; \n\tSat, 08 Jun 2019 15:22:43 -0700 (PDT)",
        "From": "Tomasz Jozwiak <tjozwiakgm@gmail.com>",
        "To": "dev@dpdk.org, fiona.trahe@intel.com, tjozwiakgm@gmail.com,\n\tshallyv@marvell.com",
        "Date": "Sun,  9 Jun 2019 00:22:27 +0200",
        "Message-Id": "<1560032553-15528-2-git-send-email-tjozwiakgm@gmail.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1560032553-15528-1-git-send-email-tjozwiakgm@gmail.com>",
        "References": "<1559203588-24046-1-git-send-email-tomaszx.jozwiak@intel.com>\n\t<1560032553-15528-1-git-send-email-tjozwiakgm@gmail.com>",
        "Subject": "[dpdk-dev] [PATCH v2 1/7] app/test-compress-perf: add weak\n\tfunctions for multi-cores test",
        "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": "From: Tomasz Jozwiak <tomaszx.jozwiak@intel.com>\n\nThis patch adds a template functions for multi-cores performance\nversion of compress-perf-tool.\n\nSigned-off-by: Tomasz Jozwiak <tjozwiakgm@gmail.com>\nSigned-off-by: Tomasz Jozwiak <tomaszx.jozwiak@intel.com>\n---\n app/test-compress-perf/Makefile                  |   3 +-\n app/test-compress-perf/comp_perf.h               |  61 +++\n app/test-compress-perf/comp_perf_options.h       |  45 +-\n app/test-compress-perf/comp_perf_options_parse.c |  24 +-\n app/test-compress-perf/comp_perf_test_common.c   | 285 +++++++++++\n app/test-compress-perf/comp_perf_test_common.h   |  41 ++\n app/test-compress-perf/main.c                    | 627 ++++++++++-------------\n app/test-compress-perf/meson.build               |   3 +-\n 8 files changed, 688 insertions(+), 401 deletions(-)\n create mode 100644 app/test-compress-perf/comp_perf.h\n create mode 100644 app/test-compress-perf/comp_perf_test_common.c\n create mode 100644 app/test-compress-perf/comp_perf_test_common.h",
    "diff": "diff --git a/app/test-compress-perf/Makefile b/app/test-compress-perf/Makefile\nindex d20e17e..de74129 100644\n--- a/app/test-compress-perf/Makefile\n+++ b/app/test-compress-perf/Makefile\n@@ -12,7 +12,6 @@ CFLAGS += -O3\n # all source are stored in SRCS-y\n SRCS-y := main.c\n SRCS-y += comp_perf_options_parse.c\n-SRCS-y += comp_perf_test_verify.c\n-SRCS-y += comp_perf_test_benchmark.c\n+SRCS-y += comp_perf_test_common.c\n \n include $(RTE_SDK)/mk/rte.app.mk\ndiff --git a/app/test-compress-perf/comp_perf.h b/app/test-compress-perf/comp_perf.h\nnew file mode 100644\nindex 0000000..144ad8a\n--- /dev/null\n+++ b/app/test-compress-perf/comp_perf.h\n@@ -0,0 +1,61 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019 Intel Corporation\n+ */\n+\n+#ifndef _COMP_PERF_\n+#define _COMP_PERF_\n+\n+#include <rte_mempool.h>\n+\n+struct comp_test_data;\n+\n+typedef void  *(*cperf_constructor_t)(\n+\t\tuint8_t dev_id,\n+\t\tuint16_t qp_id,\n+\t\tstruct comp_test_data *options);\n+\n+typedef int (*cperf_runner_t)(void *test_ctx);\n+typedef void (*cperf_destructor_t)(void *test_ctx);\n+\n+struct cperf_test {\n+\tcperf_constructor_t constructor;\n+\tcperf_runner_t runner;\n+\tcperf_destructor_t destructor;\n+};\n+\n+/* Needed for weak functions*/\n+\n+void *\n+cperf_benchmark_test_constructor(uint8_t dev_id __rte_unused,\n+\t\t\t\t uint16_t qp_id __rte_unused,\n+\t\t\t\t struct comp_test_data *options __rte_unused);\n+\n+void\n+cperf_benchmark_test_destructor(void *arg __rte_unused);\n+\n+int\n+cperf_benchmark_test_runner(void *test_ctx __rte_unused);\n+\n+void *\n+cperf_verify_test_constructor(uint8_t dev_id __rte_unused,\n+\t\t\t\t uint16_t qp_id __rte_unused,\n+\t\t\t\t struct comp_test_data *options __rte_unused);\n+\n+void\n+cperf_verify_test_destructor(void *arg __rte_unused);\n+\n+int\n+cperf_verify_test_runner(void *test_ctx __rte_unused);\n+\n+void *\n+cperf_pmd_cyclecount_test_constructor(uint8_t dev_id __rte_unused,\n+\t\t\t\t uint16_t qp_id __rte_unused,\n+\t\t\t\t struct comp_test_data *options __rte_unused);\n+\n+void\n+cperf_pmd_cyclecount_test_destructor(void *arg __rte_unused);\n+\n+int\n+cperf_pmd_cyclecount_test_runner(void *test_ctx __rte_unused);\n+\n+#endif /* _COMP_PERF_ */\ndiff --git a/app/test-compress-perf/comp_perf_options.h b/app/test-compress-perf/comp_perf_options.h\nindex f87751d..79e63d5 100644\n--- a/app/test-compress-perf/comp_perf_options.h\n+++ b/app/test-compress-perf/comp_perf_options.h\n@@ -13,6 +13,24 @@\n #define MAX_MBUF_DATA_SIZE (UINT16_MAX - RTE_PKTMBUF_HEADROOM)\n #define MAX_SEG_SIZE ((int)(MAX_MBUF_DATA_SIZE / EXPANSE_RATIO))\n \n+extern const char *cperf_test_type_strs[];\n+\n+/* Cleanup state machine */\n+enum cleanup_st {\n+\tST_CLEAR = 0,\n+\tST_TEST_DATA,\n+\tST_COMPDEV,\n+\tST_INPUT_DATA,\n+\tST_MEMORY_ALLOC,\n+\tST_DURING_TEST\n+};\n+\n+enum cperf_perf_test_type {\n+\tCPERF_TEST_TYPE_BENCHMARK,\n+\tCPERF_TEST_TYPE_VERIFY,\n+\tCPERF_TEST_TYPE_PMDCC\n+};\n+\n enum comp_operation {\n \tCOMPRESS_ONLY,\n \tDECOMPRESS_ONLY,\n@@ -30,37 +48,26 @@ struct range_list {\n struct comp_test_data {\n \tchar driver_name[64];\n \tchar input_file[64];\n-\tstruct rte_mbuf **comp_bufs;\n-\tstruct rte_mbuf **decomp_bufs;\n-\tuint32_t total_bufs;\n+\tenum cperf_perf_test_type test;\n+\n \tuint8_t *input_data;\n \tsize_t input_data_sz;\n-\tuint8_t *compressed_data;\n-\tuint8_t *decompressed_data;\n-\tstruct rte_mempool *comp_buf_pool;\n-\tstruct rte_mempool *decomp_buf_pool;\n-\tstruct rte_mempool *op_pool;\n-\tint8_t cdev_id;\n+\tuint16_t nb_qps;\n \tuint16_t seg_sz;\n \tuint16_t out_seg_sz;\n \tuint16_t burst_sz;\n \tuint32_t pool_sz;\n \tuint32_t num_iter;\n \tuint16_t max_sgl_segs;\n+\n \tenum rte_comp_huffman huffman_enc;\n \tenum comp_operation test_op;\n \tint window_sz;\n-\tstruct range_list level;\n-\t/* Store TSC duration for all levels (including level 0) */\n-\tuint64_t comp_tsc_duration[RTE_COMP_LEVEL_MAX + 1];\n-\tuint64_t decomp_tsc_duration[RTE_COMP_LEVEL_MAX + 1];\n-\tsize_t comp_data_sz;\n-\tsize_t decomp_data_sz;\n+\tstruct range_list level_lst;\n+\tuint8_t level;\n+\n \tdouble ratio;\n-\tdouble comp_gbps;\n-\tdouble decomp_gbps;\n-\tdouble comp_tsc_byte;\n-\tdouble decomp_tsc_byte;\n+\tenum cleanup_st cleanup;\n };\n \n int\ndiff --git a/app/test-compress-perf/comp_perf_options_parse.c b/app/test-compress-perf/comp_perf_options_parse.c\nindex 2fb6fb4..bc4b98a 100644\n--- a/app/test-compress-perf/comp_perf_options_parse.c\n+++ b/app/test-compress-perf/comp_perf_options_parse.c\n@@ -466,19 +466,20 @@ parse_level(struct comp_test_data *test_data, const char *arg)\n \t * Try parsing the argument as a range, if it fails,\n \t * arse it as a list\n \t */\n-\tif (parse_range(arg, &test_data->level.min, &test_data->level.max,\n-\t\t\t&test_data->level.inc) < 0) {\n-\t\tret = parse_list(arg, test_data->level.list,\n-\t\t\t\t\t&test_data->level.min,\n-\t\t\t\t\t&test_data->level.max);\n+\tif (parse_range(arg, &test_data->level_lst.min,\n+\t\t\t&test_data->level_lst.max,\n+\t\t\t&test_data->level_lst.inc) < 0) {\n+\t\tret = parse_list(arg, test_data->level_lst.list,\n+\t\t\t\t\t&test_data->level_lst.min,\n+\t\t\t\t\t&test_data->level_lst.max);\n \t\tif (ret < 0) {\n \t\t\tRTE_LOG(ERR, USER1,\n \t\t\t\t\"Failed to parse compression level/s\\n\");\n \t\t\treturn -1;\n \t\t}\n-\t\ttest_data->level.count = ret;\n+\t\ttest_data->level_lst.count = ret;\n \n-\t\tif (test_data->level.max > RTE_COMP_LEVEL_MAX) {\n+\t\tif (test_data->level_lst.max > RTE_COMP_LEVEL_MAX) {\n \t\t\tRTE_LOG(ERR, USER1, \"Level cannot be higher than %u\\n\",\n \t\t\t\t\tRTE_COMP_LEVEL_MAX);\n \t\t\treturn -1;\n@@ -498,7 +499,6 @@ struct long_opt_parser {\n };\n \n static struct option lgopts[] = {\n-\n \t{ CPERF_DRIVER_NAME, required_argument, 0, 0 },\n \t{ CPERF_TEST_FILE, required_argument, 0, 0 },\n \t{ CPERF_SEG_SIZE, required_argument, 0, 0 },\n@@ -572,7 +572,6 @@ comp_perf_options_parse(struct comp_test_data *test_data, int argc, char **argv)\n void\n comp_perf_options_default(struct comp_test_data *test_data)\n {\n-\ttest_data->cdev_id = -1;\n \ttest_data->seg_sz = 2048;\n \ttest_data->burst_sz = 32;\n \ttest_data->pool_sz = 8192;\n@@ -581,9 +580,10 @@ comp_perf_options_default(struct comp_test_data *test_data)\n \ttest_data->huffman_enc = RTE_COMP_HUFFMAN_DYNAMIC;\n \ttest_data->test_op = COMPRESS_DECOMPRESS;\n \ttest_data->window_sz = -1;\n-\ttest_data->level.min = 1;\n-\ttest_data->level.max = 9;\n-\ttest_data->level.inc = 1;\n+\ttest_data->level_lst.min = 1;\n+\ttest_data->level_lst.max = 9;\n+\ttest_data->level_lst.inc = 1;\n+\ttest_data->test = CPERF_TEST_TYPE_BENCHMARK;\n }\n \n int\ndiff --git a/app/test-compress-perf/comp_perf_test_common.c b/app/test-compress-perf/comp_perf_test_common.c\nnew file mode 100644\nindex 0000000..1d2b25e\n--- /dev/null\n+++ b/app/test-compress-perf/comp_perf_test_common.c\n@@ -0,0 +1,285 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019 Intel Corporation\n+ */\n+\n+#include <rte_malloc.h>\n+#include <rte_eal.h>\n+#include <rte_log.h>\n+#include <rte_compressdev.h>\n+\n+#include \"comp_perf_options.h\"\n+#include \"comp_perf_test_verify.h\"\n+#include \"comp_perf_test_benchmark.h\"\n+#include \"comp_perf.h\"\n+#include \"comp_perf_test_common.h\"\n+\n+#define DIV_CEIL(a, b)  ((a) / (b) + ((a) % (b) != 0))\n+\n+int\n+param_range_check(uint16_t size, const struct rte_param_log2_range *range)\n+{\n+\tunsigned int next_size;\n+\n+\t/* Check lower/upper bounds */\n+\tif (size < range->min)\n+\t\treturn -1;\n+\n+\tif (size > range->max)\n+\t\treturn -1;\n+\n+\t/* If range is actually only one value, size is correct */\n+\tif (range->increment == 0)\n+\t\treturn 0;\n+\n+\t/* Check if value is one of the supported sizes */\n+\tfor (next_size = range->min; next_size <= range->max;\n+\t\t\tnext_size += range->increment)\n+\t\tif (size == next_size)\n+\t\t\treturn 0;\n+\n+\treturn -1;\n+}\n+\n+static uint32_t\n+find_buf_size(uint32_t input_size)\n+{\n+\tuint32_t i;\n+\n+\t/* From performance point of view the buffer size should be a\n+\t * power of 2 but also should be enough to store incompressible data\n+\t */\n+\n+\t/* We're looking for nearest power of 2 buffer size, which is greather\n+\t * than input_size\n+\t */\n+\tuint32_t size =\n+\t\t!input_size ? MIN_COMPRESSED_BUF_SIZE : (input_size << 1);\n+\n+\tfor (i = UINT16_MAX + 1; !(i & size); i >>= 1)\n+\t\t;\n+\n+\treturn i > ((UINT16_MAX + 1) >> 1)\n+\t\t\t? (uint32_t)((float)input_size * EXPANSE_RATIO)\n+\t\t\t: i;\n+}\n+\n+void\n+comp_perf_free_memory(struct cperf_mem_resources *mem)\n+{\n+\tuint32_t i;\n+\n+\tfor (i = 0; i < mem->total_bufs; i++) {\n+\t\trte_pktmbuf_free(mem->comp_bufs[i]);\n+\t\trte_pktmbuf_free(mem->decomp_bufs[i]);\n+\t}\n+\n+\trte_free(mem->decomp_bufs);\n+\trte_free(mem->comp_bufs);\n+\trte_free(mem->decompressed_data);\n+\trte_free(mem->compressed_data);\n+\trte_mempool_free(mem->op_pool);\n+\trte_mempool_free(mem->decomp_buf_pool);\n+\trte_mempool_free(mem->comp_buf_pool);\n+}\n+\n+int\n+comp_perf_allocate_memory(struct comp_test_data *test_data,\n+\t\t\t  struct cperf_mem_resources *mem)\n+{\n+\ttest_data->out_seg_sz = find_buf_size(test_data->seg_sz);\n+\t/* Number of segments for input and output\n+\t * (compression and decompression)\n+\t */\n+\tuint32_t total_segs = DIV_CEIL(test_data->input_data_sz,\n+\t\t\ttest_data->seg_sz);\n+\tchar pool_name[32] = \"\";\n+\n+\tsnprintf(pool_name, sizeof(pool_name), \"comp_buf_pool_%u_qp_%u\",\n+\t\t\tmem->dev_id, mem->qp_id);\n+\tmem->comp_buf_pool = rte_pktmbuf_pool_create(pool_name,\n+\t\t\t\ttotal_segs,\n+\t\t\t\t0, 0,\n+\t\t\t\ttest_data->out_seg_sz + RTE_PKTMBUF_HEADROOM,\n+\t\t\t\trte_socket_id());\n+\tif (mem->comp_buf_pool == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"Mbuf mempool could not be created\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tsnprintf(pool_name, sizeof(pool_name), \"decomp_buf_pool_%u_qp_%u\",\n+\t\t\tmem->dev_id, mem->qp_id);\n+\tmem->decomp_buf_pool = rte_pktmbuf_pool_create(pool_name,\n+\t\t\t\ttotal_segs,\n+\t\t\t\t0, 0, test_data->seg_sz + RTE_PKTMBUF_HEADROOM,\n+\t\t\t\trte_socket_id());\n+\tif (mem->decomp_buf_pool == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"Mbuf mempool could not be created\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tmem->total_bufs = DIV_CEIL(total_segs, test_data->max_sgl_segs);\n+\n+\tsnprintf(pool_name, sizeof(pool_name), \"op_pool_%u_qp_%u\",\n+\t\t\tmem->dev_id, mem->qp_id);\n+\tmem->op_pool = rte_comp_op_pool_create(pool_name,\n+\t\t\t\t  mem->total_bufs,\n+\t\t\t\t  0, 0, rte_socket_id());\n+\tif (mem->op_pool == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"Comp op mempool could not be created\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\t/*\n+\t * Compressed data might be a bit larger than input data,\n+\t * if data cannot be compressed\n+\t */\n+\tmem->compressed_data = rte_zmalloc_socket(NULL,\n+\t\t\t\ttest_data->input_data_sz * EXPANSE_RATIO\n+\t\t\t\t\t\t+ MIN_COMPRESSED_BUF_SIZE, 0,\n+\t\t\t\trte_socket_id());\n+\tif (mem->compressed_data == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"Memory to hold the data from the input \"\n+\t\t\t\t\"file could not be allocated\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tmem->decompressed_data = rte_zmalloc_socket(NULL,\n+\t\t\t\ttest_data->input_data_sz, 0,\n+\t\t\t\trte_socket_id());\n+\tif (mem->decompressed_data == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"Memory to hold the data from the input \"\n+\t\t\t\t\"file could not be allocated\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tmem->comp_bufs = rte_zmalloc_socket(NULL,\n+\t\t\tmem->total_bufs * sizeof(struct rte_mbuf *),\n+\t\t\t0, rte_socket_id());\n+\tif (mem->comp_bufs == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"Memory to hold the compression mbufs\"\n+\t\t\t\t\" could not be allocated\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tmem->decomp_bufs = rte_zmalloc_socket(NULL,\n+\t\t\tmem->total_bufs * sizeof(struct rte_mbuf *),\n+\t\t\t0, rte_socket_id());\n+\tif (mem->decomp_bufs == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"Memory to hold the decompression mbufs\"\n+\t\t\t\t\" could not be allocated\\n\");\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+prepare_bufs(struct comp_test_data *test_data, struct cperf_mem_resources *mem)\n+{\n+\tuint32_t remaining_data = test_data->input_data_sz;\n+\tuint8_t *input_data_ptr = test_data->input_data;\n+\tsize_t data_sz;\n+\tuint8_t *data_addr;\n+\tuint32_t i, j;\n+\n+\tfor (i = 0; i < mem->total_bufs; i++) {\n+\t\t/* Allocate data in input mbuf and copy data from input file */\n+\t\tmem->decomp_bufs[i] =\n+\t\t\trte_pktmbuf_alloc(mem->decomp_buf_pool);\n+\t\tif (mem->decomp_bufs[i] == NULL) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Could not allocate mbuf\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tdata_sz = RTE_MIN(remaining_data, test_data->seg_sz);\n+\t\tdata_addr = (uint8_t *) rte_pktmbuf_append(\n+\t\t\t\t\tmem->decomp_bufs[i], data_sz);\n+\t\tif (data_addr == NULL) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Could not append data\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\t\trte_memcpy(data_addr, input_data_ptr, data_sz);\n+\n+\t\tinput_data_ptr += data_sz;\n+\t\tremaining_data -= data_sz;\n+\n+\t\t/* Already one segment in the mbuf */\n+\t\tuint16_t segs_per_mbuf = 1;\n+\n+\t\t/* Chain mbufs if needed for input mbufs */\n+\t\twhile (segs_per_mbuf < test_data->max_sgl_segs\n+\t\t\t\t&& remaining_data > 0) {\n+\t\t\tstruct rte_mbuf *next_seg =\n+\t\t\t\trte_pktmbuf_alloc(mem->decomp_buf_pool);\n+\n+\t\t\tif (next_seg == NULL) {\n+\t\t\t\tRTE_LOG(ERR, USER1,\n+\t\t\t\t\t\"Could not allocate mbuf\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\n+\t\t\tdata_sz = RTE_MIN(remaining_data, test_data->seg_sz);\n+\t\t\tdata_addr = (uint8_t *)rte_pktmbuf_append(next_seg,\n+\t\t\t\tdata_sz);\n+\n+\t\t\tif (data_addr == NULL) {\n+\t\t\t\tRTE_LOG(ERR, USER1, \"Could not append data\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\n+\t\t\trte_memcpy(data_addr, input_data_ptr, data_sz);\n+\t\t\tinput_data_ptr += data_sz;\n+\t\t\tremaining_data -= data_sz;\n+\n+\t\t\tif (rte_pktmbuf_chain(mem->decomp_bufs[i],\n+\t\t\t\t\tnext_seg) < 0) {\n+\t\t\t\tRTE_LOG(ERR, USER1, \"Could not chain mbufs\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tsegs_per_mbuf++;\n+\t\t}\n+\n+\t\t/* Allocate data in output mbuf */\n+\t\tmem->comp_bufs[i] =\n+\t\t\trte_pktmbuf_alloc(mem->comp_buf_pool);\n+\t\tif (mem->comp_bufs[i] == NULL) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Could not allocate mbuf\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\t\tdata_addr = (uint8_t *) rte_pktmbuf_append(\n+\t\t\t\t\tmem->comp_bufs[i],\n+\t\t\t\t\ttest_data->out_seg_sz);\n+\t\tif (data_addr == NULL) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Could not append data\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t/* Chain mbufs if needed for output mbufs */\n+\t\tfor (j = 1; j < segs_per_mbuf; j++) {\n+\t\t\tstruct rte_mbuf *next_seg =\n+\t\t\t\trte_pktmbuf_alloc(mem->comp_buf_pool);\n+\n+\t\t\tif (next_seg == NULL) {\n+\t\t\t\tRTE_LOG(ERR, USER1,\n+\t\t\t\t\t\"Could not allocate mbuf\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\n+\t\t\tdata_addr = (uint8_t *)rte_pktmbuf_append(next_seg,\n+\t\t\t\ttest_data->out_seg_sz);\n+\n+\t\t\tif (data_addr == NULL) {\n+\t\t\t\tRTE_LOG(ERR, USER1, \"Could not append data\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\n+\t\t\tif (rte_pktmbuf_chain(mem->comp_bufs[i],\n+\t\t\t\t\tnext_seg) < 0) {\n+\t\t\t\tRTE_LOG(ERR, USER1, \"Could not chain mbufs\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\ndiff --git a/app/test-compress-perf/comp_perf_test_common.h b/app/test-compress-perf/comp_perf_test_common.h\nnew file mode 100644\nindex 0000000..9c11e3a\n--- /dev/null\n+++ b/app/test-compress-perf/comp_perf_test_common.h\n@@ -0,0 +1,41 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019 Intel Corporation\n+ */\n+\n+#ifndef _COMP_PERF_TEST_COMMON_H_\n+#define _COMP_PERF_TEST_COMMON_H_\n+\n+#include <stdint.h>\n+\n+#include <rte_mempool.h>\n+\n+struct cperf_mem_resources {\n+\tuint8_t dev_id;\n+\tuint16_t qp_id;\n+\tuint8_t lcore_id;\n+\tuint32_t total_bufs;\n+\tuint8_t *compressed_data;\n+\tuint8_t *decompressed_data;\n+\n+\tstruct rte_mbuf **comp_bufs;\n+\tstruct rte_mbuf **decomp_bufs;\n+\n+\tstruct rte_mempool *comp_buf_pool;\n+\tstruct rte_mempool *decomp_buf_pool;\n+\tstruct rte_mempool *op_pool;\n+};\n+\n+int\n+param_range_check(uint16_t size, const struct rte_param_log2_range *range);\n+\n+void\n+comp_perf_free_memory(struct cperf_mem_resources *mem);\n+\n+int\n+comp_perf_allocate_memory(struct comp_test_data *test_data,\n+\t\t\t  struct cperf_mem_resources *mem);\n+\n+int\n+prepare_bufs(struct comp_test_data *test_data, struct cperf_mem_resources *mem);\n+\n+#endif /* _COMP_PERF_TEST_COMMON_H_ */\ndiff --git a/app/test-compress-perf/main.c b/app/test-compress-perf/main.c\nindex c2a45d1..c65d609 100644\n--- a/app/test-compress-perf/main.c\n+++ b/app/test-compress-perf/main.c\n@@ -8,56 +8,44 @@\n #include <rte_compressdev.h>\n \n #include \"comp_perf_options.h\"\n-#include \"comp_perf_test_verify.h\"\n-#include \"comp_perf_test_benchmark.h\"\n+#include \"comp_perf.h\"\n+#include \"comp_perf_test_common.h\"\n \n #define NUM_MAX_XFORMS 16\n #define NUM_MAX_INFLIGHT_OPS 512\n \n-#define DIV_CEIL(a, b)  ((a) / (b) + ((a) % (b) != 0))\n-\n-/* Cleanup state machine */\n-static enum cleanup_st {\n-\tST_CLEAR = 0,\n-\tST_TEST_DATA,\n-\tST_COMPDEV,\n-\tST_INPUT_DATA,\n-\tST_MEMORY_ALLOC,\n-\tST_PREPARE_BUF,\n-\tST_DURING_TEST\n-} cleanup = ST_CLEAR;\n-\n-static int\n-param_range_check(uint16_t size, const struct rte_param_log2_range *range)\n-{\n-\tunsigned int next_size;\n-\n-\t/* Check lower/upper bounds */\n-\tif (size < range->min)\n-\t\treturn -1;\n-\n-\tif (size > range->max)\n-\t\treturn -1;\n-\n-\t/* If range is actually only one value, size is correct */\n-\tif (range->increment == 0)\n-\t\treturn 0;\n-\n-\t/* Check if value is one of the supported sizes */\n-\tfor (next_size = range->min; next_size <= range->max;\n-\t\t\tnext_size += range->increment)\n-\t\tif (size == next_size)\n-\t\t\treturn 0;\n-\n-\treturn -1;\n-}\n+__extension__\n+const char *cperf_test_type_strs[] = {\n+\t[CPERF_TEST_TYPE_BENCHMARK] = \"benchmark\",\n+\t[CPERF_TEST_TYPE_VERIFY] = \"verify\",\n+\t[CPERF_TEST_TYPE_PMDCC] = \"pmd-cyclecount\"\n+};\n+\n+__extension__\n+static const struct cperf_test cperf_testmap[] = {\n+\t[CPERF_TEST_TYPE_BENCHMARK] = {\n+\t\t\tcperf_benchmark_test_constructor,\n+\t\t\tcperf_benchmark_test_runner,\n+\t\t\tcperf_benchmark_test_destructor\n+\t},\n+\t[CPERF_TEST_TYPE_VERIFY] = {\n+\t\t\tcperf_verify_test_constructor,\n+\t\t\tcperf_verify_test_runner,\n+\t\t\tcperf_verify_test_destructor\n+\t},\n+\t[CPERF_TEST_TYPE_PMDCC] = {\n+\t\t\tcperf_pmd_cyclecount_test_constructor,\n+\t\t\tcperf_pmd_cyclecount_test_runner,\n+\t\t\tcperf_pmd_cyclecount_test_destructor\n+\t}\n+};\n \n static int\n-comp_perf_check_capabilities(struct comp_test_data *test_data)\n+comp_perf_check_capabilities(struct comp_test_data *test_data, uint8_t cdev_id)\n {\n \tconst struct rte_compressdev_capabilities *cap;\n \n-\tcap = rte_compressdev_capability_get(test_data->cdev_id,\n+\tcap = rte_compressdev_capability_get(cdev_id,\n \t\t\t\t\t     RTE_COMP_ALGO_DEFLATE);\n \n \tif (cap == NULL) {\n@@ -105,7 +93,7 @@ comp_perf_check_capabilities(struct comp_test_data *test_data)\n \t}\n \n \t/* Level 0 support */\n-\tif (test_data->level.min == 0 &&\n+\tif (test_data->level_lst.min == 0 &&\n \t\t\t(comp_flags & RTE_COMP_FF_NONCOMPRESSED_BLOCKS) == 0) {\n \t\tRTE_LOG(ERR, USER1, \"Compress device does not support \"\n \t\t\t\t\"level 0 (no compression)\\n\");\n@@ -115,110 +103,108 @@ comp_perf_check_capabilities(struct comp_test_data *test_data)\n \treturn 0;\n }\n \n-static uint32_t\n-find_buf_size(uint32_t input_size)\n+static int\n+comp_perf_initialize_compressdev(struct comp_test_data *test_data,\n+\t\t\t\t uint8_t *enabled_cdevs)\n {\n-\tuint32_t i;\n+\tuint8_t enabled_cdev_count, nb_lcores, cdev_id;\n+\tunsigned int i, j;\n+\tint ret;\n \n-\t/* From performance point of view the buffer size should be a\n-\t * power of 2 but also should be enough to store incompressible data\n-\t */\n+\tenabled_cdev_count = rte_compressdev_devices_get(test_data->driver_name,\n+\t\t\tenabled_cdevs, RTE_COMPRESS_MAX_DEVS);\n+\tif (enabled_cdev_count == 0) {\n+\t\tRTE_LOG(ERR, USER1, \"No compress devices type %s available\\n\",\n+\t\t\t\ttest_data->driver_name);\n+\t\treturn -EINVAL;\n+\t}\n \n-\t/* We're looking for nearest power of 2 buffer size, which is greather\n-\t * than input_size\n+\tnb_lcores = rte_lcore_count() - 1;\n+\t/*\n+\t * Use fewer devices,\n+\t * if there are more available than cores.\n \t */\n-\tuint32_t size =\n-\t\t!input_size ? MIN_COMPRESSED_BUF_SIZE : (input_size << 1);\n-\n-\tfor (i = UINT16_MAX + 1; !(i & size); i >>= 1)\n-\t\t;\n-\n-\treturn i > ((UINT16_MAX + 1) >> 1)\n-\t\t\t? (uint32_t)((float)input_size * EXPANSE_RATIO)\n-\t\t\t: i;\n-}\n-\n-static int\n-comp_perf_allocate_memory(struct comp_test_data *test_data)\n-{\n+\tif (enabled_cdev_count > nb_lcores) {\n+\t\tenabled_cdev_count = nb_lcores;\n+\t\tRTE_LOG(INFO, USER1,\n+\t\t\t\" There's more available devices than cores!\"\n+\t\t\t\" The number of devices has been aligned to %d cores\\n\",\n+\t\t\tnb_lcores);\n+\t}\n \n-\ttest_data->out_seg_sz = find_buf_size(test_data->seg_sz);\n-\t/* Number of segments for input and output\n-\t * (compression and decompression)\n+\t/*\n+\t * Calculate number of needed queue pairs, based on the amount\n+\t * of available number of logical cores and compression devices.\n+\t * For instance, if there are 4 cores and 2 compression devices,\n+\t * 2 queue pairs will be set up per device.\n+\t * One queue pair per one core.\n+\t * if e.g.: there're 3 cores and 2 compression devices,\n+\t * 2 queue pairs will be set up per device but one queue pair\n+\t * will left unused in the last one device\n \t */\n-\tuint32_t total_segs = DIV_CEIL(test_data->input_data_sz,\n-\t\t\ttest_data->seg_sz);\n-\ttest_data->comp_buf_pool = rte_pktmbuf_pool_create(\"comp_buf_pool\",\n-\t\t\t\ttotal_segs,\n-\t\t\t\t0, 0,\n-\t\t\t\ttest_data->out_seg_sz + RTE_PKTMBUF_HEADROOM,\n-\t\t\t\trte_socket_id());\n-\tif (test_data->comp_buf_pool == NULL) {\n-\t\tRTE_LOG(ERR, USER1, \"Mbuf mempool could not be created\\n\");\n-\t\treturn -1;\n-\t}\n+\ttest_data->nb_qps = (nb_lcores % enabled_cdev_count) ?\n+\t\t\t\t(nb_lcores / enabled_cdev_count) + 1 :\n+\t\t\t\tnb_lcores / enabled_cdev_count;\n \n-\tcleanup = ST_MEMORY_ALLOC;\n-\ttest_data->decomp_buf_pool = rte_pktmbuf_pool_create(\"decomp_buf_pool\",\n-\t\t\t\ttotal_segs,\n-\t\t\t\t0, 0, test_data->seg_sz + RTE_PKTMBUF_HEADROOM,\n-\t\t\t\trte_socket_id());\n-\tif (test_data->decomp_buf_pool == NULL) {\n-\t\tRTE_LOG(ERR, USER1, \"Mbuf mempool could not be created\\n\");\n-\t\treturn -1;\n-\t}\n+\tfor (i = 0; i < enabled_cdev_count &&\n+\t\t\ti < RTE_COMPRESS_MAX_DEVS; i++,\n+\t\t\t\t\tnb_lcores -= test_data->nb_qps) {\n+\t\tcdev_id = enabled_cdevs[i];\n \n-\ttest_data->total_bufs = DIV_CEIL(total_segs, test_data->max_sgl_segs);\n+\t\tstruct rte_compressdev_info cdev_info;\n+\t\tuint8_t socket_id = rte_compressdev_socket_id(cdev_id);\n \n-\ttest_data->op_pool = rte_comp_op_pool_create(\"op_pool\",\n-\t\t\t\t  test_data->total_bufs,\n-\t\t\t\t  0, 0, rte_socket_id());\n-\tif (test_data->op_pool == NULL) {\n-\t\tRTE_LOG(ERR, USER1, \"Comp op mempool could not be created\\n\");\n-\t\treturn -1;\n-\t}\n+\t\trte_compressdev_info_get(cdev_id, &cdev_info);\n+\t\tif (cdev_info.max_nb_queue_pairs &&\n+\t\t\ttest_data->nb_qps > cdev_info.max_nb_queue_pairs) {\n+\t\t\tRTE_LOG(ERR, USER1,\n+\t\t\t\t\"Number of needed queue pairs is higher \"\n+\t\t\t\t\"than the maximum number of queue pairs \"\n+\t\t\t\t\"per device.\\n\");\n+\t\t\tRTE_LOG(ERR, USER1,\n+\t\t\t\t\"Lower the number of cores or increase \"\n+\t\t\t\t\"the number of crypto devices\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n \n-\t/*\n-\t * Compressed data might be a bit larger than input data,\n-\t * if data cannot be compressed\n-\t */\n-\ttest_data->compressed_data = rte_zmalloc_socket(NULL,\n-\t\t\t\ttest_data->input_data_sz * EXPANSE_RATIO\n-\t\t\t\t\t\t+ MIN_COMPRESSED_BUF_SIZE, 0,\n-\t\t\t\trte_socket_id());\n-\tif (test_data->compressed_data == NULL) {\n-\t\tRTE_LOG(ERR, USER1, \"Memory to hold the data from the input \"\n-\t\t\t\t\"file could not be allocated\\n\");\n-\t\treturn -1;\n-\t}\n+\t\tif (comp_perf_check_capabilities(test_data, cdev_id) < 0)\n+\t\t\treturn -EINVAL;\n+\n+\t\t/* Configure compressdev */\n+\t\tstruct rte_compressdev_config config = {\n+\t\t\t.socket_id = socket_id,\n+\t\t\t.nb_queue_pairs = nb_lcores > test_data->nb_qps\n+\t\t\t\t\t? test_data->nb_qps : nb_lcores,\n+\t\t\t.max_nb_priv_xforms = NUM_MAX_XFORMS,\n+\t\t\t.max_nb_streams = 0\n+\t\t};\n+\n+\t\tif (rte_compressdev_configure(cdev_id, &config) < 0) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Device configuration failed\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n \n-\ttest_data->decompressed_data = rte_zmalloc_socket(NULL,\n-\t\t\t\ttest_data->input_data_sz, 0,\n-\t\t\t\trte_socket_id());\n-\tif (test_data->decompressed_data == NULL) {\n-\t\tRTE_LOG(ERR, USER1, \"Memory to hold the data from the input \"\n-\t\t\t\t\"file could not be allocated\\n\");\n-\t\treturn -1;\n-\t}\n+\t\tfor (j = 0; j < test_data->nb_qps; j++) {\n+\t\t\tret = rte_compressdev_queue_pair_setup(cdev_id, j,\n+\t\t\t\t\tNUM_MAX_INFLIGHT_OPS, socket_id);\n+\t\t\tif (ret < 0) {\n+\t\t\t\tRTE_LOG(ERR, USER1,\n+\t\t\t      \"Failed to setup queue pair %u on compressdev %u\",\n+\t\t\t\t\tj, cdev_id);\n+\t\t\t\treturn -EINVAL;\n+\t\t\t}\n+\t\t}\n \n-\ttest_data->comp_bufs = rte_zmalloc_socket(NULL,\n-\t\t\ttest_data->total_bufs * sizeof(struct rte_mbuf *),\n-\t\t\t0, rte_socket_id());\n-\tif (test_data->comp_bufs == NULL) {\n-\t\tRTE_LOG(ERR, USER1, \"Memory to hold the compression mbufs\"\n-\t\t\t\t\" could not be allocated\\n\");\n-\t\treturn -1;\n+\t\tret = rte_compressdev_start(cdev_id);\n+\t\tif (ret < 0) {\n+\t\t\tRTE_LOG(ERR, USER1,\n+\t\t\t\t\"Failed to start device %u: error %d\\n\",\n+\t\t\t\tcdev_id, ret);\n+\t\t\treturn -EPERM;\n+\t\t}\n \t}\n \n-\ttest_data->decomp_bufs = rte_zmalloc_socket(NULL,\n-\t\t\ttest_data->total_bufs * sizeof(struct rte_mbuf *),\n-\t\t\t0, rte_socket_id());\n-\tif (test_data->decomp_bufs == NULL) {\n-\t\tRTE_LOG(ERR, USER1, \"Memory to hold the decompression mbufs\"\n-\t\t\t\t\" could not be allocated\\n\");\n-\t\treturn -1;\n-\t}\n-\treturn 0;\n+\treturn enabled_cdev_count;\n }\n \n static int\n@@ -244,7 +230,8 @@ comp_perf_dump_input_data(struct comp_test_data *test_data)\n \tif (test_data->input_data_sz == 0)\n \t\ttest_data->input_data_sz = actual_file_sz;\n \n-\tif (fseek(f, 0, SEEK_SET) != 0) {\n+\tif (test_data->input_data_sz <= 0 || actual_file_sz <= 0 ||\n+\t\t\tfseek(f, 0, SEEK_SET) != 0) {\n \t\tRTE_LOG(ERR, USER1, \"Size of input could not be calculated\\n\");\n \t\tgoto end;\n \t}\n@@ -294,187 +281,18 @@ comp_perf_dump_input_data(struct comp_test_data *test_data)\n \treturn ret;\n }\n \n-static int\n-comp_perf_initialize_compressdev(struct comp_test_data *test_data)\n-{\n-\tuint8_t enabled_cdev_count;\n-\tuint8_t enabled_cdevs[RTE_COMPRESS_MAX_DEVS];\n-\n-\tenabled_cdev_count = rte_compressdev_devices_get(test_data->driver_name,\n-\t\t\tenabled_cdevs, RTE_COMPRESS_MAX_DEVS);\n-\tif (enabled_cdev_count == 0) {\n-\t\tRTE_LOG(ERR, USER1, \"No compress devices type %s available\\n\",\n-\t\t\t\ttest_data->driver_name);\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tif (enabled_cdev_count > 1)\n-\t\tRTE_LOG(INFO, USER1,\n-\t\t\t\"Only the first compress device will be used\\n\");\n-\n-\ttest_data->cdev_id = enabled_cdevs[0];\n-\n-\tif (comp_perf_check_capabilities(test_data) < 0)\n-\t\treturn -1;\n-\n-\t/* Configure compressdev (one device, one queue pair) */\n-\tstruct rte_compressdev_config config = {\n-\t\t.socket_id = rte_socket_id(),\n-\t\t.nb_queue_pairs = 1,\n-\t\t.max_nb_priv_xforms = NUM_MAX_XFORMS,\n-\t\t.max_nb_streams = 0\n-\t};\n-\n-\tif (rte_compressdev_configure(test_data->cdev_id, &config) < 0) {\n-\t\tRTE_LOG(ERR, USER1, \"Device configuration failed\\n\");\n-\t\treturn -1;\n-\t}\n-\n-\tif (rte_compressdev_queue_pair_setup(test_data->cdev_id, 0,\n-\t\t\tNUM_MAX_INFLIGHT_OPS, rte_socket_id()) < 0) {\n-\t\tRTE_LOG(ERR, USER1, \"Queue pair setup failed\\n\");\n-\t\treturn -1;\n-\t}\n-\n-\tif (rte_compressdev_start(test_data->cdev_id) < 0) {\n-\t\tRTE_LOG(ERR, USER1, \"Device could not be started\\n\");\n-\t\treturn -1;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-static int\n-prepare_bufs(struct comp_test_data *test_data)\n-{\n-\tuint32_t remaining_data = test_data->input_data_sz;\n-\tuint8_t *input_data_ptr = test_data->input_data;\n-\tsize_t data_sz;\n-\tuint8_t *data_addr;\n-\tuint32_t i, j;\n-\n-\tfor (i = 0; i < test_data->total_bufs; i++) {\n-\t\t/* Allocate data in input mbuf and copy data from input file */\n-\t\ttest_data->decomp_bufs[i] =\n-\t\t\trte_pktmbuf_alloc(test_data->decomp_buf_pool);\n-\t\tif (test_data->decomp_bufs[i] == NULL) {\n-\t\t\tRTE_LOG(ERR, USER1, \"Could not allocate mbuf\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tcleanup = ST_PREPARE_BUF;\n-\t\tdata_sz = RTE_MIN(remaining_data, test_data->seg_sz);\n-\t\tdata_addr = (uint8_t *) rte_pktmbuf_append(\n-\t\t\t\t\ttest_data->decomp_bufs[i], data_sz);\n-\t\tif (data_addr == NULL) {\n-\t\t\tRTE_LOG(ERR, USER1, \"Could not append data\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\t\trte_memcpy(data_addr, input_data_ptr, data_sz);\n-\n-\t\tinput_data_ptr += data_sz;\n-\t\tremaining_data -= data_sz;\n-\n-\t\t/* Already one segment in the mbuf */\n-\t\tuint16_t segs_per_mbuf = 1;\n-\n-\t\t/* Chain mbufs if needed for input mbufs */\n-\t\twhile (segs_per_mbuf < test_data->max_sgl_segs\n-\t\t\t\t&& remaining_data > 0) {\n-\t\t\tstruct rte_mbuf *next_seg =\n-\t\t\t\trte_pktmbuf_alloc(test_data->decomp_buf_pool);\n-\n-\t\t\tif (next_seg == NULL) {\n-\t\t\t\tRTE_LOG(ERR, USER1,\n-\t\t\t\t\t\"Could not allocate mbuf\\n\");\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\n-\t\t\tdata_sz = RTE_MIN(remaining_data, test_data->seg_sz);\n-\t\t\tdata_addr = (uint8_t *)rte_pktmbuf_append(next_seg,\n-\t\t\t\tdata_sz);\n-\n-\t\t\tif (data_addr == NULL) {\n-\t\t\t\tRTE_LOG(ERR, USER1, \"Could not append data\\n\");\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\n-\t\t\trte_memcpy(data_addr, input_data_ptr, data_sz);\n-\t\t\tinput_data_ptr += data_sz;\n-\t\t\tremaining_data -= data_sz;\n-\n-\t\t\tif (rte_pktmbuf_chain(test_data->decomp_bufs[i],\n-\t\t\t\t\tnext_seg) < 0) {\n-\t\t\t\tRTE_LOG(ERR, USER1, \"Could not chain mbufs\\n\");\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t\tsegs_per_mbuf++;\n-\t\t}\n-\n-\t\t/* Allocate data in output mbuf */\n-\t\ttest_data->comp_bufs[i] =\n-\t\t\trte_pktmbuf_alloc(test_data->comp_buf_pool);\n-\t\tif (test_data->comp_bufs[i] == NULL) {\n-\t\t\tRTE_LOG(ERR, USER1, \"Could not allocate mbuf\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\t\tdata_addr = (uint8_t *) rte_pktmbuf_append(\n-\t\t\t\t\ttest_data->comp_bufs[i],\n-\t\t\t\t\ttest_data->out_seg_sz);\n-\t\tif (data_addr == NULL) {\n-\t\t\tRTE_LOG(ERR, USER1, \"Could not append data\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\t/* Chain mbufs if needed for output mbufs */\n-\t\tfor (j = 1; j < segs_per_mbuf; j++) {\n-\t\t\tstruct rte_mbuf *next_seg =\n-\t\t\t\trte_pktmbuf_alloc(test_data->comp_buf_pool);\n-\n-\t\t\tif (next_seg == NULL) {\n-\t\t\t\tRTE_LOG(ERR, USER1,\n-\t\t\t\t\t\"Could not allocate mbuf\\n\");\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\n-\t\t\tdata_addr = (uint8_t *)rte_pktmbuf_append(next_seg,\n-\t\t\t\ttest_data->out_seg_sz);\n-\n-\t\t\tif (data_addr == NULL) {\n-\t\t\t\tRTE_LOG(ERR, USER1, \"Could not append data\\n\");\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\n-\t\t\tif (rte_pktmbuf_chain(test_data->comp_bufs[i],\n-\t\t\t\t\tnext_seg) < 0) {\n-\t\t\t\tRTE_LOG(ERR, USER1, \"Could not chain mbufs\\n\");\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t}\n-\t}\n-\n-\treturn 0;\n-}\n-\n-static void\n-free_bufs(struct comp_test_data *test_data)\n-{\n-\tuint32_t i;\n-\n-\tfor (i = 0; i < test_data->total_bufs; i++) {\n-\t\trte_pktmbuf_free(test_data->comp_bufs[i]);\n-\t\trte_pktmbuf_free(test_data->decomp_bufs[i]);\n-\t}\n-}\n-\n-\n-\n int\n main(int argc, char **argv)\n {\n-\tuint8_t level, level_idx = 0;\n+\tuint8_t level_idx = 0;\n \tint ret, i;\n \tstruct comp_test_data *test_data;\n+\tvoid *ctx[RTE_MAX_LCORE] = {};\n+\tuint8_t enabled_cdevs[RTE_COMPRESS_MAX_DEVS];\n+\tint nb_compressdevs = 0;\n+\tuint16_t total_nb_qps = 0;\n+\tuint8_t cdev_id;\n+\tuint32_t lcore_id;\n \n \t/* Initialise DPDK EAL */\n \tret = rte_eal_init(argc, argv);\n@@ -491,7 +309,7 @@ main(int argc, char **argv)\n \t\t\t\trte_socket_id());\n \n \tret = EXIT_SUCCESS;\n-\tcleanup = ST_TEST_DATA;\n+\ttest_data->cleanup = ST_TEST_DATA;\n \tcomp_perf_options_default(test_data);\n \n \tif (comp_perf_options_parse(test_data, argc, argv) < 0) {\n@@ -506,96 +324,111 @@ main(int argc, char **argv)\n \t\tgoto end;\n \t}\n \n-\tif (comp_perf_initialize_compressdev(test_data) < 0) {\n-\t\tret = EXIT_FAILURE;\n-\t\tgoto end;\n-\t}\n+\tnb_compressdevs =\n+\t\tcomp_perf_initialize_compressdev(test_data, enabled_cdevs);\n \n-\tcleanup = ST_COMPDEV;\n-\tif (comp_perf_dump_input_data(test_data) < 0) {\n+\tif (nb_compressdevs < 1) {\n \t\tret = EXIT_FAILURE;\n \t\tgoto end;\n \t}\n \n-\tcleanup = ST_INPUT_DATA;\n-\tif (comp_perf_allocate_memory(test_data) < 0) {\n+\ttest_data->cleanup = ST_COMPDEV;\n+\tif (comp_perf_dump_input_data(test_data) < 0) {\n \t\tret = EXIT_FAILURE;\n \t\tgoto end;\n \t}\n \n-\tif (prepare_bufs(test_data) < 0) {\n-\t\tret = EXIT_FAILURE;\n-\t\tgoto end;\n-\t}\n+\ttest_data->cleanup = ST_INPUT_DATA;\n \n-\tif (test_data->level.inc != 0)\n-\t\tlevel = test_data->level.min;\n+\tif (test_data->level_lst.inc != 0)\n+\t\ttest_data->level = test_data->level_lst.min;\n \telse\n-\t\tlevel = test_data->level.list[0];\n+\t\ttest_data->level = test_data->level_lst.list[0];\n \n \tprintf(\"Burst size = %u\\n\", test_data->burst_sz);\n \tprintf(\"File size = %zu\\n\", test_data->input_data_sz);\n \n-\tprintf(\"%6s%12s%17s%19s%21s%15s%21s%23s%16s\\n\",\n-\t\t\"Level\", \"Comp size\", \"Comp ratio [%]\",\n-\t\t\"Comp [Cycles/it]\", \"Comp [Cycles/Byte]\", \"Comp [Gbps]\",\n-\t\t\"Decomp [Cycles/it]\", \"Decomp [Cycles/Byte]\", \"Decomp [Gbps]\");\n+\ttest_data->cleanup = ST_DURING_TEST;\n+\ttotal_nb_qps = nb_compressdevs * test_data->nb_qps;\n \n-\tcleanup = ST_DURING_TEST;\n-\twhile (level <= test_data->level.max) {\n+\ti = 0;\n+\tuint8_t qp_id = 0, cdev_index = 0;\n \n-\t\t/*\n-\t\t * Run a first iteration, to verify compression and\n-\t\t * get the compression ratio for the level\n-\t\t */\n-\t\tif (cperf_verification(test_data, level) != EXIT_SUCCESS)\n-\t\t\tbreak;\n+\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n \n-\t\t/*\n-\t\t * Run benchmarking test\n-\t\t */\n-\t\tif (cperf_benchmark(test_data, level) != EXIT_SUCCESS)\n+\t\tif (i == total_nb_qps)\n \t\t\tbreak;\n \n-\t\tprintf(\"%6u%12zu%17.2f%19\"PRIu64\"%21.2f\"\n-\t\t\t\t\t\"%15.2f%21\"PRIu64\"%23.2f%16.2f\\n\",\n-\t\t       level, test_data->comp_data_sz, test_data->ratio,\n-\t\t       test_data->comp_tsc_duration[level],\n-\t\t       test_data->comp_tsc_byte, test_data->comp_gbps,\n-\t\t       test_data->decomp_tsc_duration[level],\n-\t\t       test_data->decomp_tsc_byte, test_data->decomp_gbps);\n+\t\tcdev_id = enabled_cdevs[cdev_index];\n+\t\tctx[i] = cperf_testmap[test_data->test].constructor(\n+\t\t\t\t\t\t\tcdev_id, qp_id,\n+\t\t\t\t\t\t\ttest_data);\n+\t\tif (ctx[i] == NULL) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Test run constructor failed\\n\");\n+\t\t\tgoto end;\n+\t\t}\n+\t\tqp_id = (qp_id + 1) % test_data->nb_qps;\n+\t\tif (qp_id == 0)\n+\t\t\tcdev_index++;\n+\t\ti++;\n+\t}\n+\n+\twhile (test_data->level <= test_data->level_lst.max) {\n+\n+\t\ti = 0;\n+\t\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n+\n+\t\t\tif (i == total_nb_qps)\n+\t\t\t\tbreak;\n \n-\t\tif (test_data->level.inc != 0)\n-\t\t\tlevel += test_data->level.inc;\n+\t\t\trte_eal_remote_launch(\n+\t\t\t\t\tcperf_testmap[test_data->test].runner,\n+\t\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 == total_nb_qps)\n+\t\t\t\tbreak;\n+\t\t\tret |= rte_eal_wait_lcore(lcore_id);\n+\t\t\ti++;\n+\t\t}\n+\n+\t\tif (ret != EXIT_SUCCESS)\n+\t\t\tbreak;\n+\n+\t\tif (test_data->level_lst.inc != 0)\n+\t\t\ttest_data->level += test_data->level_lst.inc;\n \t\telse {\n-\t\t\tif (++level_idx == test_data->level.count)\n+\t\t\tif (++level_idx == test_data->level_lst.count)\n \t\t\t\tbreak;\n-\t\t\tlevel = test_data->level.list[level_idx];\n+\t\t\ttest_data->level = test_data->level_lst.list[level_idx];\n \t\t}\n \t}\n \n end:\n-\tswitch (cleanup) {\n+\tswitch (test_data->cleanup) {\n \n \tcase ST_DURING_TEST:\n-\tcase ST_PREPARE_BUF:\n-\t\tfree_bufs(test_data);\n-\t\t/* fallthrough */\n-\tcase ST_MEMORY_ALLOC:\n-\t\trte_free(test_data->decomp_bufs);\n-\t\trte_free(test_data->comp_bufs);\n-\t\trte_free(test_data->decompressed_data);\n-\t\trte_free(test_data->compressed_data);\n-\t\trte_mempool_free(test_data->op_pool);\n-\t\trte_mempool_free(test_data->decomp_buf_pool);\n-\t\trte_mempool_free(test_data->comp_buf_pool);\n+\t\ti = 0;\n+\t\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n+\t\t\tif (i == total_nb_qps)\n+\t\t\t\tbreak;\n+\n+\t\t\tif (ctx[i] && cperf_testmap[test_data->test].destructor)\n+\t\t\t\tcperf_testmap[test_data->test].destructor(\n+\t\t\t\t\t\t\t\t\tctx[i]);\n+\t\t\ti++;\n+\t\t}\n \t\t/* fallthrough */\n \tcase ST_INPUT_DATA:\n \t\trte_free(test_data->input_data);\n \t\t/* fallthrough */\n \tcase ST_COMPDEV:\n-\t\tif (test_data->cdev_id != -1)\n-\t\t\trte_compressdev_stop(test_data->cdev_id);\n+\t\tfor (i = 0; i < nb_compressdevs &&\n+\t\t\t\ti < RTE_COMPRESS_MAX_DEVS; i++)\n+\t\t\trte_compressdev_stop(enabled_cdevs[i]);\n \t\t/* fallthrough */\n \tcase ST_TEST_DATA:\n \t\trte_free(test_data);\n@@ -612,3 +445,65 @@ main(int argc, char **argv)\n \t}\n \treturn ret;\n }\n+\n+__rte_weak void *\n+cperf_benchmark_test_constructor(uint8_t dev_id __rte_unused,\n+\t\t\t\t uint16_t qp_id __rte_unused,\n+\t\t\t\t struct comp_test_data *options __rte_unused)\n+{\n+\tRTE_LOG(INFO, USER1, \"Benchmark test is not supported yet\\n\");\n+\treturn NULL;\n+}\n+\n+__rte_weak void\n+cperf_benchmark_test_destructor(void *arg __rte_unused)\n+{\n+\n+}\n+\n+__rte_weak int\n+cperf_benchmark_test_runner(void *test_ctx __rte_unused)\n+{\n+\treturn 0;\n+}\n+__rte_weak void *\n+cperf_verify_test_constructor(uint8_t dev_id __rte_unused,\n+\t\t\t\t uint16_t qp_id __rte_unused,\n+\t\t\t\t struct comp_test_data *options __rte_unused)\n+{\n+\tRTE_LOG(INFO, USER1, \"Verify test is not supported yet\\n\");\n+\treturn NULL;\n+}\n+\n+__rte_weak void\n+cperf_verify_test_destructor(void *arg __rte_unused)\n+{\n+\n+}\n+\n+__rte_weak int\n+cperf_verify_test_runner(void *test_ctx __rte_unused)\n+{\n+\treturn 0;\n+}\n+\n+__rte_weak void *\n+cperf_pmd_cyclecount_test_constructor(uint8_t dev_id __rte_unused,\n+\t\t\t\t uint16_t qp_id __rte_unused,\n+\t\t\t\t struct comp_test_data *options __rte_unused)\n+{\n+\tRTE_LOG(INFO, USER1, \"Pmd_cyclecount test is not supported yet\\n\");\n+\treturn NULL;\n+}\n+\n+__rte_weak void\n+cperf_pmd_cyclecount_test_destructor(void *arg __rte_unused)\n+{\n+\n+}\n+\n+__rte_weak int\n+cperf_pmd_cyclecount_test_runner(void *test_ctx __rte_unused)\n+{\n+\treturn 0;\n+}\ndiff --git a/app/test-compress-perf/meson.build b/app/test-compress-perf/meson.build\nindex ec73e5e..00413c6 100644\n--- a/app/test-compress-perf/meson.build\n+++ b/app/test-compress-perf/meson.build\n@@ -4,6 +4,5 @@\n allow_experimental_apis = true\n sources = files('comp_perf_options_parse.c',\n \t\t'main.c',\n-\t\t'comp_perf_test_verify.c',\n-\t\t'comp_perf_test_benchmark.c')\n+\t\t'comp_perf_test_common.c')\n deps = ['compressdev']\n",
    "prefixes": [
        "v2",
        "1/7"
    ]
}