Show a patch.

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

{
    "id": 207,
    "url": "https://patches.dpdk.org/api/patches/207/",
    "web_url": "https://patches.dpdk.org/patch/207/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/",
        "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": "<1408947174-11323-5-git-send-email-cunming.liang@intel.com>",
    "date": "2014-08-25T06:12:53",
    "name": "[dpdk-dev,4/5] app/test: add unit test to measure RX burst cycles",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "86325d8cb9cbbe3d274f1e9972960fad9c4c9299",
    "submitter": {
        "id": 46,
        "url": "https://patches.dpdk.org/api/people/46/",
        "name": "Cunming Liang",
        "email": "cunming.liang@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/patch/207/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/207/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/207/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<cliang18@shecgisg004.sh.intel.com>",
        "References": "<1408947174-11323-1-git-send-email-cunming.liang@intel.com>",
        "X-Mailman-Version": "2.1.15",
        "X-IronPort-AV": "E=Sophos;i=\"5.04,395,1406617200\"; d=\"scan'208\";a=\"581204318\"",
        "From": "Cunming Liang <cunming.liang@intel.com>",
        "X-List-Received-Date": "Mon, 25 Aug 2014 06:10:08 -0000",
        "X-BeenThere": "dev@dpdk.org",
        "Message-Id": "<1408947174-11323-5-git-send-email-cunming.liang@intel.com>",
        "Received": [
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id 7F700B379\n\tfor <dev@dpdk.org>; Mon, 25 Aug 2014 08:10:07 +0200 (CEST)",
            "from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby fmsmga102.fm.intel.com with ESMTP; 24 Aug 2014 23:13:42 -0700",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby fmsmga001.fm.intel.com with ESMTP; 24 Aug 2014 23:13:41 -0700",
            "from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com\n\t[10.239.29.89])\n\tby shvmail01.sh.intel.com with ESMTP id s7P6Def9012314;\n\tMon, 25 Aug 2014 14:13:40 +0800",
            "from shecgisg004.sh.intel.com (localhost [127.0.0.1])\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP\n\tid s7P6DaZ7011403; Mon, 25 Aug 2014 14:13:38 +0800",
            "(from cliang18@localhost)\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id s7P6DaHD011399; \n\tMon, 25 Aug 2014 14:13:36 +0800"
        ],
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "Precedence": "list",
        "Date": "Mon, 25 Aug 2014 14:12:53 +0800",
        "Subject": "[dpdk-dev] [PATCH 4/5] app/test: add unit test to measure RX burst\n\tcycles",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "X-ExtLoop1": "1",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "In-Reply-To": "<1408947174-11323-1-git-send-email-cunming.liang@intel.com>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "To": "dev@dpdk.org"
    },
    "content": "Signed-off-by: Cunming Liang <cunming.liang@intel.com>\n---\n app/test/commands.c      |  43 +++++++++-\n app/test/test.h          |   1 +\n app/test/test_pmd_perf.c | 214 +++++++++++++++++++++++++++++++++++++++++++----\n 3 files changed, 237 insertions(+), 21 deletions(-)",
    "diff": "diff --git a/app/test/commands.c b/app/test/commands.c\nindex 8721e25..f222398 100644\n--- a/app/test/commands.c\n+++ b/app/test/commands.c\n@@ -454,8 +454,6 @@ cmdline_parse_inst_t cmd_quit = {\n \n /****************/\n \n-/****************/\n-\n struct cmd_set_rxtx_result {\n \tcmdline_fixed_string_t set;\n \tcmdline_fixed_string_t mode;\n@@ -490,8 +488,6 @@ cmdline_parse_inst_t cmd_set_rxtx = {\n \n /****************/\n \n-/****************/\n-\n struct cmd_set_rxtx_anchor {\n \tcmdline_fixed_string_t set;\n \tcmdline_fixed_string_t type;\n@@ -528,6 +524,44 @@ cmdline_parse_inst_t cmd_set_rxtx_anchor = {\n \n /****************/\n \n+/* for stream control */\n+struct cmd_set_rxtx_sc {\n+\tcmdline_fixed_string_t set;\n+\tcmdline_fixed_string_t type;\n+};\n+\n+static void\n+cmd_set_rxtx_sc_parsed(void *parsed_result,\n+\t\t\t   struct cmdline *cl,\n+\t\t\t   __attribute__((unused)) void *data)\n+{\n+\tstruct cmd_set_rxtx_sc *res = parsed_result;\n+\tif (test_set_rxtx_sc(res->type) < 0)\n+\t\tcmdline_printf(cl, \"Cannot find such stream control\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_set_rxtx_sc_set =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, set,\n+\t\t\t\t \"set_rxtx_sc\");\n+\n+cmdline_parse_token_string_t cmd_set_rxtx_sc_type =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, type, NULL);\n+\n+cmdline_parse_inst_t cmd_set_rxtx_sc = {\n+\t.f = cmd_set_rxtx_sc_parsed,  /* function to call */\n+\t.data = NULL,      /* 2nd arg of func */\n+\t.help_str = \"set rxtx stream control: \"\n+\t\t\t\"set_rxtx_sc <type>\",\n+\t.tokens = {        /* token list, NULL terminated */\n+\t\t(void *)&cmd_set_rxtx_sc_set,\n+\t\t(void *)&cmd_set_rxtx_sc_type,\n+\t\tNULL,\n+\t},\n+};\n+\n+/****************/\n+\n+\n cmdline_parse_ctx_t main_ctx[] = {\n \t(cmdline_parse_inst_t *)&cmd_autotest,\n \t(cmdline_parse_inst_t *)&cmd_dump,\n@@ -536,6 +570,7 @@ cmdline_parse_ctx_t main_ctx[] = {\n \t(cmdline_parse_inst_t *)&cmd_quit,\n \t(cmdline_parse_inst_t *)&cmd_set_rxtx,\n \t(cmdline_parse_inst_t *)&cmd_set_rxtx_anchor,\n+\t(cmdline_parse_inst_t *)&cmd_set_rxtx_sc,\n \tNULL,\n };\n \ndiff --git a/app/test/test.h b/app/test/test.h\nindex c24ce9f..4c10afe 100644\n--- a/app/test/test.h\n+++ b/app/test/test.h\n@@ -186,6 +186,7 @@ int test_link_bonding(void);\n int test_pmd_perf(void);\n int test_set_rxtx_conf(cmdline_fixed_string_t mode);\n int test_set_rxtx_anchor(cmdline_fixed_string_t type);\n+int test_set_rxtx_sc(cmdline_fixed_string_t type);\n \n \n int test_pci_run;\ndiff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c\nindex 5d02fac..e11fa41 100644\n--- a/app/test/test_pmd_perf.c\n+++ b/app/test/test_pmd_perf.c\n@@ -39,6 +39,8 @@\n #include <rte_cycles.h>\n #include <rte_ethdev.h>\n #include <rte_byteorder.h>\n+#include <rte_atomic.h>\n+#include <rte_malloc.h>\n #include \"packet_burst_generator.h\"\n #include \"test.h\"\n \n@@ -73,13 +75,15 @@\n #define TX_HTHRESH 0  /**< Default values of TX host threshold reg. */\n #define TX_WTHRESH 0  /**< Default values of TX write-back threshold reg. */\n \n+#define MAX_TRAFFIC_BURST              2048\n \n #define NB_MBUF RTE_MAX(\t\t\t\t\t\t\\\n-\t  (unsigned)(nb_ports*nb_rx_queue*RTE_TEST_RX_DESC_DEFAULT +\t\\\n-\t   nb_ports*nb_lcores*MAX_PKT_BURST +\t\t\t\t\\\n-\t   nb_ports*nb_tx_queue*RTE_TEST_TX_DESC_DEFAULT +\t\t\\\n-\t   nb_lcores*MEMPOOL_CACHE_SIZE),\t\t\t\t\\\n-\t  (unsigned)8192)\n+\t\t(unsigned)(nb_ports*nb_rx_queue*nb_rxd +\t\t\\\n+\t\t\t   nb_ports*nb_lcores*MAX_PKT_BURST +\t\t\\\n+\t\t\t   nb_ports*nb_tx_queue*nb_txd +\t\t\\\n+\t\t\t   nb_lcores*MEMPOOL_CACHE_SIZE +\t\t\\\n+\t\t\t   nb_ports*MAX_TRAFFIC_BURST),\t\t\t\\\n+\t\t\t(unsigned)8192)\n \n \n static struct rte_mempool *mbufpool[NB_SOCKETS];\n@@ -147,6 +151,14 @@ struct lcore_conf lcore_conf[RTE_MAX_LCORE];\n \n static uint64_t link_mbps;\n \n+enum {\n+\tSC_CONTINUOUS = 0,\n+\tSC_BURST_POLL_FIRST,\n+\tSC_BURST_XMIT_FIRST,\n+};\n+\n+static uint32_t sc_flag;\n+\n /* Check the link status of all ports in up to 3s, and print them finally */\n static void\n check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)\n@@ -361,8 +373,7 @@ signal_handler(int signum)\n \t\tstats_display(0);\n }\n \n-#define MAX_TRAFIC_BURST                (4096)\n-struct rte_mbuf *tx_burst[MAX_TRAFIC_BURST];\n+struct rte_mbuf **tx_burst;\n \n uint64_t (*do_measure)(struct lcore_conf *conf,\n \t\t       struct rte_mbuf *pkts_burst[],\n@@ -503,7 +514,7 @@ main_loop(__rte_unused void *args)\n \tif (conf->status != LCORE_USED)\n \t\treturn 0;\n \n-\tpkt_per_port =  MAX_TRAFIC_BURST / conf->nb_ports;\n+\tpkt_per_port = MAX_TRAFFIC_BURST;\n \n \tint idx = 0;\n \tfor (i = 0; i < conf->nb_ports; i++) {\n@@ -554,12 +565,137 @@ main_loop(__rte_unused void *args)\n \treturn 0;\n }\n \n+rte_atomic64_t start;\n+\n+/* main processing loop */\n+static inline int\n+poll_burst(void *args)\n+{\n+#define MAX_IDLE           (1000)\n+\tunsigned lcore_id;\n+\tstruct rte_mbuf **pkts_burst;\n+\tuint64_t diff_tsc, cur_tsc;\n+\tuint16_t next[RTE_MAX_ETHPORTS];\n+\tstruct lcore_conf *conf;\n+\tuint32_t pkt_per_port = *((uint32_t *)args);\n+\tunsigned i, portid, nb_rx = 0;\n+\tuint64_t total;\n+\tuint64_t timeout = MAX_IDLE;\n+\n+\tlcore_id = rte_lcore_id();\n+\tconf = &lcore_conf[lcore_id];\n+\tif (conf->status != LCORE_USED)\n+\t\treturn 0;\n+\n+\ttotal = pkt_per_port * conf->nb_ports;\n+\tprintf(\"start to receive total expect %ld\\n\", total);\n+\n+\tpkts_burst = (struct rte_mbuf **)\n+\t\trte_calloc_socket(\"poll_burst\",\n+\t\t\t\t  total, sizeof(void *),\n+\t\t\t\t  CACHE_LINE_SIZE, conf->socketid);\n+\tif (!pkts_burst)\n+\t\treturn -1;\n+\n+\tfor (i = 0; i < conf->nb_ports; i++) {\n+\t\tportid = conf->portlist[i];\n+\t\tnext[portid] = i * pkt_per_port;\n+\t}\n+\n+\twhile (!rte_atomic64_read(&start))\n+\t\t;\n+\n+\tcur_tsc = rte_rdtsc();\n+\twhile (total) {\n+\t\tfor (i = 0; i < conf->nb_ports; i++) {\n+\t\t\tportid = conf->portlist[i];\n+\t\t\tnb_rx = rte_eth_rx_burst((uint8_t) portid, 0,\n+\t\t\t\t\t\t &pkts_burst[next[portid]],\n+\t\t\t\t\t\t MAX_PKT_BURST);\n+\t\t\tif (unlikely(nb_rx == 0)) {\n+\t\t\t\ttimeout--;\n+\t\t\t\tif (unlikely(timeout == 0))\n+\t\t\t\t\tgoto timeout;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tnext[portid] += nb_rx;\n+\t\t\ttotal -= nb_rx;\n+\t\t}\n+\t}\n+timeout:\n+\tdiff_tsc = rte_rdtsc() - cur_tsc;\n+\n+\tprintf(\"%ld packets lost, IDLE %ld times\\n\", total, MAX_IDLE - timeout);\n+\n+\t/* clean up */\n+\ttotal = pkt_per_port * conf->nb_ports - total;\n+\tfor (i = 0; i < total; i++)\n+\t\trte_pktmbuf_free(pkts_burst[i]);\n+\n+\trte_free(pkts_burst);\n+\n+\treturn diff_tsc / total;\n+}\n+\n+/* main processing loop */\n+static int\n+exec_burst(uint32_t flags, int lcore)\n+{\n+\tunsigned i, portid, nb_tx = 0;\n+\tstruct lcore_conf *conf;\n+\tuint32_t pkt_per_port;\n+\tint num, idx = 0;\n+\tint diff_tsc;\n+\n+\tconf = &lcore_conf[lcore];\n+\n+\tpkt_per_port = MAX_TRAFFIC_BURST;\n+\tnum = pkt_per_port;\n+\n+\trte_atomic64_init(&start);\n+\n+\t/* start polling thread, but not actually poll yet */\n+\trte_eal_remote_launch(poll_burst,\n+\t\t\t      (void *)&pkt_per_port, lcore);\n+\n+\t/* Only when polling first */\n+\tif (flags == SC_BURST_POLL_FIRST)\n+\t\trte_atomic64_set(&start, 1);\n+\n+\t/* start xmit */\n+\twhile (num) {\n+\t\tnb_tx = RTE_MIN(MAX_PKT_BURST, num);\n+\t\tfor (i = 0; i < conf->nb_ports; i++) {\n+\t\t\tportid = conf->portlist[i];\n+\t\t\trte_eth_tx_burst(portid, 0,\n+\t\t\t\t\t &tx_burst[idx], nb_tx);\n+\t\t\tidx += nb_tx;\n+\t\t}\n+\t\tnum -= nb_tx;\n+\t}\n+\n+\tsleep(5);\n+\n+\t/* only when polling second  */\n+\tif (flags == SC_BURST_XMIT_FIRST)\n+\t\trte_atomic64_set(&start, 1);\n+\n+\t/* wait for polling finished */\n+\tdiff_tsc = rte_eal_wait_lcore(lcore);\n+\tif (diff_tsc < 0)\n+\t\treturn -1;\n+\n+\tprintf(\"Result: %d cycles per packet\\n\", diff_tsc);\n+\n+\treturn 0;\n+}\n+\n int\n test_pmd_perf(void)\n {\n \tuint16_t nb_ports, num, nb_lcores, slave_id = (uint16_t)-1;\n-\tuint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;\n-\tuint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;\n+\tuint16_t nb_rxd = MAX_TRAFFIC_BURST;\n+\tuint16_t nb_txd = MAX_TRAFFIC_BURST;\n \tuint16_t portid;\n \tuint16_t nb_rx_queue = 1, nb_tx_queue = 1;\n \tint socketid = -1;\n@@ -587,6 +723,12 @@ test_pmd_perf(void)\n \n \tinit_mbufpool(NB_MBUF);\n \n+\tif (sc_flag == SC_CONTINUOUS) {\n+\t\tnb_rxd = RTE_TEST_RX_DESC_DEFAULT;\n+\t\tnb_txd = RTE_TEST_TX_DESC_DEFAULT;\n+\t}\n+\tprintf(\"CONFIG RXD=%d TXD=%d\\n\", nb_rxd, nb_txd);\n+\n \treset_count();\n \tnum = 0;\n \tfor (portid = 0; portid < nb_ports; portid++) {\n@@ -651,15 +793,34 @@ test_pmd_perf(void)\n \t}\n \tcheck_all_ports_link_status(nb_ports, RTE_PORT_ALL);\n \n-\tinit_traffic(mbufpool[socketid], tx_burst, MAX_TRAFIC_BURST);\n+\tif (tx_burst == NULL) {\n+\t\ttx_burst = (struct rte_mbuf **)\n+\t\t\trte_calloc_socket(\"tx_buff\",\n+\t\t\t\t\t  MAX_TRAFFIC_BURST * nb_ports,\n+\t\t\t\t\t  sizeof(void *),\n+\t\t\t\t\t  CACHE_LINE_SIZE, socketid);\n+\t\tif (!tx_burst)\n+\t\t\treturn -1;\n+\t}\n \n-\t/* do both rxtx by default */\n-\tif (NULL == do_measure)\n-\t\tdo_measure = measure_rxtx;\n+\tinit_traffic(mbufpool[socketid],\n+\t\t     tx_burst, MAX_TRAFFIC_BURST * nb_ports);\n \n-\trte_eal_remote_launch(main_loop, NULL, slave_id);\n-\tif (rte_eal_wait_lcore(slave_id) < 0)\n-\t\treturn -1;\n+\tprintf(\"Generate %d packets @socket %d\\n\",\n+\t       MAX_TRAFFIC_BURST * nb_ports, socketid);\n+\n+\tif (sc_flag == SC_CONTINUOUS) {\n+\t\t/* do both rxtx by default */\n+\t\tif (NULL == do_measure)\n+\t\t\tdo_measure = measure_rxtx;\n+\n+\t\trte_eal_remote_launch(main_loop, NULL, slave_id);\n+\n+\t\tif (rte_eal_wait_lcore(slave_id) < 0)\n+\t\t\treturn -1;\n+\t} else if (sc_flag == SC_BURST_POLL_FIRST ||\n+\t\t   sc_flag == SC_BURST_XMIT_FIRST)\n+\t\texec_burst(sc_flag, slave_id);\n \n \t/* port tear down */\n \tfor (portid = 0; portid < nb_ports; portid++) {\n@@ -735,3 +896,22 @@ test_set_rxtx_anchor(cmdline_fixed_string_t type)\n \n \treturn -1;\n }\n+\n+int\n+test_set_rxtx_sc(cmdline_fixed_string_t type)\n+{\n+\tprintf(\"stream control switch to %s\\n\", type);\n+\n+\tif (!strcmp(type, \"continuous\")) {\n+\t\tsc_flag = SC_CONTINUOUS;\n+\t\treturn 0;\n+\t} else if (!strcmp(type, \"poll_before_xmit\")) {\n+\t\tsc_flag = SC_BURST_POLL_FIRST;\n+\t\treturn 0;\n+\t} else if (!strcmp(type, \"poll_after_xmit\")) {\n+\t\tsc_flag = SC_BURST_XMIT_FIRST;\n+\t\treturn 0;\n+\t}\n+\n+\treturn -1;\n+}\n",
    "prefixes": [
        "dpdk-dev",
        "4/5"
    ]
}