Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/100986/?format=api
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" ] }{ "id": 100986, "url": "