Show a patch.

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

{
    "id": 73595,
    "url": "https://patches.dpdk.org/api/patches/73595/?format=api",
    "web_url": "https://patches.dpdk.org/patch/73595/",
    "project": {
        "id": 1,
        "url": "https://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"
    },
    "msgid": "<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": "https://patches.dpdk.org/api/people/1198/?format=api",
        "name": "Ruifeng Wang",
        "email": "ruifeng.wang@arm.com"
    },
    "delegate": {
        "id": 24651,
        "url": "https://patches.dpdk.org/api/users/24651/?format=api",
        "username": "dmarchand",
        "first_name": "David",
        "last_name": "Marchand",
        "email": "david.marchand@redhat.com"
    },
    "mbox": "https://patches.dpdk.org/patch/73595/mbox/",
    "series": [
        {
            "id": 10914,
            "url": "https://patches.dpdk.org/api/series/10914/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=10914",
            "date": "2020-07-09T08:02:46",
            "name": "RCU integration with LPM library",
            "version": 8,
            "mbox": "https://patches.dpdk.org/series/10914/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/73595/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/73595/checks/",
    "tags": {},
    "headers": {
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "List-Post": "<mailto:dev@dpdk.org>",
        "References": "<20190906094534.36060-1-ruifeng.wang@arm.com>\n <20200709080250.200166-1-ruifeng.wang@arm.com>",
        "X-BeenThere": "dev@dpdk.org",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "Subject": "[dpdk-dev] [PATCH v8 2/3] test/lpm: add LPM RCU integration\n\tfunctional tests",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>",
        "From": "Ruifeng Wang <ruifeng.wang@arm.com>",
        "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)"
        ],
        "To": "Bruce Richardson <bruce.richardson@intel.com>,\n Vladimir Medvedkin <vladimir.medvedkin@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "Date": "Thu,  9 Jul 2020 16:02:48 +0800",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "In-Reply-To": "<20200709080250.200166-1-ruifeng.wang@arm.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>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Message-Id": "<20200709080250.200166-3-ruifeng.wang@arm.com>",
        "Return-Path": "<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"
    ]
}