Show a patch.

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

{
    "id": 203,
    "url": "http://patches.dpdk.org/api/patches/203/",
    "web_url": "http://patches.dpdk.org/patch/203/",
    "project": {
        "id": 1,
        "url": "http://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-2-git-send-email-cunming.liang@intel.com>",
    "date": "2014-08-25T06:12:50",
    "name": "[dpdk-dev,1/5] app/test: unit test for rx and tx cycles/packet",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "44f163c65d9bc6a10c0b562a1f2bb3c48f1059e6",
    "submitter": {
        "id": 46,
        "url": "http://patches.dpdk.org/api/people/46/",
        "name": "Cunming Liang",
        "email": "cunming.liang@intel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/patch/203/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/203/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/203/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=\"581204286\"",
        "From": "Cunming Liang <cunming.liang@intel.com>",
        "X-List-Received-Date": "Mon, 25 Aug 2014 06:09:38 -0000",
        "X-BeenThere": "dev@dpdk.org",
        "Message-Id": "<1408947174-11323-2-git-send-email-cunming.liang@intel.com>",
        "Received": [
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby dpdk.org (Postfix) with ESMTP id 7DDA158D2\n\tfor <dev@dpdk.org>; Mon, 25 Aug 2014 08:09:37 +0200 (CEST)",
            "from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby fmsmga103.fm.intel.com with ESMTP; 24 Aug 2014 23:05:34 -0700",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby fmsmga001.fm.intel.com with ESMTP; 24 Aug 2014 23:13:28 -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 s7P6DRSD011960;\n\tMon, 25 Aug 2014 14:13:27 +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 s7P6DNvx011382; Mon, 25 Aug 2014 14:13:25 +0800",
            "(from cliang18@localhost)\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id s7P6DN1C011378; \n\tMon, 25 Aug 2014 14:13:23 +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:50 +0800",
        "Subject": "[dpdk-dev] [PATCH 1/5] app/test: unit test for rx and tx\n\tcycles/packet",
        "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>\nAcked-by: Bruce Richardson <bruce.richardson@intel.com>\n---\n app/test/Makefile                   |   1 +\n app/test/commands.c                 |  41 +++\n app/test/packet_burst_generator.c   |   4 +-\n app/test/test.h                     |   6 +\n app/test/test_pmd_perf.c            | 620 ++++++++++++++++++++++++++++++++++++\n lib/librte_pmd_ixgbe/ixgbe_ethdev.c |   6 +\n 6 files changed, 676 insertions(+), 2 deletions(-)\n create mode 100644 app/test/test_pmd_perf.c",
    "diff": "diff --git a/app/test/Makefile b/app/test/Makefile\nindex 0024737..8418b2e 100644\n--- a/app/test/Makefile\n+++ b/app/test/Makefile\n@@ -104,6 +104,7 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_distributor_perf.c\n SRCS-$(CONFIG_RTE_APP_TEST) += test_devargs.c\n SRCS-$(CONFIG_RTE_APP_TEST) += virtual_pmd.c\n SRCS-$(CONFIG_RTE_APP_TEST) += packet_burst_generator.c\n+SRCS-$(CONFIG_RTE_APP_TEST) += test_pmd_perf.c\n ifeq ($(CONFIG_RTE_APP_TEST),y)\n SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c\n SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += test_link_bonding.c\ndiff --git a/app/test/commands.c b/app/test/commands.c\nindex 5f23420..d0e583e 100644\n--- a/app/test/commands.c\n+++ b/app/test/commands.c\n@@ -204,6 +204,8 @@ static void cmd_autotest_parsed(void *parsed_result,\n \tif (!strcmp(res->autotest, \"kvargs_autotest\"))\n \t\tret |= test_kvargs();\n #endif /* RTE_LIBRTE_KVARGS */\n+\tif (!strcmp(res->autotest, \"pmd_perf_autotest\"))\n+\t\tret = test_pmd_perf();\n \n \tif (ret == 0)\n \t\tprintf(\"Test OK\\n\");\n@@ -251,6 +253,7 @@ cmdline_parse_token_string_t cmd_autotest_autotest =\n #ifdef RTE_LIBRTE_KVARGS\n \t\t\t\"kvargs_autotest#\"\n #endif\n+\t\t\t\"pmd_perf_autotest#\"\n \t\t\t\"common_autotest#\"\n \t\t\t\"distributor_autotest#distributor_perf_autotest\");\n \n@@ -451,12 +454,50 @@ 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+};\n+\n+static void cmd_set_rxtx_parsed(void *parsed_result, struct cmdline *cl,\n+\t\t\t\t__attribute__((unused)) void *data)\n+{\n+\tstruct cmd_set_rxtx_result *res = parsed_result;\n+\tif (test_set_rxtx_conf(res->mode) < 0)\n+\t\tcmdline_printf(cl, \"Cannot find such mode\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_set_rxtx_set =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, set,\n+\t\t\t\t \"set_rxtx_mode\");\n+\n+cmdline_parse_token_string_t cmd_set_rxtx_mode =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, mode, NULL);\n+\n+cmdline_parse_inst_t cmd_set_rxtx = {\n+\t.f = cmd_set_rxtx_parsed,  /* function to call */\n+\t.data = NULL,      /* 2nd arg of func */\n+\t.help_str = \"set rxtx routine: \"\n+\t\t\t\"set_rxtx <mode>\",\n+\t.tokens = {        /* token list, NULL terminated */\n+\t\t(void *)&cmd_set_rxtx_set,\n+\t\t(void *)&cmd_set_rxtx_mode,\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 \t(cmdline_parse_inst_t *)&cmd_dump_one,\n \t(cmdline_parse_inst_t *)&cmd_set_ring,\n \t(cmdline_parse_inst_t *)&cmd_quit,\n+\t(cmdline_parse_inst_t *)&cmd_set_rxtx,\n \tNULL,\n };\n \ndiff --git a/app/test/packet_burst_generator.c b/app/test/packet_burst_generator.c\nindex 5d539f1..943ea98 100644\n--- a/app/test/packet_burst_generator.c\n+++ b/app/test/packet_burst_generator.c\n@@ -190,12 +190,12 @@ initialize_ipv4_header(struct ipv4_hdr *ip_hdr, uint32_t src_addr,\n  */\n #define RTE_MAX_SEGS_PER_PKT 255 /**< pkt.nb_segs is a 8-bit unsigned char. */\n \n-#define TXONLY_DEF_PACKET_LEN 64\n+#define TXONLY_DEF_PACKET_LEN 60\n #define TXONLY_DEF_PACKET_LEN_128 128\n \n uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN;\n uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {\n-\t\tTXONLY_DEF_PACKET_LEN_128,\n+\t\tTXONLY_DEF_PACKET_LEN,\n };\n \n uint8_t  tx_pkt_nb_segs = 1;\ndiff --git a/app/test/test.h b/app/test/test.h\nindex 181c38e..ad01eec 100644\n--- a/app/test/test.h\n+++ b/app/test/test.h\n@@ -123,6 +123,9 @@ int unit_test_suite_runner(struct unit_test_suite *suite);\n \n #define RECURSIVE_ENV_VAR \"RTE_TEST_RECURSIVE\"\n \n+#include <cmdline_parse.h>\n+#include <cmdline_parse_string.h>\n+\n extern const char *prgname;\n \n int main(int argc, char **argv);\n@@ -180,6 +183,9 @@ int test_distributor_perf(void);\n int test_kvargs(void);\n int test_devargs(void);\n int test_link_bonding(void);\n+int test_pmd_perf(void);\n+int test_set_rxtx_conf(cmdline_fixed_string_t mode);\n+\n \n int test_pci_run;\n \ndiff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c\nnew file mode 100644\nindex 0000000..ee527d3\n--- /dev/null\n+++ b/app/test/test_pmd_perf.c\n@@ -0,0 +1,620 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+\n+#include <stdio.h>\n+#include <inttypes.h>\n+#include <signal.h>\n+#include <unistd.h>\n+#include <rte_cycles.h>\n+#include <rte_ethdev.h>\n+#include <rte_byteorder.h>\n+#include \"packet_burst_generator.h\"\n+#include \"test.h\"\n+\n+#define NB_ETHPORTS_USED                (1)\n+#define NB_SOCKETS                      (2)\n+#define MEMPOOL_CACHE_SIZE 250\n+#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)\n+#define MAX_PKT_BURST                   (32)\n+#define RTE_TEST_RX_DESC_DEFAULT        (128)\n+#define RTE_TEST_TX_DESC_DEFAULT        (512)\n+#define RTE_PORT_ALL            (~(uint8_t)0x0)\n+\n+/* how long test would take at full line rate */\n+#define RTE_TEST_DURATION                (2)\n+\n+/*\n+ * RX and TX Prefetch, Host, and Write-back threshold values should be\n+ * carefully set for optimal performance. Consult the network\n+ * controller's datasheet and supporting DPDK documentation for guidance\n+ * on how these parameters should be set.\n+ */\n+#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */\n+#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */\n+#define RX_WTHRESH 0 /**< Default values of RX write-back threshold reg. */\n+\n+/*\n+ * These default values are optimized for use with the Intel(R) 82599 10 GbE\n+ * Controller and the DPDK ixgbe PMD. Consider using other values for other\n+ * network controllers and/or network drivers.\n+ */\n+#define TX_PTHRESH 32 /**< Default values of TX prefetch threshold reg. */\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+\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+\n+\n+static struct rte_mempool *mbufpool[NB_SOCKETS];\n+/* ethernet addresses of ports */\n+static struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS];\n+\n+static struct rte_eth_conf port_conf = {\n+\t.rxmode = {\n+\t\t.mq_mode = ETH_MQ_RX_NONE,\n+\t\t.max_rx_pkt_len = ETHER_MAX_LEN,\n+\t\t.split_hdr_size = 0,\n+\t\t.header_split   = 0, /**< Header Split disabled */\n+\t\t.hw_ip_checksum = 0, /**< IP checksum offload enabled */\n+\t\t.hw_vlan_filter = 0, /**< VLAN filtering disabled */\n+\t\t.hw_vlan_strip  = 0, /**< VLAN strip enabled. */\n+\t\t.hw_vlan_extend = 0, /**< Extended VLAN disabled. */\n+\t\t.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */\n+\t\t.hw_strip_crc   = 0, /**< CRC stripped by hardware */\n+\t\t.enable_scatter = 0, /**< scatter rx disabled */\n+\t},\n+\t.txmode = {\n+\t\t.mq_mode = ETH_MQ_TX_NONE,\n+\t},\n+\t.lpbk_mode = 1,  /* enable loopback */\n+};\n+\n+static struct rte_eth_rxconf rx_conf = {\n+\t.rx_thresh = {\n+\t\t.pthresh = RX_PTHRESH,\n+\t\t.hthresh = RX_HTHRESH,\n+\t\t.wthresh = RX_WTHRESH,\n+\t},\n+\t.rx_free_thresh = 32,\n+};\n+\n+static struct rte_eth_txconf tx_conf = {\n+\t.tx_thresh = {\n+\t\t.pthresh = TX_PTHRESH,\n+\t\t.hthresh = TX_HTHRESH,\n+\t\t.wthresh = TX_WTHRESH,\n+\t},\n+\t.tx_free_thresh = 32, /* Use PMD default values */\n+\t.tx_rs_thresh = 32, /* Use PMD default values */\n+\t.txq_flags = (ETH_TXQ_FLAGS_NOMULTSEGS |\n+\t\t      ETH_TXQ_FLAGS_NOVLANOFFL |\n+\t\t      ETH_TXQ_FLAGS_NOXSUMSCTP |\n+\t\t      ETH_TXQ_FLAGS_NOXSUMUDP |\n+\t\t      ETH_TXQ_FLAGS_NOXSUMTCP)\n+};\n+\n+enum {\n+\tLCORE_INVALID = 0,\n+\tLCORE_AVAIL,\n+\tLCORE_USED,\n+};\n+\n+struct lcore_conf {\n+\tuint8_t status;\n+\tuint8_t socketid;\n+\tuint16_t nb_ports;\n+\tuint8_t portlist[RTE_MAX_ETHPORTS];\n+} __rte_cache_aligned;\n+\n+struct lcore_conf lcore_conf[RTE_MAX_LCORE];\n+\n+static uint64_t link_mbps;\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+{\n+#define CHECK_INTERVAL 100 /* 100ms */\n+#define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */\n+\tuint8_t portid, count, all_ports_up, print_flag = 0;\n+\tstruct rte_eth_link link;\n+\n+\tprintf(\"Checking link statuses...\\n\");\n+\tfflush(stdout);\n+\tfor (count = 0; count <= MAX_CHECK_TIME; count++) {\n+\t\tall_ports_up = 1;\n+\t\tfor (portid = 0; portid < port_num; portid++) {\n+\t\t\tif ((port_mask & (1 << portid)) == 0)\n+\t\t\t\tcontinue;\n+\t\t\tmemset(&link, 0, sizeof(link));\n+\t\t\trte_eth_link_get_nowait(portid, &link);\n+\t\t\t/* print link status if flag set */\n+\t\t\tif (print_flag == 1) {\n+\t\t\t\tif (link.link_status) {\n+\t\t\t\t\tprintf(\"Port %d Link Up - speed %u \"\n+\t\t\t\t\t\t\"Mbps - %s\\n\", (uint8_t)portid,\n+\t\t\t\t\t\t(unsigned)link.link_speed,\n+\t\t\t\t(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?\n+\t\t\t\t\t(\"full-duplex\") : (\"half-duplex\\n\"));\n+\t\t\t\t\tif (link_mbps == 0)\n+\t\t\t\t\t\tlink_mbps = link.link_speed;\n+\t\t\t\t} else\n+\t\t\t\t\tprintf(\"Port %d Link Down\\n\",\n+\t\t\t\t\t\t(uint8_t)portid);\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\t/* clear all_ports_up flag if any link down */\n+\t\t\tif (link.link_status == 0) {\n+\t\t\t\tall_ports_up = 0;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\t/* after finally printing all link status, get out */\n+\t\tif (print_flag == 1)\n+\t\t\tbreak;\n+\n+\t\tif (all_ports_up == 0) {\n+\t\t\tfflush(stdout);\n+\t\t\trte_delay_ms(CHECK_INTERVAL);\n+\t\t}\n+\n+\t\t/* set the print_flag if all ports up or timeout */\n+\t\tif (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1))\n+\t\t\tprint_flag = 1;\n+\t}\n+}\n+\n+static void\n+print_ethaddr(const char *name, const struct ether_addr *eth_addr)\n+{\n+\tprintf(\"%s%02X:%02X:%02X:%02X:%02X:%02X\", name,\n+\t\teth_addr->addr_bytes[0],\n+\t\teth_addr->addr_bytes[1],\n+\t\teth_addr->addr_bytes[2],\n+\t\teth_addr->addr_bytes[3],\n+\t\teth_addr->addr_bytes[4],\n+\t\teth_addr->addr_bytes[5]);\n+}\n+\n+static int\n+init_traffic(struct rte_mempool *mp,\n+\t     struct rte_mbuf **pkts_burst, uint32_t burst_size)\n+{\n+\tstruct ether_hdr pkt_eth_hdr;\n+\tstruct ipv4_hdr pkt_ipv4_hdr;\n+\tstruct udp_hdr pkt_udp_hdr;\n+\tuint32_t pktlen;\n+\tstatic uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };\n+\tstatic uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };\n+\n+\n+\tinitialize_eth_header(&pkt_eth_hdr,\n+\t\t(struct ether_addr *)src_mac,\n+\t\t(struct ether_addr *)dst_mac, 0, 0);\n+\tpkt_eth_hdr.ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);\n+\n+\tpktlen = initialize_ipv4_header(&pkt_ipv4_hdr,\n+\t\t\t\t\tIPV4_ADDR(10, 0, 0, 1),\n+\t\t\t\t\tIPV4_ADDR(10, 0, 0, 2), 26);\n+\tprintf(\"IPv4 pktlen %u\\n\", pktlen);\n+\n+\tpktlen = initialize_udp_header(&pkt_udp_hdr, 0, 0, 18);\n+\n+\tprintf(\"UDP pktlen %u\\n\", pktlen);\n+\n+\treturn generate_packet_burst(mp, pkts_burst, &pkt_eth_hdr,\n+\t\t\t\t     0, &pkt_ipv4_hdr, 1,\n+\t\t\t\t     &pkt_udp_hdr, burst_size);\n+}\n+\n+static int\n+init_lcores(void)\n+{\n+\tunsigned lcore_id;\n+\n+\tfor (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {\n+\t\tlcore_conf[lcore_id].socketid =\n+\t\t\trte_lcore_to_socket_id(lcore_id);\n+\t\tif (rte_lcore_is_enabled(lcore_id) == 0) {\n+\t\t\tlcore_conf[lcore_id].status = LCORE_INVALID;\n+\t\t\tcontinue;\n+\t\t} else\n+\t\t\tlcore_conf[lcore_id].status = LCORE_AVAIL;\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+init_mbufpool(unsigned nb_mbuf)\n+{\n+\tint socketid;\n+\tunsigned lcore_id;\n+\tchar s[64];\n+\n+\tfor (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {\n+\t\tif (rte_lcore_is_enabled(lcore_id) == 0)\n+\t\t\tcontinue;\n+\n+\t\tsocketid = rte_lcore_to_socket_id(lcore_id);\n+\t\tif (socketid >= NB_SOCKETS) {\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\"Socket %d of lcore %u is out of range %d\\n\",\n+\t\t\t\tsocketid, lcore_id, NB_SOCKETS);\n+\t\t}\n+\t\tif (mbufpool[socketid] == NULL) {\n+\t\t\tsnprintf(s, sizeof(s), \"mbuf_pool_%d\", socketid);\n+\t\t\tmbufpool[socketid] =\n+\t\t\t\trte_mempool_create(s, nb_mbuf, MBUF_SIZE,\n+\t\t\t\t\tMEMPOOL_CACHE_SIZE,\n+\t\t\t\t\tsizeof(struct rte_pktmbuf_pool_private),\n+\t\t\t\t\trte_pktmbuf_pool_init, NULL,\n+\t\t\t\t\trte_pktmbuf_init, NULL,\n+\t\t\t\t\tsocketid, 0);\n+\t\t\tif (mbufpool[socketid] == NULL)\n+\t\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\t\"Cannot init mbuf pool on socket %d\\n\",\n+\t\t\t\t\tsocketid);\n+\t\t\telse\n+\t\t\t\tprintf(\"Allocated mbuf pool on socket %d\\n\",\n+\t\t\t\t\tsocketid);\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+static uint16_t\n+alloc_lcore(uint16_t socketid)\n+{\n+\tunsigned lcore_id;\n+\n+\tfor (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {\n+\t\tif (LCORE_AVAIL != lcore_conf[lcore_id].status ||\n+\t\t    lcore_conf[lcore_id].socketid != socketid ||\n+\t\t    lcore_id == rte_get_master_lcore())\n+\t\t\tcontinue;\n+\t\tlcore_conf[lcore_id].status = LCORE_USED;\n+\t\tlcore_conf[lcore_id].nb_ports = 0;\n+\t\treturn lcore_id;\n+\t}\n+\n+\treturn (uint16_t)-1;\n+}\n+\n+volatile uint64_t stop;\n+uint64_t count;\n+uint64_t drop;\n+uint64_t idle;\n+\n+static void\n+reset_count(void)\n+{\n+\tcount = 0;\n+\tdrop = 0;\n+\tidle = 0;\n+}\n+\n+static void\n+stats_display(uint8_t port_id)\n+{\n+\tstruct rte_eth_stats stats;\n+\trte_eth_stats_get(port_id, &stats);\n+\n+\tprintf(\"  RX-packets: %-10\"PRIu64\" RX-missed: %-10\"PRIu64\" RX-bytes:  \"\n+\t       \"%-\"PRIu64\"\\n\",\n+\t       stats.ipackets, stats.imissed, stats.ibytes);\n+\tprintf(\"  RX-badcrc:  %-10\"PRIu64\" RX-badlen: %-10\"PRIu64\" RX-errors: \"\n+\t       \"%-\"PRIu64\"\\n\",\n+\t       stats.ibadcrc, stats.ibadlen, stats.ierrors);\n+\tprintf(\"  RX-nombuf:  %-10\"PRIu64\"\\n\",\n+\t       stats.rx_nombuf);\n+\tprintf(\"  TX-packets: %-10\"PRIu64\" TX-errors: %-10\"PRIu64\" TX-bytes:  \"\n+\t       \"%-\"PRIu64\"\\n\",\n+\t       stats.opackets, stats.oerrors, stats.obytes);\n+}\n+\n+static void\n+signal_handler(int signum)\n+{\n+\t/* When we receive a USR1 signal, print stats */\n+\tif (signum == SIGUSR1) {\n+\t\tprintf(\"Force Stop!\\n\");\n+\t\tstop = 1;\n+\t}\n+\tif (signum == SIGUSR2)\n+\t\tstats_display(0);\n+}\n+\n+#define MAX_TRAFIC_BURST                (4096)\n+struct rte_mbuf *tx_burst[MAX_TRAFIC_BURST];\n+\n+/* main processing loop */\n+static int\n+main_loop(__rte_unused void *args)\n+{\n+#define PACKET_SIZE 64\n+#define FRAME_GAP 12\n+#define MAC_PREAMBLE 8\n+\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST];\n+\tunsigned lcore_id;\n+\tunsigned i, portid, nb_rx = 0, nb_tx = 0;\n+\tstruct lcore_conf *conf;\n+\tuint64_t prev_tsc, cur_tsc;\n+\tint pkt_per_port;\n+\tuint64_t packets_per_second, total_packets;\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+\tpkt_per_port =  MAX_TRAFIC_BURST / conf->nb_ports;\n+\n+\tint idx = 0;\n+\tfor (i = 0; i < conf->nb_ports; i++) {\n+\t\tint num = pkt_per_port;\n+\t\tportid = conf->portlist[i];\n+\t\tprintf(\"inject %d packet to port %d\\n\", num, portid);\n+\t\twhile (num) {\n+\t\t\tnb_tx = RTE_MIN(MAX_PKT_BURST, num);\n+\t\t\tnb_tx = rte_eth_tx_burst(portid, 0,\n+\t\t\t\t\t\t&tx_burst[idx], nb_tx);\n+\t\t\tnum -= nb_tx;\n+\t\t\tidx += nb_tx;\n+\t\t}\n+\t}\n+\tprintf(\"Total packets inject to prime ports = %u\\n\", idx);\n+\n+\tpackets_per_second = (link_mbps * 1000 * 1000) /\n+\t\t+((PACKET_SIZE + FRAME_GAP + MAC_PREAMBLE) * CHAR_BIT);\n+\tprintf(\"Each port will do %\"PRIu64\" packets per second\\n\",\n+\t\t+packets_per_second);\n+\n+\ttotal_packets = RTE_TEST_DURATION * conf->nb_ports * packets_per_second;\n+\tprintf(\"Test will stop after at least %\"PRIu64\" packets received\\n\",\n+\t\t+ total_packets);\n+\n+\tprev_tsc = rte_rdtsc();\n+\n+\twhile (likely(!stop)) {\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, MAX_PKT_BURST);\n+\t\t\tif (unlikely(nb_rx == 0)) {\n+\t\t\t\tidle++;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tcount += nb_rx;\n+\t\t\tnb_tx = rte_eth_tx_burst(portid, 0, pkts_burst, nb_rx);\n+\t\t\tif (unlikely(nb_tx < nb_rx)) {\n+\t\t\t\tdrop += (nb_rx - nb_tx);\n+\t\t\t\tdo {\n+\t\t\t\t\trte_pktmbuf_free(pkts_burst[nb_tx]);\n+\t\t\t\t} while (++nb_tx < nb_rx);\n+\t\t\t}\n+\t\t}\n+\t\tif (unlikely(count >= total_packets))\n+\t\t\tbreak;\n+\t}\n+\n+\tcur_tsc = rte_rdtsc();\n+\n+\tfor (i = 0; i < conf->nb_ports; i++) {\n+\t\tportid = conf->portlist[i];\n+\t\tint nb_free = pkt_per_port;\n+\t\tdo { /* dry out */\n+\t\t\tnb_rx = rte_eth_rx_burst((uint8_t) portid, 0,\n+\t\t\t\t\t\t pkts_burst, MAX_PKT_BURST);\n+\t\t\tnb_tx = 0;\n+\t\t\twhile (nb_tx < nb_rx)\n+\t\t\t\trte_pktmbuf_free(pkts_burst[nb_tx++]);\n+\t\t\tnb_free -= nb_rx;\n+\t\t} while (nb_free != 0);\n+\t\tprintf(\"free %d mbuf left in port %u\\n\", pkt_per_port, portid);\n+\t}\n+\n+\tif (count == 0)\n+\t\treturn -1;\n+\n+\tprintf(\"%lu packet, %lu drop, %lu idle\\n\", count, drop, idle);\n+\tprintf(\"Result: %ld cycles per packet\\n\", (cur_tsc - prev_tsc) / count);\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 portid;\n+\tuint16_t nb_rx_queue = 1, nb_tx_queue = 1;\n+\tint socketid = -1;\n+\tint ret;\n+\n+\tprintf(\"Start PMD RXTX cycles cost test.\\n\");\n+\n+\tsignal(SIGUSR1, signal_handler);\n+\tsignal(SIGUSR2, signal_handler);\n+\n+\tnb_ports = rte_eth_dev_count();\n+\tif (nb_ports < NB_ETHPORTS_USED) {\n+\t\tprintf(\"At least %u port(s) used for perf. test\\n\",\n+\t\t       NB_ETHPORTS_USED);\n+\t\treturn -1;\n+\t}\n+\n+\tif (nb_ports > RTE_MAX_ETHPORTS)\n+\t\tnb_ports = RTE_MAX_ETHPORTS;\n+\n+\tnb_lcores = rte_lcore_count();\n+\n+\tmemset(lcore_conf, 0, sizeof(lcore_conf));\n+\tinit_lcores();\n+\n+\tinit_mbufpool(NB_MBUF);\n+\n+\treset_count();\n+\tnum = 0;\n+\tfor (portid = 0; portid < nb_ports; portid++) {\n+\t\tif (socketid == -1) {\n+\t\t\tsocketid = rte_eth_dev_socket_id(portid);\n+\t\t\tslave_id = alloc_lcore(socketid);\n+\t\t\tif (slave_id == (uint16_t)-1) {\n+\t\t\t\tprintf(\"No avail lcore to run test\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tprintf(\"Performance test runs on lcore %u socket %u\\n\",\n+\t\t\t       slave_id, socketid);\n+\t\t}\n+\n+\t\tif (socketid != rte_eth_dev_socket_id(portid)) {\n+\t\t\tprintf(\"Skip port %d\\n\", portid);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* port configure */\n+\t\tret = rte_eth_dev_configure(portid, nb_rx_queue,\n+\t\t\t\t\t    nb_tx_queue, &port_conf);\n+\t\tif (ret < 0)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\"Cannot configure device: err=%d, port=%d\\n\",\n+\t\t\t\t ret, portid);\n+\n+\t\trte_eth_macaddr_get(portid, &ports_eth_addr[portid]);\n+\t\tprintf(\"Port %u \", portid);\n+\t\tprint_ethaddr(\"Address:\", &ports_eth_addr[portid]);\n+\t\tprintf(\"\\n\");\n+\n+\t\t/* tx queue setup */\n+\t\tret = rte_eth_tx_queue_setup(portid, 0, nb_txd,\n+\t\t\t\t\t     socketid, &tx_conf);\n+\t\tif (ret < 0)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\"rte_eth_tx_queue_setup: err=%d, \"\n+\t\t\t\t\"port=%d\\n\", ret, portid);\n+\n+\t\t/* rx queue steup */\n+\t\tret = rte_eth_rx_queue_setup(portid, 0, nb_rxd,\n+\t\t\t\t\t\tsocketid, &rx_conf,\n+\t\t\t\t\t\tmbufpool[socketid]);\n+\t\tif (ret < 0)\n+\t\t\trte_exit(EXIT_FAILURE, \"rte_eth_rx_queue_setup: err=%d,\"\n+\t\t\t\t \"port=%d\\n\", ret, portid);\n+\n+\t\t/* Start device */\n+\t\tstop = 0;\n+\t\tret = rte_eth_dev_start(portid);\n+\t\tif (ret < 0)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\"rte_eth_dev_start: err=%d, port=%d\\n\",\n+\t\t\t\tret, portid);\n+\n+\t\t/* always eanble promiscuous */\n+\t\trte_eth_promiscuous_enable(portid);\n+\n+\t\tlcore_conf[slave_id].portlist[num++] = portid;\n+\t\tlcore_conf[slave_id].nb_ports++;\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+\n+\trte_eal_remote_launch(main_loop, NULL, slave_id);\n+\tif (rte_eal_wait_lcore(slave_id) < 0)\n+\t\treturn -1;\n+\n+\t/* port tear down */\n+\tfor (portid = 0; portid < nb_ports; portid++) {\n+\t\tif (socketid != rte_eth_dev_socket_id(portid))\n+\t\t\tcontinue;\n+\n+\t\trte_eth_dev_stop(portid);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+test_set_rxtx_conf(cmdline_fixed_string_t mode)\n+{\n+\tprintf(\"mode is %s\\n\", mode);\n+\n+\tif (!strcmp(mode, \"vector\")) {\n+\t\t/* vector rx, tx */\n+\t\ttx_conf.txq_flags = 0xf01;\n+\t\ttx_conf.tx_rs_thresh = 32;\n+\t\ttx_conf.tx_free_thresh = 32;\n+\t\tport_conf.rxmode.hw_ip_checksum = 0;\n+\t\tport_conf.rxmode.enable_scatter = 0;\n+\t\treturn 0;\n+\t} else if (!strcmp(mode, \"scalar\")) {\n+\t\t/* bulk alloc rx, simple tx */\n+\t\ttx_conf.txq_flags = 0xf01;\n+\t\ttx_conf.tx_rs_thresh = 128;\n+\t\ttx_conf.tx_free_thresh = 128;\n+\t\tport_conf.rxmode.hw_ip_checksum = 1;\n+\t\tport_conf.rxmode.enable_scatter = 0;\n+\t\treturn 0;\n+\t} else if (!strcmp(mode, \"hybrid\")) {\n+\t\t/* bulk alloc rx, vector tx\n+\t\t * when vec macro not define,\n+\t\t * using the same rx/tx as scalar\n+\t\t */\n+\t\ttx_conf.txq_flags = 0xf01;\n+\t\ttx_conf.tx_rs_thresh = 32;\n+\t\ttx_conf.tx_free_thresh = 32;\n+\t\tport_conf.rxmode.hw_ip_checksum = 1;\n+\t\tport_conf.rxmode.enable_scatter = 0;\n+\t\treturn 0;\n+\t} else if (!strcmp(mode, \"full\")) {\n+\t\t/* full feature rx,tx pair */\n+\t\ttx_conf.txq_flags = 0x0;   /* must condition */\n+\t\ttx_conf.tx_rs_thresh = 32;\n+\t\ttx_conf.tx_free_thresh = 32;\n+\t\tport_conf.rxmode.hw_ip_checksum = 0;\n+\t\tport_conf.rxmode.enable_scatter = 1; /* must condition */\n+\t\treturn 0;\n+\t}\n+\n+\treturn -1;\n+}\ndiff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\nindex 59122a1..c581dbf 100644\n--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\n+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c\n@@ -1582,6 +1582,9 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)\n \n \tixgbe_dev_clear_queues(dev);\n \n+\t/* Clear stored conf */\n+\tdev->data->scattered_rx = 0;\n+\n \t/* Clear recorded link status */\n \tmemset(&link, 0, sizeof(link));\n \trte_ixgbe_dev_atomic_write_link_status(dev, &link);\n@@ -2853,6 +2856,9 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev)\n \t  */\n \tixgbevf_set_vfta_all(dev,0);\n \n+\t/* Clear stored conf */\n+\tdev->data->scattered_rx = 0;\n+\n \tixgbe_dev_clear_queues(dev);\n }\n \n",
    "prefixes": [
        "dpdk-dev",
        "1/5"
    ]
}