get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 100986,
    "url": "http://patchwork.dpdk.org/api/patches/100986/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20211011075541.1182775-6-wojciechx.liguzinski@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20211011075541.1182775-6-wojciechx.liguzinski@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20211011075541.1182775-6-wojciechx.liguzinski@intel.com",
    "date": "2021-10-11T07:55:41",
    "name": "[v9,5/5] app/test: add tests for PIE",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "642a210488bfbb93751eeb0e428a75e2aceaa9fd",
    "submitter": {
        "id": 2195,
        "url": "http://patchwork.dpdk.org/api/people/2195/?format=api",
        "name": "Liguzinski, WojciechX",
        "email": "wojciechx.liguzinski@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20211011075541.1182775-6-wojciechx.liguzinski@intel.com/mbox/",
    "series": [
        {
            "id": 19501,
            "url": "http://patchwork.dpdk.org/api/series/19501/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=19501",
            "date": "2021-10-11T07:55:36",
            "name": "Add PIE support for HQoS library",
            "version": 9,
            "mbox": "http://patchwork.dpdk.org/series/19501/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/100986/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/100986/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 mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 596E6A034F;\n\tMon, 11 Oct 2021 09:56:31 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id A622241125;\n\tMon, 11 Oct 2021 09:56:06 +0200 (CEST)",
            "from mga17.intel.com (mga17.intel.com [192.55.52.151])\n by mails.dpdk.org (Postfix) with ESMTP id ABCDC410EF\n for <dev@dpdk.org>; Mon, 11 Oct 2021 09:56:02 +0200 (CEST)",
            "from orsmga003.jf.intel.com ([10.7.209.27])\n by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 11 Oct 2021 00:56:01 -0700",
            "from silpixa00400629.ir.intel.com ([10.237.213.30])\n by orsmga003.jf.intel.com with ESMTP; 11 Oct 2021 00:55:59 -0700"
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6200,9189,10133\"; a=\"207626901\"",
            "E=Sophos;i=\"5.85,364,1624345200\"; d=\"scan'208\";a=\"207626901\"",
            "E=Sophos;i=\"5.85,364,1624345200\"; d=\"scan'208\";a=\"441341377\""
        ],
        "X-ExtLoop1": "1",
        "From": "\"Liguzinski, WojciechX\" <wojciechx.liguzinski@intel.com>",
        "To": "dev@dpdk.org,\n\tjasvinder.singh@intel.com,\n\tcristian.dumitrescu@intel.com",
        "Cc": "megha.ajmera@intel.com",
        "Date": "Mon, 11 Oct 2021 07:55:41 +0000",
        "Message-Id": "<20211011075541.1182775-6-wojciechx.liguzinski@intel.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20211011075541.1182775-1-wojciechx.liguzinski@intel.com>",
        "References": "<20210923094533.939757-1-wojciechx.liguzinski@intel.com>\n <20211011075541.1182775-1-wojciechx.liguzinski@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v9 5/5] app/test: add tests for PIE",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "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": "Tests for PIE code added to test application.\n\nSigned-off-by: Liguzinski, WojciechX <wojciechx.liguzinski@intel.com>\n---\n app/test/autotest_data.py |   18 +\n app/test/meson.build      |    4 +\n app/test/test_pie.c       | 1065 +++++++++++++++++++++++++++++++++++++\n lib/sched/rte_pie.c       |    6 +-\n lib/sched/rte_pie.h       |   17 +-\n lib/sched/rte_sched.c     |    2 +-\n 6 files changed, 1104 insertions(+), 8 deletions(-)\n create mode 100644 app/test/test_pie.c",
    "diff": "diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py\nindex 302d6374c1..1d4418b6a3 100644\n--- a/app/test/autotest_data.py\n+++ b/app/test/autotest_data.py\n@@ -279,6 +279,12 @@\n         \"Func\":    default_autotest,\n         \"Report\":  None,\n     },\n+    {\n+        \"Name\":    \"Pie autotest\",\n+        \"Command\": \"pie_autotest\",\n+        \"Func\":    default_autotest,\n+        \"Report\":  None,\n+    },\n     {\n         \"Name\":    \"PMD ring autotest\",\n         \"Command\": \"ring_pmd_autotest\",\n@@ -525,6 +531,12 @@\n         \"Func\":    default_autotest,\n         \"Report\":  None,\n     },\n+    {\n+        \"Name\":    \"Pie all\",\n+        \"Command\": \"red_all\",\n+        \"Func\":    default_autotest,\n+        \"Report\":  None,\n+    },\n     {\n \t\"Name\":    \"Fbarray autotest\",\n \t\"Command\": \"fbarray_autotest\",\n@@ -731,6 +743,12 @@\n         \"Func\":    default_autotest,\n         \"Report\":  None,\n     },\n+    {\n+        \"Name\":    \"Pie_perf\",\n+        \"Command\": \"pie_perf\",\n+        \"Func\":    default_autotest,\n+        \"Report\":  None,\n+    },\n     {\n         \"Name\":    \"Lpm6 perf autotest\",\n         \"Command\": \"lpm6_perf_autotest\",\ndiff --git a/app/test/meson.build b/app/test/meson.build\nindex a7611686ad..f224b0c17e 100644\n--- a/app/test/meson.build\n+++ b/app/test/meson.build\n@@ -111,6 +111,7 @@ test_sources = files(\n         'test_reciprocal_division.c',\n         'test_reciprocal_division_perf.c',\n         'test_red.c',\n+        'test_pie.c',\n         'test_reorder.c',\n         'test_rib.c',\n         'test_rib6.c',\n@@ -241,6 +242,7 @@ fast_tests = [\n         ['prefetch_autotest', true],\n         ['rcu_qsbr_autotest', true],\n         ['red_autotest', true],\n+        ['pie_autotest', true],\n         ['rib_autotest', true],\n         ['rib6_autotest', true],\n         ['ring_autotest', true],\n@@ -292,6 +294,7 @@ perf_test_names = [\n         'fib_slow_autotest',\n         'fib_perf_autotest',\n         'red_all',\n+        'pie_all',\n         'barrier_autotest',\n         'hash_multiwriter_autotest',\n         'timer_racecond_autotest',\n@@ -305,6 +308,7 @@ perf_test_names = [\n         'fib6_perf_autotest',\n         'rcu_qsbr_perf_autotest',\n         'red_perf',\n+        'pie_perf',\n         'distributor_perf_autotest',\n         'pmd_perf_autotest',\n         'stack_perf_autotest',\ndiff --git a/app/test/test_pie.c b/app/test/test_pie.c\nnew file mode 100644\nindex 0000000000..dfa69d1c7e\n--- /dev/null\n+++ b/app/test/test_pie.c\n@@ -0,0 +1,1065 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2014 Intel Corporation\n+ */\n+\n+#include <stdlib.h>\n+#include <stdio.h>\n+#include <string.h>\n+#include <stdint.h>\n+#include <unistd.h>\n+#include <inttypes.h>\n+#include <sys/time.h>\n+#include <time.h>\n+#include <math.h>\n+\n+#include \"test.h\"\n+\n+#include <rte_pie.h>\n+\n+#ifdef __INTEL_COMPILER\n+#pragma warning(disable:2259)       /* conversion may lose significant bits */\n+#pragma warning(disable:181)        /* Arg incompatible with format string */\n+#endif\n+\n+/**< structures for testing rte_pie performance and function */\n+struct test_rte_pie_config {        /**< Test structure for RTE_PIE config */\n+\tstruct rte_pie_config *pconfig; /**< RTE_PIE configuration parameters */\n+\tuint8_t num_cfg;                /**< Number of RTE_PIE configs to test */\n+\tuint16_t qdelay_ref;            /**< Latency Target (milliseconds) */\n+\tuint16_t *dp_update_interval;   /**< Update interval for drop probability\n+\t\t\t\t\t  * (milliseconds)\n+\t\t\t\t\t  */\n+\tuint16_t *max_burst;            /**< Max Burst Allowance (milliseconds) */\n+\tuint16_t tailq_th;              /**< Tailq drop threshold (packet counts) */\n+};\n+\n+struct test_queue {                 /**< Test structure for RTE_PIE Queues */\n+\tstruct rte_pie *pdata_in;       /**< RTE_PIE runtime data input */\n+\tstruct rte_pie *pdata_out;\t\t/**< RTE_PIE runtime data output*/\n+\tuint32_t num_queues;            /**< Number of RTE_PIE queues to test */\n+\tuint32_t *qlen;                 /**< Queue size */\n+\tuint32_t q_ramp_up;             /**< Num of enqueues to ramp up the queue */\n+\tdouble drop_tolerance;          /**< Drop tolerance of packets not enqueued */\n+};\n+\n+struct test_var {                   /**< Test variables used for testing RTE_PIE */\n+\tuint32_t num_iterations;        /**< Number of test iterations */\n+\tuint32_t num_ops;               /**< Number of test operations */\n+\tuint64_t clk_freq;              /**< CPU clock frequency */\n+\tuint32_t *dropped;              /**< Test operations dropped */\n+\tuint32_t *enqueued;             /**< Test operations enqueued */\n+\tuint32_t *dequeued;             /**< Test operations dequeued */\n+};\n+\n+struct test_config {                /**< Primary test structure for RTE_PIE */\n+\tconst char *ifname;             /**< Interface name */\n+\tconst char *msg;                /**< Test message for display */\n+\tconst char *htxt;               /**< Header txt display for result output */\n+\tstruct test_rte_pie_config *tconfig; /**< Test structure for RTE_PIE config */\n+\tstruct test_queue *tqueue;      /**< Test structure for RTE_PIE Queues */\n+\tstruct test_var *tvar;          /**< Test variables used for testing RTE_PIE */\n+\tuint32_t *tlevel;               /**< Queue levels */\n+};\n+\n+enum test_result {\n+\tFAIL = 0,\n+\tPASS\n+};\n+\n+/**< Test structure to define tests to run */\n+struct tests {\n+\tstruct test_config *testcfg;\n+\tenum test_result (*testfn)(struct test_config *cfg);\n+};\n+\n+struct rdtsc_prof {\n+\tuint64_t clk_start;\n+\tuint64_t clk_min;               /**< min clocks */\n+\tuint64_t clk_max;               /**< max clocks */\n+\tuint64_t clk_avgc;              /**< count to calc average */\n+\tdouble clk_avg;                 /**< cumulative sum to calc average */\n+\tconst char *name;\n+};\n+\n+static const uint64_t port_speed_bytes = (10ULL*1000ULL*1000ULL*1000ULL)/8ULL;\n+static double inv_cycles_per_byte;\n+\n+static void init_port_ts(uint64_t cpu_clock)\n+{\n+\tdouble cycles_per_byte = (double)(cpu_clock) / (double)(port_speed_bytes);\n+\tinv_cycles_per_byte = 1.0 / cycles_per_byte;\n+}\n+\n+static uint64_t get_port_ts(void)\n+{\n+\treturn (uint64_t)((double)rte_rdtsc() * inv_cycles_per_byte);\n+}\n+\n+static void rdtsc_prof_init(struct rdtsc_prof *p, const char *name)\n+{\n+\tp->clk_min = (uint64_t)(-1LL);\n+\tp->clk_max = 0;\n+\tp->clk_avg = 0;\n+\tp->clk_avgc = 0;\n+\tp->name = name;\n+}\n+\n+static inline void rdtsc_prof_start(struct rdtsc_prof *p)\n+{\n+\tp->clk_start = rte_rdtsc_precise();\n+}\n+\n+static inline void rdtsc_prof_end(struct rdtsc_prof *p)\n+{\n+\tuint64_t clk_start = rte_rdtsc() - p->clk_start;\n+\n+\tp->clk_avgc++;\n+\tp->clk_avg += (double) clk_start;\n+\n+\tif (clk_start > p->clk_max)\n+\t\tp->clk_max = clk_start;\n+\tif (clk_start < p->clk_min)\n+\t\tp->clk_min = clk_start;\n+}\n+\n+static void rdtsc_prof_print(struct rdtsc_prof *p)\n+{\n+\tif (p->clk_avgc > 0) {\n+\t\tprintf(\"RDTSC stats for %s: n=%\" PRIu64 \", min=%\" PRIu64\n+\t\t\t\t\t\t\",max=%\" PRIu64 \", avg=%.1f\\n\",\n+\t\t\tp->name,\n+\t\t\tp->clk_avgc,\n+\t\t\tp->clk_min,\n+\t\t\tp->clk_max,\n+\t\t\t(p->clk_avg / ((double) p->clk_avgc)));\n+\t}\n+}\n+\n+static uint16_t rte_pie_get_active(const struct rte_pie_config *pie_cfg,\n+\t\t\t\t    struct rte_pie *pie)\n+{\n+    /**< Flag for activating/deactivating pie */\n+\tRTE_SET_USED(pie_cfg);\n+\treturn pie->active;\n+}\n+\n+static void rte_pie_set_active(const struct rte_pie_config *pie_cfg,\n+\t\t\t\t\tstruct rte_pie *pie,\n+\t\t\t\t\tuint16_t active)\n+{\n+    /**< Flag for activating/deactivating pie */\n+\tRTE_SET_USED(pie_cfg);\n+\tpie->active = active;\n+}\n+\n+/**\n+ * Read the drop probability\n+ */\n+static double rte_pie_get_drop_prob(const struct rte_pie_config *pie_cfg,\n+\t\t\t\t    struct rte_pie *pie)\n+{\n+    /**< Current packet drop probability */\n+\tRTE_SET_USED(pie_cfg);\n+\treturn pie->drop_prob;\n+}\n+\n+static double rte_pie_get_avg_dq_time(const struct rte_pie_config *pie_cfg,\n+\t\t\t\t    struct rte_pie *pie)\n+{\n+    /**< Current packet drop probability */\n+\tRTE_SET_USED(pie_cfg);\n+\treturn pie->avg_dq_time;\n+}\n+\n+static double calc_drop_rate(uint32_t enqueued, uint32_t dropped)\n+{\n+\treturn (double)dropped / ((double)enqueued + (double)dropped);\n+}\n+\n+/**\n+ *  check if drop rate matches drop probability within tolerance\n+ */\n+static int check_drop_rate(double *diff, double drop_rate, double drop_prob,\n+\t\t\t\t\t\t\tdouble tolerance)\n+{\n+\tdouble abs_diff = 0.0;\n+\tint ret = 1;\n+\n+\tabs_diff = fabs(drop_rate - drop_prob);\n+\tif ((int)abs_diff == 0) {\n+\t\t*diff = 0.0;\n+\t} else {\n+\t\t*diff = (abs_diff / drop_prob) * 100.0;\n+\t\tif (*diff > tolerance)\n+\t\t\tret = 0;\n+\t}\n+\treturn ret;\n+}\n+\n+/**\n+ * initialize the test rte_pie config\n+ */\n+static enum test_result\n+test_rte_pie_init(struct test_config *tcfg)\n+{\n+\tunsigned int i = 0;\n+\n+\ttcfg->tvar->clk_freq = rte_get_timer_hz();\n+\tinit_port_ts(tcfg->tvar->clk_freq);\n+\n+\tfor (i = 0; i < tcfg->tconfig->num_cfg; i++) {\n+\t\tif (rte_pie_config_init(&tcfg->tconfig->pconfig[i],\n+\t\t\t\t\t(uint16_t)tcfg->tconfig->qdelay_ref,\n+\t\t\t\t\t(uint16_t)tcfg->tconfig->dp_update_interval[i],\n+\t\t\t\t\t(uint16_t)tcfg->tconfig->max_burst[i],\n+\t\t\t\t\t(uint16_t)tcfg->tconfig->tailq_th) != 0) {\n+\t\t\treturn FAIL;\n+\t\t}\n+\t}\n+\n+\t*tcfg->tqueue->qlen = 0;\n+\t*tcfg->tvar->dropped = 0;\n+\t*tcfg->tvar->enqueued = 0;\n+\n+\treturn PASS;\n+}\n+\n+/**\n+ * enqueue until actual queue size reaches target level\n+ */\n+static int\n+increase_qsize(struct rte_pie_config *pie_cfg,\n+\t\t\t\tstruct rte_pie *pie,\n+\t\t\t\tuint32_t *qlen,\n+\t\t\t\tuint32_t pkt_len,\n+\t\t\t\tuint32_t attempts)\n+{\n+\tuint32_t i = 0;\n+\n+\t\tfor (i = 0; i < attempts; i++) {\n+\t\t\tint ret = 0;\n+\n+\t\t\t/**\n+\t\t\t * enqueue\n+\t\t\t */\n+\t\t\tret = rte_pie_enqueue(pie_cfg, pie, *qlen, pkt_len, get_port_ts());\n+\t\t\t/**\n+\t\t\t * check if target actual queue size has been reached\n+\t\t\t */\n+\t\t\tif (ret == 0)\n+\t\t\t\treturn 0;\n+\t\t}\n+\t\t/**\n+\t\t * no success\n+\t\t */\n+\t\treturn -1;\n+}\n+\n+/**\n+ * functional test enqueue/dequeue packets\n+ */\n+static void\n+enqueue_dequeue_func(struct rte_pie_config *pie_cfg,\n+\t\t\t\t\tstruct rte_pie *pie,\n+\t\t\t\t\tuint32_t *qlen,\n+\t\t\t\t\tuint32_t num_ops,\n+\t\t\t\t\tuint32_t *enqueued,\n+\t\t\t\t\tuint32_t *dropped)\n+{\n+\tuint32_t i = 0;\n+\n+\tfor (i = 0; i < num_ops; i++) {\n+\t\tint ret = 0;\n+\n+\t\t/**\n+\t\t * enqueue\n+\t\t */\n+\t\tret = rte_pie_enqueue(pie_cfg, pie, *qlen, sizeof(uint32_t),\n+\t\t\t\t\t\t\tget_port_ts());\n+\t\tif (ret == 0)\n+\t\t\t(*enqueued)++;\n+\t\telse\n+\t\t\t(*dropped)++;\n+\t}\n+}\n+\n+/**\n+ * setup default values for the Functional test structures\n+ */\n+static struct rte_pie_config ft_wpconfig[1];\n+static struct rte_pie ft_rtdata[1];\n+static uint32_t  ft_q[] = {0};\n+static uint32_t  ft_dropped[] = {0};\n+static uint32_t  ft_enqueued[] = {0};\n+static uint16_t ft_max_burst[] = {64};\n+static uint16_t ft_dp_update_interval[] = {150};\n+\n+static struct test_rte_pie_config ft_tconfig =  {\n+\t.pconfig = ft_wpconfig,\n+\t.num_cfg = RTE_DIM(ft_wpconfig),\n+\t.qdelay_ref = 15,\n+\t.dp_update_interval = ft_dp_update_interval,\n+\t.max_burst = ft_max_burst,\n+\t.tailq_th = 15,\n+};\n+\n+static struct test_queue ft_tqueue = {\n+\t.pdata_in = ft_rtdata,\n+\t.num_queues = RTE_DIM(ft_rtdata),\n+\t.qlen = ft_q,\n+\t.q_ramp_up = 10,\n+\t.drop_tolerance = 0,\n+};\n+\n+static struct test_var ft_tvar = {\n+\t.num_iterations = 0,\n+\t.num_ops = 10000,\n+\t.clk_freq = 0,\n+\t.dropped = ft_dropped,\n+\t.enqueued = ft_enqueued,\n+};\n+\n+/**\n+ * Test F1: functional test 1\n+ */\n+static uint32_t ft_tlevels[] =  {6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66,\n+\t\t\t\t72, 78, 84, 90, 96, 102, 108, 114, 120, 126, 132, 138, 144};\n+\n+static struct test_config func_test_config1 = {\n+\t.ifname = \"functional test interface\",\n+\t.msg = \"functional test : use one pie configuration\\n\\n\",\n+\t.htxt = \"                \"\n+\t\"drop probability \"\n+\t\"enqueued    \"\n+\t\"dropped     \"\n+\t\"drop prob % \"\n+\t\"drop rate % \"\n+\t\"diff %      \"\n+\t\"tolerance % \"\n+\t\"active  \"\n+\t\"\\n\",\n+\t.tconfig = &ft_tconfig,\n+\t.tqueue = &ft_tqueue,\n+\t.tvar = &ft_tvar,\n+\t.tlevel = ft_tlevels,\n+};\n+\n+static enum test_result func_test1(struct test_config *tcfg)\n+{\n+\tenum test_result result = PASS;\n+\tuint32_t i = 0;\n+\n+\tprintf(\"%s\", tcfg->msg);\n+\n+\tif (test_rte_pie_init(tcfg) != PASS) {\n+\t\tresult = FAIL;\n+\t\tgoto out;\n+\t}\n+\n+\tprintf(\"%s\", tcfg->htxt);\n+\n+\t/**\n+\t * reset rte_pie run-time data\n+\t */\n+\trte_pie_rt_data_init(tcfg->tqueue->pdata_in);\n+\trte_pie_set_active(NULL, tcfg->tqueue->pdata_in, 1);\n+\t*tcfg->tvar->enqueued = 0;\n+\t*tcfg->tvar->dropped = 0;\n+\n+\tif (increase_qsize(&tcfg->tconfig->pconfig[i],\n+\t\t\t\ttcfg->tqueue->pdata_in,\n+\t\t\t\ttcfg->tqueue->qlen,\n+\t\t\t\ttcfg->tlevel[i],\n+\t\t\t\ttcfg->tqueue->q_ramp_up) != 0) {\n+\t\tfprintf(stderr, \"Fail: increase qsize\\n\");\n+\t\tresult = FAIL;\n+\t\tgoto out;\n+\t}\n+\n+\tfor (i = 0; i < RTE_DIM(ft_tlevels); i++) {\n+\t\tconst char *label = NULL;\n+\t\tuint16_t prob = 0;\n+\t\tuint16_t active = 0;\n+\t\tdouble drop_rate = 1.0;\n+\t\tdouble drop_prob = 0.0;\n+\t\tdouble diff = 0.0;\n+\n+\t\tenqueue_dequeue_func(&tcfg->tconfig->pconfig[i],\n+\t\t\t\t     tcfg->tqueue->pdata_in,\n+\t\t\t\t     tcfg->tqueue->qlen,\n+\t\t\t\t     tcfg->tvar->num_ops,\n+\t\t\t\t     tcfg->tvar->enqueued,\n+\t\t\t\t     tcfg->tvar->dropped);\n+\n+\t\tdrop_rate = calc_drop_rate(*tcfg->tvar->enqueued,\n+\t\t\t\t\t\t\t*tcfg->tvar->dropped);\n+\t\tdrop_prob = rte_pie_get_drop_prob(NULL, tcfg->tqueue->pdata_in);\n+\n+\t\tif (drop_prob != 0) {\n+\t\t\tfprintf(stderr, \"Fail: check drop prob\\n\");\n+\t\t\tresult = FAIL;\n+\t\t}\n+\n+\t\tif (drop_rate != 0) {\n+\t\t\tfprintf(stderr, \"Fail: check drop rate\\n\");\n+\t\t\tresult = FAIL;\n+\t\t}\n+\n+\t\tlabel = \"Summary           \";\n+\t\tactive = rte_pie_get_active(NULL, tcfg->tqueue->pdata_in);\n+\t\tprintf(\"%s%-16u%-12u%-12u%-12.4lf%-12.4lf%-12.4lf%-12.4lf%-8i\\n\",\n+\t\t\t\tlabel, prob, *tcfg->tvar->enqueued, *tcfg->tvar->dropped,\n+\t\t\t\tdrop_prob * 100.0, drop_rate * 100.0, diff,\n+\t\t\t\t(double)tcfg->tqueue->drop_tolerance, active);\n+\t}\n+out:\n+\treturn result;\n+}\n+\n+/**\n+ * Test F2: functional test 2\n+ */\n+static uint32_t ft2_tlevel[] = {127};\n+static uint16_t ft2_max_burst[] = {1, 2, 8, 16, 32, 64, 128, 256, 512, 1024};\n+static uint16_t ft2_dp_update_interval[] = {\n+\t\t\t\t10, 20, 50, 150, 300, 600, 900, 1200, 1500, 3000};\n+static struct rte_pie_config ft2_pconfig[10];\n+\n+static struct test_rte_pie_config ft2_tconfig =  {\n+\t.pconfig = ft2_pconfig,\n+\t.num_cfg = RTE_DIM(ft2_pconfig),\n+\t.qdelay_ref = 15,\n+\t.dp_update_interval = ft2_dp_update_interval,\n+\t.max_burst = ft2_max_burst,\n+\t.tailq_th = 15,\n+};\n+\n+static struct test_config func_test_config2 = {\n+\t.ifname = \"functional test 2 interface\",\n+\t.msg = \"functional test 2 : use several PIE configurations,\\n\"\n+\t\"\t\t    compare drop rate to drop probability\\n\\n\",\n+\t.htxt = \"PIE config     \"\n+\t\"avg queue size \"\n+\t\"enqueued       \"\n+\t\"dropped        \"\n+\t\"drop prob %    \"\n+\t\"drop rate %    \"\n+\t\"diff %         \"\n+\t\"tolerance %    \"\n+\t\"\\n\",\n+\t.tconfig = &ft2_tconfig,\n+\t.tqueue = &ft_tqueue,\n+\t.tvar = &ft_tvar,\n+\t.tlevel = ft2_tlevel,\n+};\n+\n+static enum test_result func_test2(struct test_config *tcfg)\n+{\n+\tenum test_result result = PASS;\n+\tuint32_t i = 0;\n+\n+\tprintf(\"%s\", tcfg->msg);\n+\n+\tprintf(\"%s\", tcfg->htxt);\n+\n+\tfor (i = 0; i < tcfg->tconfig->num_cfg; i++) {\n+\t\tuint32_t avg = 0;\n+\t\tdouble drop_rate = 0.0;\n+\t\tdouble drop_prob = 0.0;\n+\t\tdouble diff = 0.0;\n+\n+\t\tif (test_rte_pie_init(tcfg) != PASS) {\n+\t\t\tresult = FAIL;\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\trte_pie_rt_data_init(tcfg->tqueue->pdata_in);\n+\t\trte_pie_set_active(NULL, tcfg->tqueue->pdata_in, 1);\n+\t\t*tcfg->tvar->enqueued = 0;\n+\t\t*tcfg->tvar->dropped = 0;\n+\n+\t\tif (increase_qsize(&tcfg->tconfig->pconfig[i],\n+\t\t\t\t\ttcfg->tqueue->pdata_in,\n+\t\t\t\t\ttcfg->tqueue->qlen,\n+\t\t\t\t\t*tcfg->tlevel,\n+\t\t\t\t\ttcfg->tqueue->q_ramp_up) != 0) {\n+\t\t\tresult = FAIL;\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\tenqueue_dequeue_func(&tcfg->tconfig->pconfig[i],\n+\t\t\t\t     tcfg->tqueue->pdata_in,\n+\t\t\t\t     tcfg->tqueue->qlen,\n+\t\t\t\t     tcfg->tvar->num_ops,\n+\t\t\t\t     tcfg->tvar->enqueued,\n+\t\t\t\t     tcfg->tvar->dropped);\n+\n+\t\tavg = rte_pie_get_avg_dq_time(NULL, tcfg->tqueue->pdata_in);\n+\n+\t\tdrop_rate = calc_drop_rate(*tcfg->tvar->enqueued,\n+\t\t\t\t\t\t\t*tcfg->tvar->dropped);\n+\t\tdrop_prob = rte_pie_get_drop_prob(NULL, tcfg->tqueue->pdata_in);\n+\n+\t\tif (!check_drop_rate(&diff, drop_rate, drop_prob,\n+\t\t\t\t (double)tcfg->tqueue->drop_tolerance)) {\n+\t\t\tfprintf(stderr, \"Fail: drop rate outside tolerance\\n\");\n+\t\t\tresult = FAIL;\n+\t\t}\n+\n+\t\tprintf(\"%-15u%-15u%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf\\n\",\n+\t\t\t\ti, avg, *tcfg->tvar->enqueued, *tcfg->tvar->dropped,\n+\t\t\t\tdrop_prob * 100.0, drop_rate * 100.0, diff,\n+\t\t\t\t(double)tcfg->tqueue->drop_tolerance);\n+\t}\n+out:\n+\treturn result;\n+}\n+\n+static uint32_t ft3_qlen[] = {100};\n+\n+static struct test_rte_pie_config ft3_tconfig =  {\n+\t.pconfig = ft_wpconfig,\n+\t.num_cfg = RTE_DIM(ft_wpconfig),\n+\t.qdelay_ref = 15,\n+\t.dp_update_interval = ft_dp_update_interval,\n+\t.max_burst = ft_max_burst,\n+\t.tailq_th = 15,\n+};\n+\n+static struct test_queue ft3_tqueue = {\n+\t.pdata_in = ft_rtdata,\n+\t.num_queues = RTE_DIM(ft_rtdata),\n+\t.qlen = ft3_qlen,\n+\t.q_ramp_up = 10,\n+\t.drop_tolerance = 0,\n+};\n+\n+static struct test_var ft3_tvar = {\n+\t.num_iterations = 0,\n+\t.num_ops = 10000,\n+\t.clk_freq = 0,\n+\t.dropped = ft_dropped,\n+\t.enqueued = ft_enqueued,\n+};\n+\n+/**\n+ * Test F3: functional test 3\n+ */\n+static uint32_t ft3_tlevels[] =  {64, 127, 222};\n+\n+static struct test_config func_test_config3 = {\n+\t.ifname = \"functional test interface\",\n+\t.msg = \"functional test 2 : use one pie configuration\\n\"\n+\t\t\t\"using non zero qlen\\n\\n\",\n+\t.htxt = \"                \"\n+\t\"drop probability \"\n+\t\"enqueued    \"\n+\t\"dropped     \"\n+\t\"drop prob % \"\n+\t\"drop rate % \"\n+\t\"diff %      \"\n+\t\"tolerance % \"\n+\t\"active  \"\n+\t\"\\n\",\n+\t.tconfig = &ft3_tconfig,\n+\t.tqueue = &ft3_tqueue,\n+\t.tvar = &ft3_tvar,\n+\t.tlevel = ft3_tlevels,\n+};\n+\n+static enum test_result func_test3(struct test_config *tcfg)\n+{\n+\tenum test_result result = PASS;\n+\tuint32_t i = 0;\n+\n+\tprintf(\"%s\", tcfg->msg);\n+\n+\tif (test_rte_pie_init(tcfg) != PASS) {\n+\t\tresult = FAIL;\n+\t\tgoto out;\n+\t}\n+\n+\tprintf(\"%s\", tcfg->htxt);\n+\n+\t/**\n+\t * reset rte_pie run-time data\n+\t */\n+\trte_pie_rt_data_init(tcfg->tqueue->pdata_in);\n+\trte_pie_set_active(NULL, tcfg->tqueue->pdata_in, 1);\n+\t*tcfg->tvar->enqueued = 0;\n+\t*tcfg->tvar->dropped = 0;\n+\n+\tif (increase_qsize(&tcfg->tconfig->pconfig[i],\n+\t\t\t\ttcfg->tqueue->pdata_in,\n+\t\t\t\ttcfg->tqueue->qlen,\n+\t\t\t\ttcfg->tlevel[i],\n+\t\t\t\ttcfg->tqueue->q_ramp_up) != 0) {\n+\t\tfprintf(stderr, \"Fail: increase qsize\\n\");\n+\t\tresult = FAIL;\n+\t\tgoto out;\n+\t}\n+\n+\tfor (i = 0; i < RTE_DIM(ft_tlevels); i++) {\n+\t\tconst char *label = NULL;\n+\t\tuint16_t prob = 0;\n+\t\tuint16_t active = 0;\n+\t\tdouble drop_rate = 1.0;\n+\t\tdouble drop_prob = 0.0;\n+\t\tdouble diff = 0.0;\n+\n+\t\tenqueue_dequeue_func(&tcfg->tconfig->pconfig[i],\n+\t\t\t\t     tcfg->tqueue->pdata_in,\n+\t\t\t\t     tcfg->tqueue->qlen,\n+\t\t\t\t     tcfg->tvar->num_ops,\n+\t\t\t\t     tcfg->tvar->enqueued,\n+\t\t\t\t     tcfg->tvar->dropped);\n+\n+\t\tdrop_rate = calc_drop_rate(*tcfg->tvar->enqueued,\n+\t\t\t\t\t\t*tcfg->tvar->dropped);\n+\t\tdrop_prob = rte_pie_get_drop_prob(NULL, tcfg->tqueue->pdata_in);\n+\n+\t\tif (drop_prob != 0) {\n+\t\t\tfprintf(stderr, \"Fail: check drop prob\\n\");\n+\t\t\tresult = FAIL;\n+\t\t}\n+\n+\t\tif (drop_rate != 0) {\n+\t\t\tfprintf(stderr, \"Fail: check drop rate\\n\");\n+\t\t\tresult = FAIL;\n+\t\t}\n+\n+\t\tlabel = \"Summary           \";\n+\t\tactive = rte_pie_get_active(NULL, tcfg->tqueue->pdata_in);\n+\t\tprintf(\"%s%-16u%-12u%-12u%-12.4lf%-12.4lf%-12.4lf%-12.4lf%-8i\\n\",\n+\t\t\t\tlabel, prob, *tcfg->tvar->enqueued, *tcfg->tvar->dropped,\n+\t\t\t\tdrop_prob * 100.0, drop_rate * 100.0, diff,\n+\t\t\t\t(double)tcfg->tqueue->drop_tolerance, active);\n+\t}\n+out:\n+\treturn result;\n+}\n+\n+/**\n+ * setup default values for the Performance test structures\n+ */\n+static struct rte_pie_config pt_wrconfig[1];\n+static struct rte_pie pt_rtdata[1];\n+static struct rte_pie pt_wtdata[1];\n+static uint32_t pt_q[] = {0};\n+static uint32_t pt_dropped[] = {0};\n+static uint32_t pt_enqueued[] = {0};\n+static uint32_t pt_dequeued[] = {0};\n+static uint16_t pt_max_burst[] = {64};\n+static uint16_t pt_dp_update_interval[] = {150};\n+\n+static struct test_rte_pie_config pt_tconfig =  {\n+\t.pconfig = pt_wrconfig,\n+\t.num_cfg = RTE_DIM(pt_wrconfig),\n+\t.qdelay_ref = 15,\n+\t.dp_update_interval = pt_dp_update_interval,\n+\t.max_burst = pt_max_burst,\n+\t.tailq_th = 150,\n+};\n+\n+static struct test_queue pt_tqueue = {\n+\t.pdata_in = pt_rtdata,\n+\t.num_queues = RTE_DIM(pt_rtdata),\n+\t.qlen = pt_q,\n+\t.q_ramp_up = 1000000,\n+\t.drop_tolerance = 0,  /* 0 percent */\n+};\n+\n+static struct test_rte_pie_config pt_tconfig2 =  {\n+\t.pconfig = pt_wrconfig,\n+\t.num_cfg = RTE_DIM(pt_wrconfig),\n+\t.qdelay_ref = 15,\n+\t.dp_update_interval = pt_dp_update_interval,\n+\t.max_burst = pt_max_burst,\n+\t.tailq_th = 150,\n+};\n+\n+static struct test_queue pt_tqueue2 = {\n+\t.pdata_in = pt_rtdata,\n+\t.pdata_out = pt_wtdata,\n+\t.num_queues = RTE_DIM(pt_rtdata),\n+\t.qlen = pt_q,\n+\t.q_ramp_up = 1000000,\n+\t.drop_tolerance = 0,  /* 0 percent */\n+};\n+\n+/**\n+ * enqueue/dequeue packets\n+ * aka\n+ *  rte_sched_port_enqueue(port, in_mbufs, 10);\n+ *\trte_sched_port_dequeue(port, out_mbufs, 10);\n+ */\n+static void enqueue_dequeue_perf(struct rte_pie_config *pie_cfg,\n+\t\t\t\t struct rte_pie *pie_in,\n+\t\t\t\t struct rte_pie *pie_out,\n+\t\t\t\t uint32_t *qlen,\n+\t\t\t\t uint32_t num_ops,\n+\t\t\t\t uint32_t *enqueued,\n+\t\t\t\t uint32_t *dropped,\n+\t\t\t\t uint32_t *dequeued,\n+\t\t\t\t struct rdtsc_prof *prof)\n+{\n+\tuint32_t i = 0;\n+\n+\tif (pie_cfg == NULL) {\n+\t\tprintf(\"%s: Error: PIE configuration cannot be empty.\\n\", __func__);\n+\t\treturn;\n+\t}\n+\n+\tif (pie_in == NULL) {\n+\t\tprintf(\"%s: Error: PIE enqueue data cannot be empty.\\n\", __func__);\n+\t\treturn;\n+\t}\n+\n+\tfor (i = 0; i < num_ops; i++) {\n+\t\tuint64_t ts = 0;\n+\t\tint ret = 0;\n+\n+\t\t/**\n+\t\t * enqueue\n+\t\t */\n+\t\tts = get_port_ts();\n+\t\trdtsc_prof_start(prof);\n+\t\tret = rte_pie_enqueue(pie_cfg, pie_in, *qlen,\n+\t\t\t\t\t\t\t\t1000*sizeof(uint32_t), ts);\n+\t\trdtsc_prof_end(prof);\n+\n+\t\tif (ret == 0)\n+\t\t\t(*enqueued)++;\n+\t\telse\n+\t\t\t(*dropped)++;\n+\n+\t\tif (pie_out != NULL) {\n+\t\t\tts = get_port_ts();\n+\t\t\trdtsc_prof_start(prof);\n+\t\t\trte_pie_dequeue(pie_out, 1000*sizeof(uint32_t), ts);\n+\t\t\trdtsc_prof_end(prof);\n+\n+\t\t\t(*dequeued)++;\n+\t\t}\n+\t}\n+}\n+\n+/**\n+ * Setup test structures for tests P1\n+ * performance tests 1\n+ */\n+static uint32_t pt1_tlevel[] = {80};\n+\n+static struct test_var perf1_tvar = {\n+\t.num_iterations = 0,\n+\t.num_ops = 30000,\n+\t.clk_freq = 0,\n+\t.dropped = pt_dropped,\n+\t.enqueued = pt_enqueued\n+};\n+\n+static struct test_config perf_test_config = {\n+\t.ifname = \"performance test 1 interface\",\n+\t.msg = \"performance test 1 : use one PIE configuration,\\n\"\n+\t\"\t\t     measure enqueue performance\\n\\n\",\n+\t.tconfig = &pt_tconfig,\n+\t.tqueue = &pt_tqueue,\n+\t.tvar = &perf1_tvar,\n+\t.tlevel = pt1_tlevel,\n+};\n+\n+/**\n+ * Performance test function to measure enqueue performance.\n+ *\n+ */\n+static enum test_result perf_test(struct test_config *tcfg)\n+{\n+\tenum test_result result = PASS;\n+\tstruct rdtsc_prof prof = {0, 0, 0, 0, 0.0, NULL};\n+\tuint32_t total = 0;\n+\n+\tprintf(\"%s\", tcfg->msg);\n+\n+\trdtsc_prof_init(&prof, \"enqueue\");\n+\n+\tif (test_rte_pie_init(tcfg) != PASS) {\n+\t\tresult = FAIL;\n+\t\tgoto out;\n+\t}\n+\n+\t/**\n+\t * initialize the rte_pie run time data structure\n+\t */\n+\trte_pie_rt_data_init(tcfg->tqueue->pdata_in);\n+\trte_pie_set_active(NULL, tcfg->tqueue->pdata_in, 1);\n+\t*tcfg->tvar->enqueued = 0;\n+\t*tcfg->tvar->dropped = 0;\n+\n+\tenqueue_dequeue_perf(tcfg->tconfig->pconfig,\n+\t\t\t     tcfg->tqueue->pdata_in,\n+\t\t\t\t NULL,\n+\t\t\t     tcfg->tqueue->qlen,\n+\t\t\t     tcfg->tvar->num_ops,\n+\t\t\t     tcfg->tvar->enqueued,\n+\t\t\t     tcfg->tvar->dropped,\n+\t\t\t\t tcfg->tvar->dequeued,\n+\t\t\t     &prof);\n+\n+\ttotal = *tcfg->tvar->enqueued + *tcfg->tvar->dropped;\n+\n+\tprintf(\"\\ntotal: %u, enqueued: %u (%.2lf%%), dropped: %u (%.2lf%%)\\n\",\n+\t\t\ttotal, *tcfg->tvar->enqueued,\n+\t\t\t((double)(*tcfg->tvar->enqueued) / (double)total) * 100.0,\n+\t\t\t*tcfg->tvar->dropped,\n+\t\t\t((double)(*tcfg->tvar->dropped) / (double)total) * 100.0);\n+\n+\trdtsc_prof_print(&prof);\n+out:\n+\treturn result;\n+}\n+\n+\n+\n+/**\n+ * Setup test structures for tests P2\n+ * performance tests 2\n+ */\n+static uint32_t pt2_tlevel[] = {80};\n+\n+static struct test_var perf2_tvar = {\n+\t.num_iterations = 0,\n+\t.num_ops = 30000,\n+\t.clk_freq = 0,\n+\t.dropped = pt_dropped,\n+\t.enqueued = pt_enqueued,\n+\t.dequeued = pt_dequeued\n+};\n+\n+static struct test_config perf_test_config2 = {\n+\t.ifname = \"performance test 2 interface\",\n+\t.msg = \"performance test 2 : use one PIE configuration,\\n\"\n+\t\"\t\t     measure enqueue & dequeue performance\\n\\n\",\n+\t.tconfig = &pt_tconfig2,\n+\t.tqueue = &pt_tqueue2,\n+\t.tvar = &perf2_tvar,\n+\t.tlevel = pt2_tlevel,\n+};\n+\n+/**\n+ * Performance test function to measure enqueue & dequeue performance.\n+ *\n+ */\n+static enum test_result perf_test2(struct test_config *tcfg)\n+{\n+\tenum test_result result = PASS;\n+\tstruct rdtsc_prof prof = {0, 0, 0, 0, 0.0, NULL};\n+\tuint32_t total = 0;\n+\n+\tprintf(\"%s\", tcfg->msg);\n+\n+\trdtsc_prof_init(&prof, \"enqueue\");\n+\n+\tif (test_rte_pie_init(tcfg) != PASS) {\n+\t\tresult = FAIL;\n+\t\tgoto out;\n+\t}\n+\n+\t/**\n+\t * initialize the rte_pie run time data structure\n+\t */\n+\trte_pie_rt_data_init(tcfg->tqueue->pdata_in);\n+\trte_pie_set_active(NULL, tcfg->tqueue->pdata_in, 1);\n+\t*tcfg->tvar->enqueued = 0;\n+\t*tcfg->tvar->dequeued = 0;\n+\t*tcfg->tvar->dropped = 0;\n+\n+\tenqueue_dequeue_perf(tcfg->tconfig->pconfig,\n+\t\t\t\t tcfg->tqueue->pdata_in,\n+\t\t\t\t tcfg->tqueue->pdata_out,\n+\t\t\t\t tcfg->tqueue->qlen,\n+\t\t\t\t tcfg->tvar->num_ops,\n+\t\t\t\t tcfg->tvar->enqueued,\n+\t\t\t\t tcfg->tvar->dropped,\n+\t\t\t\t tcfg->tvar->dequeued,\n+\t\t\t\t &prof);\n+\n+\ttotal = *tcfg->tvar->enqueued + *tcfg->tvar->dropped;\n+\n+\tprintf(\"\\ntotal: %u, dequeued: %u (%.2lf%%), dropped: %u (%.2lf%%)\\n\",\n+\t\t\ttotal, *tcfg->tvar->dequeued,\n+\t\t\t((double)(*tcfg->tvar->dequeued) / (double)total) * 100.0,\n+\t\t\t*tcfg->tvar->dropped,\n+\t\t\t((double)(*tcfg->tvar->dropped) / (double)total) * 100.0);\n+\n+\trdtsc_prof_print(&prof);\n+out:\n+\treturn result;\n+}\n+\n+/**\n+ * define the functional tests to be executed fast\n+ */\n+struct tests func_pie_tests_quick[] = {\n+\t{ &func_test_config1, func_test1 },\n+\t{ &func_test_config2, func_test2 },\n+};\n+\n+/**\n+ * define the functional and performance tests to be executed\n+ */\n+struct tests func_pie_tests[] = {\n+\t{ &func_test_config1, func_test1 },\n+\t{ &func_test_config2, func_test2 },\n+\t{ &func_test_config3, func_test3 },\n+};\n+\n+struct tests perf_pie_tests[] = {\n+\t{ &perf_test_config, perf_test },\n+\t{ &perf_test_config2, perf_test2 },\n+};\n+\n+/**\n+ * function to execute the required pie tests\n+ */\n+static void run_tests(struct tests *test_type, uint32_t test_count,\n+\t\t\t\t\t\tuint32_t *num_tests, uint32_t *num_pass)\n+{\n+\tenum test_result result = PASS;\n+\tuint32_t i = 0;\n+\tstatic const char *bar_str = \"-------------------------------------\"\n+\t\t\t\t\t\t\"-------------------------------------------\";\n+\tstatic const char *bar_pass_str = \"-------------------------------------\"\n+\t\t\t\t\t\t\"<pass>-------------------------------------\";\n+\tstatic const char *bar_fail_str = \"-------------------------------------\"\n+\t\t\t\t\t\t\"<fail>-------------------------------------\";\n+\n+\tfor (i = 0; i < test_count; i++) {\n+\t\tprintf(\"\\n%s\\n\", bar_str);\n+\t\tresult = test_type[i].testfn(test_type[i].testcfg);\n+\t\t(*num_tests)++;\n+\t\tif (result == PASS) {\n+\t\t\t(*num_pass)++;\n+\t\t\t\tprintf(\"%s\\n\", bar_pass_str);\n+\t\t} else {\n+\t\t\tprintf(\"%s\\n\", bar_fail_str);\n+\t\t}\n+\t}\n+}\n+\n+/**\n+ * check if functions accept invalid parameters\n+ *\n+ * First, all functions will be called without initialized PIE\n+ * Then, all of them will be called with NULL/invalid parameters\n+ *\n+ * Some functions are not tested as they are performance-critical and thus\n+ * don't do any parameter checking.\n+ */\n+static int\n+test_invalid_parameters(void)\n+{\n+\tstruct rte_pie_config config;\n+\tstatic const char *shf_str = \"rte_pie_config_init should have failed!\";\n+\tstatic const char *shf_rt_str = \"rte_pie_rt_data_init should have failed!\";\n+\n+\t/* NULL config */\n+\tif (rte_pie_rt_data_init(NULL) == 0) {\n+\t\tprintf(\"%i: %s\\n\", __LINE__, shf_rt_str);\n+\t\treturn -1;\n+\t}\n+\n+\t/* NULL config */\n+\tif (rte_pie_config_init(NULL, 0, 0, 0, 0) == 0) {\n+\t\tprintf(\"%i%s\\n\", __LINE__, shf_str);\n+\t\treturn -1;\n+\t}\n+\n+\t/* qdelay_ref <= 0 */\n+\tif (rte_pie_config_init(&config, 0, 1, 1, 1) == 0) {\n+\t\tprintf(\"%i%s\\n\", __LINE__, shf_str);\n+\t\treturn -1;\n+\t}\n+\n+\t/* dp_update_interval <= 0 */\n+\tif (rte_pie_config_init(&config, 1, 0, 1, 1) == 0) {\n+\t\tprintf(\"%i%s\\n\", __LINE__, shf_str);\n+\t\treturn -1;\n+\t}\n+\n+\t/* max_burst <= 0 */\n+\tif (rte_pie_config_init(&config, 1, 1, 0, 1) == 0) {\n+\t\tprintf(\"%i%s\\n\", __LINE__, shf_str);\n+\t\treturn -1;\n+\t}\n+\n+\t/* tailq_th <= 0 */\n+\tif (rte_pie_config_init(&config, 1, 1, 1, 0) == 0) {\n+\t\tprintf(\"%i%s\\n\", __LINE__, shf_str);\n+\t\treturn -1;\n+\t}\n+\n+\tRTE_SET_USED(config);\n+\n+\treturn 0;\n+}\n+\n+static void\n+show_stats(const uint32_t num_tests, const uint32_t num_pass)\n+{\n+\tif (num_pass == num_tests)\n+\t\tprintf(\"[total: %u, pass: %u]\\n\", num_tests, num_pass);\n+\telse\n+\t\tprintf(\"[total: %u, pass: %u, fail: %u]\\n\", num_tests, num_pass,\n+\t\t       num_tests - num_pass);\n+}\n+\n+static int\n+tell_the_result(const uint32_t num_tests, const uint32_t num_pass)\n+{\n+\treturn (num_pass == num_tests) ? 0 : 1;\n+}\n+\n+static int\n+test_pie(void)\n+{\n+\tuint32_t num_tests = 0;\n+\tuint32_t num_pass = 0;\n+\n+\tif (test_invalid_parameters() < 0)\n+\t\treturn -1;\n+\n+\trun_tests(func_pie_tests_quick, RTE_DIM(func_pie_tests_quick),\n+\t\t  &num_tests, &num_pass);\n+\tshow_stats(num_tests, num_pass);\n+\treturn tell_the_result(num_tests, num_pass);\n+}\n+\n+static int\n+test_pie_perf(void)\n+{\n+\tuint32_t num_tests = 0;\n+\tuint32_t num_pass = 0;\n+\n+\trun_tests(perf_pie_tests, RTE_DIM(perf_pie_tests), &num_tests, &num_pass);\n+\tshow_stats(num_tests, num_pass);\n+\treturn tell_the_result(num_tests, num_pass);\n+}\n+\n+static int\n+test_pie_all(void)\n+{\n+\tuint32_t num_tests = 0;\n+\tuint32_t num_pass = 0;\n+\n+\tif (test_invalid_parameters() < 0)\n+\t\treturn -1;\n+\n+\trun_tests(func_pie_tests, RTE_DIM(func_pie_tests), &num_tests, &num_pass);\n+\trun_tests(perf_pie_tests, RTE_DIM(perf_pie_tests), &num_tests, &num_pass);\n+\tshow_stats(num_tests, num_pass);\n+\treturn tell_the_result(num_tests, num_pass);\n+}\n+\n+REGISTER_TEST_COMMAND(pie_autotest, test_pie);\n+REGISTER_TEST_COMMAND(pie_perf, test_pie_perf);\n+REGISTER_TEST_COMMAND(pie_all, test_pie_all);\ndiff --git a/lib/sched/rte_pie.c b/lib/sched/rte_pie.c\nindex 2fcecb2db4..934e9aee50 100644\n--- a/lib/sched/rte_pie.c\n+++ b/lib/sched/rte_pie.c\n@@ -13,7 +13,7 @@\n #pragma warning(disable:2259) /* conversion may lose significant bits */\n #endif\n \n-void\n+int\n rte_pie_rt_data_init(struct rte_pie *pie)\n {\n \tif (pie == NULL) {\n@@ -22,6 +22,8 @@ rte_pie_rt_data_init(struct rte_pie *pie)\n \n \t\tif (pie == NULL)\n \t\t\tRTE_LOG(ERR, SCHED, \"%s: Memory allocation fails\\n\", __func__);\n+\n+\t\treturn -1;\n \t}\n \n \tpie->active = 0;\n@@ -35,6 +37,8 @@ rte_pie_rt_data_init(struct rte_pie *pie)\n \tpie->qdelay_old = 0;\n \tpie->drop_prob = 0;\n \tpie->accu_prob = 0;\n+\n+\treturn 0;\n }\n \n int\ndiff --git a/lib/sched/rte_pie.h b/lib/sched/rte_pie.h\nindex f83c95664f..68f1b96192 100644\n--- a/lib/sched/rte_pie.h\n+++ b/lib/sched/rte_pie.h\n@@ -20,6 +20,7 @@ extern \"C\" {\n \n #include <rte_random.h>\n #include <rte_debug.h>\n+#include <rte_cycles.h>\n \n #define RTE_DQ_THRESHOLD   16384   /**< Queue length threshold (2^14)\n \t\t\t\t     * to start measurement cycle (bytes)\n@@ -53,7 +54,7 @@ struct rte_pie_config {\n };\n \n /**\n- * RED run-time data\n+ * PIE run-time data\n  */\n struct rte_pie {\n \tuint16_t active;               /**< Flag for activating/deactivating pie */\n@@ -74,8 +75,12 @@ struct rte_pie {\n  * @brief Initialises run-time data\n  *\n  * @param pie [in,out] data pointer to PIE runtime data\n+ *\n+ * @return Operation status\n+ * @retval 0 success\n+ * @retval !0 error\n  */\n-void\n+int\n __rte_experimental\n rte_pie_rt_data_init(struct rte_pie *pie);\n \n@@ -113,7 +118,7 @@ rte_pie_config_init(struct rte_pie_config *pie_cfg,\n  * @retval 0 enqueue the packet\n  * @retval !0 drop the packet\n  */\n-static inline int\n+static int\n __rte_experimental\n rte_pie_enqueue_empty(const struct rte_pie_config *pie_cfg,\n \tstruct rte_pie *pie,\n@@ -145,7 +150,7 @@ rte_pie_enqueue_empty(const struct rte_pie_config *pie_cfg,\n  * @param pie [in, out] data pointer to PIE runtime data\n  * @param time [in] current time (measured in cpu cycles)\n  */\n-static inline void\n+static void\n __rte_experimental\n _calc_drop_probability(const struct rte_pie_config *pie_cfg,\n \tstruct rte_pie *pie, uint64_t time)\n@@ -155,7 +160,7 @@ _calc_drop_probability(const struct rte_pie_config *pie_cfg,\n \t/* Note: can be implemented using integer multiply.\n \t * DQ_THRESHOLD is power of 2 value.\n \t */\n-\tdouble current_qdelay = pie->qlen * (pie->avg_dq_time / RTE_DQ_THRESHOLD);\n+\tuint64_t current_qdelay = pie->qlen * (pie->avg_dq_time >> 14);\n \n \tdouble p = RTE_ALPHA * (current_qdelay - qdelay_ref) +\n \t\tRTE_BETA * (current_qdelay - pie->qdelay_old);\n@@ -181,7 +186,7 @@ _calc_drop_probability(const struct rte_pie_config *pie_cfg,\n \tdouble qdelay = qdelay_ref * 0.5;\n \n \t/*  Exponentially decay drop prob when congestion goes away  */\n-\tif (current_qdelay < qdelay && pie->qdelay_old < qdelay)\n+\tif ((double)current_qdelay < qdelay && pie->qdelay_old < qdelay)\n \t\tpie->drop_prob *= 0.98;     /* 1 - 1/64 is sufficient */\n \n \t/* Bound drop probability */\ndiff --git a/lib/sched/rte_sched.c b/lib/sched/rte_sched.c\nindex 320435ed91..480b6e531d 100644\n--- a/lib/sched/rte_sched.c\n+++ b/lib/sched/rte_sched.c\n@@ -1877,7 +1877,7 @@ rte_sched_port_aqm_drop(struct rte_sched_port *port,\n \tstruct rte_pie_config *pie_cfg = &subport->pie_config[tc_index];\n \tstruct rte_pie *pie = &qe->pie;\n \n-\treturn rte_pie_enqueue(pie_cfg, pie, pkt->pkt_len, qlen, port->time_cpu_cycles);\n+\treturn rte_pie_enqueue(pie_cfg, pie, qlen, pkt->pkt_len, port->time_cpu_cycles);\n }\n \n static inline void\n",
    "prefixes": [
        "v9",
        "5/5"
    ]
}