Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/73595/?format=api
http://patches.dpdk.org/api/patches/73595/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200709080250.200166-3-ruifeng.wang@arm.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": "<20200709080250.200166-3-ruifeng.wang@arm.com>", "list_archive_url": "https://inbox.dpdk.org/dev/20200709080250.200166-3-ruifeng.wang@arm.com", "date": "2020-07-09T08:02:48", "name": "[v8,2/3] test/lpm: add LPM RCU integration functional tests", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "31a4e23099a56a2c89da0989a66340b6d35dc2de", "submitter": { "id": 1198, "url": "http://patches.dpdk.org/api/people/1198/?format=api", "name": "Ruifeng Wang", "email": "ruifeng.wang@arm.com" }, "delegate": { "id": 24651, "url": "http://patches.dpdk.org/api/users/24651/?format=api", "username": "dmarchand", "first_name": "David", "last_name": "Marchand", "email": "david.marchand@redhat.com" }, "mbox": "http://patches.dpdk.org/project/dpdk/patch/20200709080250.200166-3-ruifeng.wang@arm.com/mbox/", "series": [ { "id": 10914, "url": "http://patches.dpdk.org/api/series/10914/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=10914", "date": "2020-07-09T08:02:46", "name": "RCU integration with LPM library", "version": 8, "mbox": "http://patches.dpdk.org/series/10914/mbox/" } ], "comments": "http://patches.dpdk.org/api/patches/73595/comments/", "check": "success", "checks": "http://patches.dpdk.org/api/patches/73595/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@inbox.dpdk.org", "Delivered-To": "patchwork@inbox.dpdk.org", "Received": [ "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 0A440A0526;\n\tThu, 9 Jul 2020 10:03:29 +0200 (CEST)", "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 80BFC1DDCC;\n\tThu, 9 Jul 2020 10:03:18 +0200 (CEST)", "from foss.arm.com (foss.arm.com [217.140.110.172])\n by dpdk.org (Postfix) with ESMTP id 270F81DDE1\n for <dev@dpdk.org>; Thu, 9 Jul 2020 10:03:17 +0200 (CEST)", "from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14])\n by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A69AE1045;\n Thu, 9 Jul 2020 01:03:16 -0700 (PDT)", "from net-arm-thunderx2-02.shanghai.arm.com\n (net-arm-thunderx2-02.shanghai.arm.com [10.169.210.119])\n by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 148923F887;\n Thu, 9 Jul 2020 01:03:13 -0700 (PDT)" ], "From": "Ruifeng Wang <ruifeng.wang@arm.com>", "To": "Bruce Richardson <bruce.richardson@intel.com>,\n Vladimir Medvedkin <vladimir.medvedkin@intel.com>", "Cc": "dev@dpdk.org, mdr@ashroe.eu, konstantin.ananyev@intel.com,\n honnappa.nagarahalli@arm.com, nd@arm.com,\n Ruifeng Wang <ruifeng.wang@arm.com>", "Date": "Thu, 9 Jul 2020 16:02:48 +0800", "Message-Id": "<20200709080250.200166-3-ruifeng.wang@arm.com>", "X-Mailer": "git-send-email 2.17.1", "In-Reply-To": "<20200709080250.200166-1-ruifeng.wang@arm.com>", "References": "<20190906094534.36060-1-ruifeng.wang@arm.com>\n <20200709080250.200166-1-ruifeng.wang@arm.com>", "Subject": "[dpdk-dev] [PATCH v8 2/3] test/lpm: add LPM RCU integration\n\tfunctional tests", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "Add positive and negative tests for API rte_lpm_rcu_qsbr_add.\nAlso test LPM library behavior when RCU QSBR is enabled.\n\nSigned-off-by: Ruifeng Wang <ruifeng.wang@arm.com>\nReviewed-by: Gavin Hu <gavin.hu@arm.com>\nReviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>\nAcked-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com>\n---\n app/test/test_lpm.c | 291 +++++++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 290 insertions(+), 1 deletion(-)", "diff": "diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c\nindex 3a3fd097f..8330501f0 100644\n--- a/app/test/test_lpm.c\n+++ b/app/test/test_lpm.c\n@@ -8,6 +8,7 @@\n \n #include <rte_ip.h>\n #include <rte_lpm.h>\n+#include <rte_malloc.h>\n \n #include \"test.h\"\n #include \"test_xmmt_ops.h\"\n@@ -40,6 +41,9 @@ static int32_t test15(void);\n static int32_t test16(void);\n static int32_t test17(void);\n static int32_t test18(void);\n+static int32_t test19(void);\n+static int32_t test20(void);\n+static int32_t test21(void);\n \n rte_lpm_test tests[] = {\n /* Test Cases */\n@@ -61,7 +65,10 @@ rte_lpm_test tests[] = {\n \ttest15,\n \ttest16,\n \ttest17,\n-\ttest18\n+\ttest18,\n+\ttest19,\n+\ttest20,\n+\ttest21\n };\n \n #define MAX_DEPTH 32\n@@ -1265,6 +1272,288 @@ test18(void)\n \treturn PASS;\n }\n \n+/*\n+ * rte_lpm_rcu_qsbr_add positive and negative tests.\n+ * - Add RCU QSBR variable to LPM\n+ * - Add another RCU QSBR variable to LPM\n+ * - Check returns\n+ */\n+int32_t\n+test19(void)\n+{\n+\tstruct rte_lpm *lpm = NULL;\n+\tstruct rte_lpm_config config;\n+\tsize_t sz;\n+\tstruct rte_rcu_qsbr *qsv;\n+\tstruct rte_rcu_qsbr *qsv2;\n+\tint32_t status;\n+\tstruct rte_lpm_rcu_config rcu_cfg = {0};\n+\n+\tconfig.max_rules = MAX_RULES;\n+\tconfig.number_tbl8s = NUMBER_TBL8S;\n+\tconfig.flags = 0;\n+\n+\tlpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);\n+\tTEST_LPM_ASSERT(lpm != NULL);\n+\n+\t/* Create RCU QSBR variable */\n+\tsz = rte_rcu_qsbr_get_memsize(RTE_MAX_LCORE);\n+\tqsv = (struct rte_rcu_qsbr *)rte_zmalloc_socket(NULL, sz,\n+\t\t\t\t\tRTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);\n+\tTEST_LPM_ASSERT(qsv != NULL);\n+\n+\tstatus = rte_rcu_qsbr_init(qsv, RTE_MAX_LCORE);\n+\tTEST_LPM_ASSERT(status == 0);\n+\n+\trcu_cfg.v = qsv;\n+\t/* Invalid QSBR mode */\n+\trcu_cfg.mode = 2;\n+\tstatus = rte_lpm_rcu_qsbr_add(lpm, &rcu_cfg, NULL);\n+\tTEST_LPM_ASSERT(status != 0);\n+\n+\trcu_cfg.mode = RTE_LPM_QSBR_MODE_DQ;\n+\t/* Attach RCU QSBR to LPM table */\n+\tstatus = rte_lpm_rcu_qsbr_add(lpm, &rcu_cfg, NULL);\n+\tTEST_LPM_ASSERT(status == 0);\n+\n+\t/* Create and attach another RCU QSBR to LPM table */\n+\tqsv2 = (struct rte_rcu_qsbr *)rte_zmalloc_socket(NULL, sz,\n+\t\t\t\t\tRTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);\n+\tTEST_LPM_ASSERT(qsv2 != NULL);\n+\n+\trcu_cfg.v = qsv2;\n+\trcu_cfg.mode = RTE_LPM_QSBR_MODE_SYNC;\n+\tstatus = rte_lpm_rcu_qsbr_add(lpm, &rcu_cfg, NULL);\n+\tTEST_LPM_ASSERT(status != 0);\n+\n+\trte_lpm_free(lpm);\n+\trte_free(qsv);\n+\trte_free(qsv2);\n+\n+\treturn PASS;\n+}\n+\n+/*\n+ * rte_lpm_rcu_qsbr_add DQ mode functional test.\n+ * Reader and writer are in the same thread in this test.\n+ * - Create LPM which supports 1 tbl8 group at max\n+ * - Add RCU QSBR variable to LPM\n+ * - Add a rule with depth=28 (> 24)\n+ * - Register a reader thread (not a real thread)\n+ * - Reader lookup existing rule\n+ * - Writer delete the rule\n+ * - Reader lookup the rule\n+ * - Writer re-add the rule (no available tbl8 group)\n+ * - Reader report quiescent state and unregister\n+ * - Writer re-add the rule\n+ * - Reader lookup the rule\n+ */\n+int32_t\n+test20(void)\n+{\n+\tstruct rte_lpm *lpm = NULL;\n+\tstruct rte_lpm_config config;\n+\tsize_t sz;\n+\tstruct rte_rcu_qsbr *qsv;\n+\tint32_t status;\n+\tuint32_t ip, next_hop, next_hop_return;\n+\tuint8_t depth;\n+\tstruct rte_lpm_rcu_config rcu_cfg = {0};\n+\n+\tconfig.max_rules = MAX_RULES;\n+\tconfig.number_tbl8s = 1;\n+\tconfig.flags = 0;\n+\n+\tlpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);\n+\tTEST_LPM_ASSERT(lpm != NULL);\n+\n+\t/* Create RCU QSBR variable */\n+\tsz = rte_rcu_qsbr_get_memsize(1);\n+\tqsv = (struct rte_rcu_qsbr *)rte_zmalloc_socket(NULL, sz,\n+\t\t\t\tRTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);\n+\tTEST_LPM_ASSERT(qsv != NULL);\n+\n+\tstatus = rte_rcu_qsbr_init(qsv, 1);\n+\tTEST_LPM_ASSERT(status == 0);\n+\n+\trcu_cfg.v = qsv;\n+\trcu_cfg.mode = RTE_LPM_QSBR_MODE_DQ;\n+\t/* Attach RCU QSBR to LPM table */\n+\tstatus = rte_lpm_rcu_qsbr_add(lpm, &rcu_cfg, NULL);\n+\tTEST_LPM_ASSERT(status == 0);\n+\n+\tip = RTE_IPV4(192, 0, 2, 100);\n+\tdepth = 28;\n+\tnext_hop = 1;\n+\tstatus = rte_lpm_add(lpm, ip, depth, next_hop);\n+\tTEST_LPM_ASSERT(status == 0);\n+\tTEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);\n+\n+\t/* Register pseudo reader */\n+\tstatus = rte_rcu_qsbr_thread_register(qsv, 0);\n+\tTEST_LPM_ASSERT(status == 0);\n+\trte_rcu_qsbr_thread_online(qsv, 0);\n+\n+\tstatus = rte_lpm_lookup(lpm, ip, &next_hop_return);\n+\tTEST_LPM_ASSERT(status == 0);\n+\tTEST_LPM_ASSERT(next_hop_return == next_hop);\n+\n+\t/* Writer update */\n+\tstatus = rte_lpm_delete(lpm, ip, depth);\n+\tTEST_LPM_ASSERT(status == 0);\n+\tTEST_LPM_ASSERT(!lpm->tbl24[ip>>8].valid);\n+\n+\tstatus = rte_lpm_lookup(lpm, ip, &next_hop_return);\n+\tTEST_LPM_ASSERT(status != 0);\n+\n+\tstatus = rte_lpm_add(lpm, ip, depth, next_hop);\n+\tTEST_LPM_ASSERT(status != 0);\n+\n+\t/* Reader quiescent */\n+\trte_rcu_qsbr_quiescent(qsv, 0);\n+\n+\tstatus = rte_lpm_add(lpm, ip, depth, next_hop);\n+\tTEST_LPM_ASSERT(status == 0);\n+\n+\trte_rcu_qsbr_thread_offline(qsv, 0);\n+\tstatus = rte_rcu_qsbr_thread_unregister(qsv, 0);\n+\tTEST_LPM_ASSERT(status == 0);\n+\n+\tstatus = rte_lpm_lookup(lpm, ip, &next_hop_return);\n+\tTEST_LPM_ASSERT(status == 0);\n+\tTEST_LPM_ASSERT(next_hop_return == next_hop);\n+\n+\trte_lpm_free(lpm);\n+\trte_free(qsv);\n+\n+\treturn PASS;\n+}\n+\n+static struct rte_lpm *g_lpm;\n+static struct rte_rcu_qsbr *g_v;\n+static uint32_t g_ip = RTE_IPV4(192, 0, 2, 100);\n+static volatile uint8_t writer_done;\n+/* Report quiescent state interval every 1024 lookups. Larger critical\n+ * sections in reader will result in writer polling multiple times.\n+ */\n+#define QSBR_REPORTING_INTERVAL 1024\n+#define WRITER_ITERATIONS\t512\n+\n+/*\n+ * Reader thread using rte_lpm data structure with RCU.\n+ */\n+static int\n+test_lpm_rcu_qsbr_reader(void *arg)\n+{\n+\tint i;\n+\tuint32_t next_hop_return = 0;\n+\n+\tRTE_SET_USED(arg);\n+\t/* Register this thread to report quiescent state */\n+\trte_rcu_qsbr_thread_register(g_v, 0);\n+\trte_rcu_qsbr_thread_online(g_v, 0);\n+\n+\tdo {\n+\t\tfor (i = 0; i < QSBR_REPORTING_INTERVAL; i++)\n+\t\t\trte_lpm_lookup(g_lpm, g_ip, &next_hop_return);\n+\n+\t\t/* Update quiescent state */\n+\t\trte_rcu_qsbr_quiescent(g_v, 0);\n+\t} while (!writer_done);\n+\n+\trte_rcu_qsbr_thread_offline(g_v, 0);\n+\trte_rcu_qsbr_thread_unregister(g_v, 0);\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * rte_lpm_rcu_qsbr_add sync mode functional test.\n+ * 1 Reader and 1 writer. They cannot be in the same thread in this test.\n+ * - Create LPM which supports 1 tbl8 group at max\n+ * - Add RCU QSBR variable with sync mode to LPM\n+ * - Register a reader thread. Reader keeps looking up a specific rule.\n+ * - Writer keeps adding and deleting a specific rule with depth=28 (> 24)\n+ */\n+int32_t\n+test21(void)\n+{\n+\tstruct rte_lpm_config config;\n+\tsize_t sz;\n+\tint32_t status;\n+\tuint32_t i, next_hop;\n+\tuint8_t depth;\n+\tstruct rte_lpm_rcu_config rcu_cfg = {0};\n+\n+\tif (rte_lcore_count() < 2) {\n+\t\tprintf(\"Not enough cores for %s, expecting at least 2\\n\",\n+\t\t\t__func__);\n+\t\treturn TEST_SKIPPED;\n+\t}\n+\n+\tconfig.max_rules = MAX_RULES;\n+\tconfig.number_tbl8s = 1;\n+\tconfig.flags = 0;\n+\n+\tg_lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);\n+\tTEST_LPM_ASSERT(g_lpm != NULL);\n+\n+\t/* Create RCU QSBR variable */\n+\tsz = rte_rcu_qsbr_get_memsize(1);\n+\tg_v = (struct rte_rcu_qsbr *)rte_zmalloc_socket(NULL, sz,\n+\t\t\t\tRTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);\n+\tTEST_LPM_ASSERT(g_v != NULL);\n+\n+\tstatus = rte_rcu_qsbr_init(g_v, 1);\n+\tTEST_LPM_ASSERT(status == 0);\n+\n+\trcu_cfg.v = g_v;\n+\trcu_cfg.mode = RTE_LPM_QSBR_MODE_SYNC;\n+\t/* Attach RCU QSBR to LPM table */\n+\tstatus = rte_lpm_rcu_qsbr_add(g_lpm, &rcu_cfg, NULL);\n+\tTEST_LPM_ASSERT(status == 0);\n+\n+\twriter_done = 0;\n+\t/* Launch reader thread */\n+\trte_eal_remote_launch(test_lpm_rcu_qsbr_reader, NULL,\n+\t\t\t\trte_get_next_lcore(-1, 1, 0));\n+\n+\tdepth = 28;\n+\tnext_hop = 1;\n+\tstatus = rte_lpm_add(g_lpm, g_ip, depth, next_hop);\n+\tif (status != 0) {\n+\t\tprintf(\"%s: Failed to add rule\\n\", __func__);\n+\t\tgoto error;\n+\t}\n+\n+\t/* Writer update */\n+\tfor (i = 0; i < WRITER_ITERATIONS; i++) {\n+\t\tstatus = rte_lpm_delete(g_lpm, g_ip, depth);\n+\t\tif (status != 0) {\n+\t\t\tprintf(\"%s: Failed to delete rule at iteration %d\\n\",\n+\t\t\t\t__func__, i);\n+\t\t\tgoto error;\n+\t\t}\n+\n+\t\tstatus = rte_lpm_add(g_lpm, g_ip, depth, next_hop);\n+\t\tif (status != 0) {\n+\t\t\tprintf(\"%s: Failed to add rule at iteration %d\\n\",\n+\t\t\t\t__func__, i);\n+\t\t\tgoto error;\n+\t\t}\n+\t}\n+\n+error:\n+\twriter_done = 1;\n+\t/* Wait until reader exited. */\n+\trte_eal_mp_wait_lcore();\n+\n+\trte_lpm_free(g_lpm);\n+\trte_free(g_v);\n+\n+\treturn (status == 0) ? PASS : -1;\n+}\n+\n /*\n * Do all unit tests.\n */\n", "prefixes": [ "v8", "2/3" ] }{ "id": 73595, "url": "