From patchwork Mon Aug 25 06:12:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cunming Liang X-Patchwork-Id: 207 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 7F700B379 for ; Mon, 25 Aug 2014 08:10:07 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 24 Aug 2014 23:13:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.04,395,1406617200"; d="scan'208";a="581204318" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga001.fm.intel.com with ESMTP; 24 Aug 2014 23:13:41 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id s7P6Def9012314; Mon, 25 Aug 2014 14:13:40 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id s7P6DaZ7011403; Mon, 25 Aug 2014 14:13:38 +0800 Received: (from cliang18@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id s7P6DaHD011399; Mon, 25 Aug 2014 14:13:36 +0800 From: Cunming Liang To: dev@dpdk.org Date: Mon, 25 Aug 2014 14:12:53 +0800 Message-Id: <1408947174-11323-5-git-send-email-cunming.liang@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <1408947174-11323-1-git-send-email-cunming.liang@intel.com> References: <1408947174-11323-1-git-send-email-cunming.liang@intel.com> Subject: [dpdk-dev] [PATCH 4/5] app/test: add unit test to measure RX burst cycles X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Aug 2014 06:10:08 -0000 Signed-off-by: Cunming Liang --- app/test/commands.c | 43 +++++++++- app/test/test.h | 1 + app/test/test_pmd_perf.c | 214 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 237 insertions(+), 21 deletions(-) diff --git a/app/test/commands.c b/app/test/commands.c index 8721e25..f222398 100644 --- a/app/test/commands.c +++ b/app/test/commands.c @@ -454,8 +454,6 @@ cmdline_parse_inst_t cmd_quit = { /****************/ -/****************/ - struct cmd_set_rxtx_result { cmdline_fixed_string_t set; cmdline_fixed_string_t mode; @@ -490,8 +488,6 @@ cmdline_parse_inst_t cmd_set_rxtx = { /****************/ -/****************/ - struct cmd_set_rxtx_anchor { cmdline_fixed_string_t set; cmdline_fixed_string_t type; @@ -528,6 +524,44 @@ cmdline_parse_inst_t cmd_set_rxtx_anchor = { /****************/ +/* for stream control */ +struct cmd_set_rxtx_sc { + cmdline_fixed_string_t set; + cmdline_fixed_string_t type; +}; + +static void +cmd_set_rxtx_sc_parsed(void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_rxtx_sc *res = parsed_result; + if (test_set_rxtx_sc(res->type) < 0) + cmdline_printf(cl, "Cannot find such stream control\n"); +} + +cmdline_parse_token_string_t cmd_set_rxtx_sc_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, set, + "set_rxtx_sc"); + +cmdline_parse_token_string_t cmd_set_rxtx_sc_type = + TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, type, NULL); + +cmdline_parse_inst_t cmd_set_rxtx_sc = { + .f = cmd_set_rxtx_sc_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = "set rxtx stream control: " + "set_rxtx_sc ", + .tokens = { /* token list, NULL terminated */ + (void *)&cmd_set_rxtx_sc_set, + (void *)&cmd_set_rxtx_sc_type, + NULL, + }, +}; + +/****************/ + + cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_autotest, (cmdline_parse_inst_t *)&cmd_dump, @@ -536,6 +570,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_quit, (cmdline_parse_inst_t *)&cmd_set_rxtx, (cmdline_parse_inst_t *)&cmd_set_rxtx_anchor, + (cmdline_parse_inst_t *)&cmd_set_rxtx_sc, NULL, }; diff --git a/app/test/test.h b/app/test/test.h index c24ce9f..4c10afe 100644 --- a/app/test/test.h +++ b/app/test/test.h @@ -186,6 +186,7 @@ int test_link_bonding(void); int test_pmd_perf(void); int test_set_rxtx_conf(cmdline_fixed_string_t mode); int test_set_rxtx_anchor(cmdline_fixed_string_t type); +int test_set_rxtx_sc(cmdline_fixed_string_t type); int test_pci_run; diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c index 5d02fac..e11fa41 100644 --- a/app/test/test_pmd_perf.c +++ b/app/test/test_pmd_perf.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include "packet_burst_generator.h" #include "test.h" @@ -73,13 +75,15 @@ #define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ #define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ +#define MAX_TRAFFIC_BURST 2048 #define NB_MBUF RTE_MAX( \ - (unsigned)(nb_ports*nb_rx_queue*RTE_TEST_RX_DESC_DEFAULT + \ - nb_ports*nb_lcores*MAX_PKT_BURST + \ - nb_ports*nb_tx_queue*RTE_TEST_TX_DESC_DEFAULT + \ - nb_lcores*MEMPOOL_CACHE_SIZE), \ - (unsigned)8192) + (unsigned)(nb_ports*nb_rx_queue*nb_rxd + \ + nb_ports*nb_lcores*MAX_PKT_BURST + \ + nb_ports*nb_tx_queue*nb_txd + \ + nb_lcores*MEMPOOL_CACHE_SIZE + \ + nb_ports*MAX_TRAFFIC_BURST), \ + (unsigned)8192) static struct rte_mempool *mbufpool[NB_SOCKETS]; @@ -147,6 +151,14 @@ struct lcore_conf lcore_conf[RTE_MAX_LCORE]; static uint64_t link_mbps; +enum { + SC_CONTINUOUS = 0, + SC_BURST_POLL_FIRST, + SC_BURST_XMIT_FIRST, +}; + +static uint32_t sc_flag; + /* Check the link status of all ports in up to 3s, and print them finally */ static void check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) @@ -361,8 +373,7 @@ signal_handler(int signum) stats_display(0); } -#define MAX_TRAFIC_BURST (4096) -struct rte_mbuf *tx_burst[MAX_TRAFIC_BURST]; +struct rte_mbuf **tx_burst; uint64_t (*do_measure)(struct lcore_conf *conf, struct rte_mbuf *pkts_burst[], @@ -503,7 +514,7 @@ main_loop(__rte_unused void *args) if (conf->status != LCORE_USED) return 0; - pkt_per_port = MAX_TRAFIC_BURST / conf->nb_ports; + pkt_per_port = MAX_TRAFFIC_BURST; int idx = 0; for (i = 0; i < conf->nb_ports; i++) { @@ -554,12 +565,137 @@ main_loop(__rte_unused void *args) return 0; } +rte_atomic64_t start; + +/* main processing loop */ +static inline int +poll_burst(void *args) +{ +#define MAX_IDLE (1000) + unsigned lcore_id; + struct rte_mbuf **pkts_burst; + uint64_t diff_tsc, cur_tsc; + uint16_t next[RTE_MAX_ETHPORTS]; + struct lcore_conf *conf; + uint32_t pkt_per_port = *((uint32_t *)args); + unsigned i, portid, nb_rx = 0; + uint64_t total; + uint64_t timeout = MAX_IDLE; + + lcore_id = rte_lcore_id(); + conf = &lcore_conf[lcore_id]; + if (conf->status != LCORE_USED) + return 0; + + total = pkt_per_port * conf->nb_ports; + printf("start to receive total expect %ld\n", total); + + pkts_burst = (struct rte_mbuf **) + rte_calloc_socket("poll_burst", + total, sizeof(void *), + CACHE_LINE_SIZE, conf->socketid); + if (!pkts_burst) + return -1; + + for (i = 0; i < conf->nb_ports; i++) { + portid = conf->portlist[i]; + next[portid] = i * pkt_per_port; + } + + while (!rte_atomic64_read(&start)) + ; + + cur_tsc = rte_rdtsc(); + while (total) { + for (i = 0; i < conf->nb_ports; i++) { + portid = conf->portlist[i]; + nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, + &pkts_burst[next[portid]], + MAX_PKT_BURST); + if (unlikely(nb_rx == 0)) { + timeout--; + if (unlikely(timeout == 0)) + goto timeout; + continue; + } + next[portid] += nb_rx; + total -= nb_rx; + } + } +timeout: + diff_tsc = rte_rdtsc() - cur_tsc; + + printf("%ld packets lost, IDLE %ld times\n", total, MAX_IDLE - timeout); + + /* clean up */ + total = pkt_per_port * conf->nb_ports - total; + for (i = 0; i < total; i++) + rte_pktmbuf_free(pkts_burst[i]); + + rte_free(pkts_burst); + + return diff_tsc / total; +} + +/* main processing loop */ +static int +exec_burst(uint32_t flags, int lcore) +{ + unsigned i, portid, nb_tx = 0; + struct lcore_conf *conf; + uint32_t pkt_per_port; + int num, idx = 0; + int diff_tsc; + + conf = &lcore_conf[lcore]; + + pkt_per_port = MAX_TRAFFIC_BURST; + num = pkt_per_port; + + rte_atomic64_init(&start); + + /* start polling thread, but not actually poll yet */ + rte_eal_remote_launch(poll_burst, + (void *)&pkt_per_port, lcore); + + /* Only when polling first */ + if (flags == SC_BURST_POLL_FIRST) + rte_atomic64_set(&start, 1); + + /* start xmit */ + while (num) { + nb_tx = RTE_MIN(MAX_PKT_BURST, num); + for (i = 0; i < conf->nb_ports; i++) { + portid = conf->portlist[i]; + rte_eth_tx_burst(portid, 0, + &tx_burst[idx], nb_tx); + idx += nb_tx; + } + num -= nb_tx; + } + + sleep(5); + + /* only when polling second */ + if (flags == SC_BURST_XMIT_FIRST) + rte_atomic64_set(&start, 1); + + /* wait for polling finished */ + diff_tsc = rte_eal_wait_lcore(lcore); + if (diff_tsc < 0) + return -1; + + printf("Result: %d cycles per packet\n", diff_tsc); + + return 0; +} + int test_pmd_perf(void) { uint16_t nb_ports, num, nb_lcores, slave_id = (uint16_t)-1; - uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; - uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; + uint16_t nb_rxd = MAX_TRAFFIC_BURST; + uint16_t nb_txd = MAX_TRAFFIC_BURST; uint16_t portid; uint16_t nb_rx_queue = 1, nb_tx_queue = 1; int socketid = -1; @@ -587,6 +723,12 @@ test_pmd_perf(void) init_mbufpool(NB_MBUF); + if (sc_flag == SC_CONTINUOUS) { + nb_rxd = RTE_TEST_RX_DESC_DEFAULT; + nb_txd = RTE_TEST_TX_DESC_DEFAULT; + } + printf("CONFIG RXD=%d TXD=%d\n", nb_rxd, nb_txd); + reset_count(); num = 0; for (portid = 0; portid < nb_ports; portid++) { @@ -651,15 +793,34 @@ test_pmd_perf(void) } check_all_ports_link_status(nb_ports, RTE_PORT_ALL); - init_traffic(mbufpool[socketid], tx_burst, MAX_TRAFIC_BURST); + if (tx_burst == NULL) { + tx_burst = (struct rte_mbuf **) + rte_calloc_socket("tx_buff", + MAX_TRAFFIC_BURST * nb_ports, + sizeof(void *), + CACHE_LINE_SIZE, socketid); + if (!tx_burst) + return -1; + } - /* do both rxtx by default */ - if (NULL == do_measure) - do_measure = measure_rxtx; + init_traffic(mbufpool[socketid], + tx_burst, MAX_TRAFFIC_BURST * nb_ports); - rte_eal_remote_launch(main_loop, NULL, slave_id); - if (rte_eal_wait_lcore(slave_id) < 0) - return -1; + printf("Generate %d packets @socket %d\n", + MAX_TRAFFIC_BURST * nb_ports, socketid); + + if (sc_flag == SC_CONTINUOUS) { + /* do both rxtx by default */ + if (NULL == do_measure) + do_measure = measure_rxtx; + + rte_eal_remote_launch(main_loop, NULL, slave_id); + + if (rte_eal_wait_lcore(slave_id) < 0) + return -1; + } else if (sc_flag == SC_BURST_POLL_FIRST || + sc_flag == SC_BURST_XMIT_FIRST) + exec_burst(sc_flag, slave_id); /* port tear down */ for (portid = 0; portid < nb_ports; portid++) { @@ -735,3 +896,22 @@ test_set_rxtx_anchor(cmdline_fixed_string_t type) return -1; } + +int +test_set_rxtx_sc(cmdline_fixed_string_t type) +{ + printf("stream control switch to %s\n", type); + + if (!strcmp(type, "continuous")) { + sc_flag = SC_CONTINUOUS; + return 0; + } else if (!strcmp(type, "poll_before_xmit")) { + sc_flag = SC_BURST_POLL_FIRST; + return 0; + } else if (!strcmp(type, "poll_after_xmit")) { + sc_flag = SC_BURST_XMIT_FIRST; + return 0; + } + + return -1; +}