get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 26476,
    "url": "http://patches.dpdk.org/api/patches/26476/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1499227716-116583-4-git-send-email-jiayu.hu@intel.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": "<1499227716-116583-4-git-send-email-jiayu.hu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1499227716-116583-4-git-send-email-jiayu.hu@intel.com",
    "date": "2017-07-05T04:08:36",
    "name": "[dpdk-dev,v11,3/3] app/testpmd: enable TCP/IPv4 GRO",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "e9480a7b827e31bca542f64527ae475ed216f02e",
    "submitter": {
        "id": 539,
        "url": "http://patches.dpdk.org/api/people/539/?format=api",
        "name": "Hu, Jiayu",
        "email": "jiayu.hu@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1499227716-116583-4-git-send-email-jiayu.hu@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/26476/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/26476/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 050F3567E;\n\tWed,  5 Jul 2017 06:07:19 +0200 (CEST)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id E325C2FDD\n\tfor <dev@dpdk.org>; Wed,  5 Jul 2017 06:07:11 +0200 (CEST)",
            "from orsmga004.jf.intel.com ([10.7.209.38])\n\tby fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t04 Jul 2017 21:07:11 -0700",
            "from dpdk15.sh.intel.com ([10.67.111.77])\n\tby orsmga004.jf.intel.com with ESMTP; 04 Jul 2017 21:07:09 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.40,310,1496127600\"; d=\"scan'208\";a=\"104515522\"",
        "From": "Jiayu Hu <jiayu.hu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "jianfeng.tan@intel.com, konstantin.ananyev@intel.com,\n\tyliu@fridaylinux.org, \n\tstephen@networkplumber.org, jingjing.wu@intel.com, lei.a.yao@intel.com,\n\tJiayu Hu <jiayu.hu@intel.com>",
        "Date": "Wed,  5 Jul 2017 12:08:36 +0800",
        "Message-Id": "<1499227716-116583-4-git-send-email-jiayu.hu@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1499227716-116583-1-git-send-email-jiayu.hu@intel.com>",
        "References": "<1498907323-17563-1-git-send-email-jiayu.hu@intel.com>\n\t<1499227716-116583-1-git-send-email-jiayu.hu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v11 3/3] app/testpmd: enable TCP/IPv4 GRO",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This patch enables TCP/IPv4 GRO library in csum forwarding engine.\nBy default, GRO is turned off. Users can use command \"gro (on|off)\n(port_id)\" to enable or disable GRO for a given port. If a port is\nenabled GRO, all TCP/IPv4 packets received from the port are performed\nGRO. Besides, users can set max flow number and packets number per-flow\nby command \"gro set (max_flow_num) (max_item_num_per_flow) (port_id)\".\n\nSigned-off-by: Jiayu Hu <jiayu.hu@intel.com>\nReviewed-by: Jingjing Wu <jingjing.wu@intel.com>\n---\n app/test-pmd/cmdline.c                      | 125 ++++++++++++++++++++++++++++\n app/test-pmd/config.c                       |  36 ++++++++\n app/test-pmd/csumonly.c                     |   5 ++\n app/test-pmd/testpmd.c                      |   3 +\n app/test-pmd/testpmd.h                      |  11 +++\n doc/guides/testpmd_app_ug/testpmd_funcs.rst |  34 ++++++++\n 6 files changed, 214 insertions(+)",
    "diff": "diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c\nindex 6789071..262d099 100644\n--- a/app/test-pmd/cmdline.c\n+++ b/app/test-pmd/cmdline.c\n@@ -76,6 +76,7 @@\n #include <rte_devargs.h>\n #include <rte_eth_ctrl.h>\n #include <rte_flow.h>\n+#include <rte_gro.h>\n \n #include <cmdline_rdline.h>\n #include <cmdline_parse.h>\n@@ -419,6 +420,14 @@ static void cmd_help_long_parsed(void *parsed_result,\n \t\t\t\"tso show (portid)\"\n \t\t\t\"    Display the status of TCP Segmentation Offload.\\n\\n\"\n \n+\t\t\t\"gro (on|off) (port_id)\"\n+\t\t\t\"    Enable or disable Generic Receive Offload in io\"\n+\t\t\t\" forward engine.\\n\\n\"\n+\n+\t\t\t\"gro set (max_flow_num) (max_item_num_per_flow) (port_id)\\n\"\n+\t\t\t\"    Set max flow number and max packet number per-flow\"\n+\t\t\t\" for GRO.\\n\\n\"\n+\n \t\t\t\"set fwd (%s)\\n\"\n \t\t\t\"    Set packet forwarding mode.\\n\\n\"\n \n@@ -3827,6 +3836,120 @@ cmdline_parse_inst_t cmd_tunnel_tso_show = {\n \t},\n };\n \n+/* *** SET GRO FOR A PORT *** */\n+struct cmd_gro_result {\n+\tcmdline_fixed_string_t cmd_keyword;\n+\tcmdline_fixed_string_t mode;\n+\tuint8_t port_id;\n+};\n+\n+static void\n+cmd_enable_gro_parsed(void *parsed_result,\n+\t\t__attribute__((unused)) struct cmdline *cl,\n+\t\t__attribute__((unused)) void *data)\n+{\n+\tstruct cmd_gro_result *res;\n+\n+\tres = parsed_result;\n+\tsetup_gro(res->mode, res->port_id);\n+}\n+\n+cmdline_parse_token_string_t cmd_gro_keyword =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_gro_result,\n+\t\t\tcmd_keyword, \"gro\");\n+cmdline_parse_token_string_t cmd_gro_mode =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_gro_result,\n+\t\t\tmode, \"on#off\");\n+cmdline_parse_token_num_t cmd_gro_pid =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_gro_result,\n+\t\t\tport_id, UINT8);\n+\n+cmdline_parse_inst_t cmd_enable_gro = {\n+\t.f = cmd_enable_gro_parsed,\n+\t.data = NULL,\n+\t.help_str = \"gro (on|off) (port_id)\",\n+\t.tokens = {\n+\t\t(void *)&cmd_gro_keyword,\n+\t\t(void *)&cmd_gro_mode,\n+\t\t(void *)&cmd_gro_pid,\n+\t\tNULL,\n+\t},\n+};\n+\n+/* *** SET MAX FLOW NUMBER AND ITEM NUM PER FLOW FOR GRO *** */\n+struct cmd_gro_set_result {\n+\tcmdline_fixed_string_t gro;\n+\tcmdline_fixed_string_t mode;\n+\tuint16_t flow_num;\n+\tuint16_t item_num_per_flow;\n+\tuint8_t port_id;\n+};\n+\n+static void\n+cmd_gro_set_parsed(void *parsed_result,\n+\t\t       __attribute__((unused)) struct cmdline *cl,\n+\t\t       __attribute__((unused)) void *data)\n+{\n+\tstruct cmd_gro_set_result *res = parsed_result;\n+\n+\tif (port_id_is_invalid(res->port_id, ENABLED_WARN))\n+\t\treturn;\n+\tif (test_done == 0) {\n+\t\tprintf(\"Before set GRO flow_num and item_num_per_flow,\"\n+\t\t\t\t\" please stop forwarding first\\n\");\n+\t\treturn;\n+\t}\n+\n+\tif (!strcmp(res->mode, \"set\")) {\n+\t\tif (res->flow_num == 0)\n+\t\t\tprintf(\"Invalid flow number. Revert to default value:\"\n+\t\t\t\t\t\" %u.\\n\", GRO_DEFAULT_FLOW_NUM);\n+\t\telse\n+\t\t\tgro_ports[res->port_id].param.max_flow_num =\n+\t\t\t\tres->flow_num;\n+\n+\t\tif (res->item_num_per_flow == 0)\n+\t\t\tprintf(\"Invalid item number per-flow. Revert\"\n+\t\t\t\t\t\" to default value:%u.\\n\",\n+\t\t\t\t\tGRO_DEFAULT_ITEM_NUM_PER_FLOW);\n+\t\telse\n+\t\t\tgro_ports[res->port_id].param.max_item_per_flow =\n+\t\t\t\tres->item_num_per_flow;\n+\t}\n+}\n+\n+cmdline_parse_token_string_t cmd_gro_set_gro =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_gro_set_result,\n+\t\t\t\tgro, \"gro\");\n+cmdline_parse_token_string_t cmd_gro_set_mode =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_gro_set_result,\n+\t\t\t\tmode, \"set\");\n+cmdline_parse_token_num_t cmd_gro_set_flow_num =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_gro_set_result,\n+\t\t\t\tflow_num, UINT16);\n+cmdline_parse_token_num_t cmd_gro_set_item_num_per_flow =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_gro_set_result,\n+\t\t\t\titem_num_per_flow, UINT16);\n+cmdline_parse_token_num_t cmd_gro_set_portid =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_gro_set_result,\n+\t\t\t\tport_id, UINT8);\n+\n+cmdline_parse_inst_t cmd_gro_set = {\n+\t.f = cmd_gro_set_parsed,\n+\t.data = NULL,\n+\t.help_str = \"gro set <max_flow_num> <max_item_num_per_flow> \"\n+\t\t\"<port_id>: set max flow number and max packet number per-flow \"\n+\t\t\"for GRO\",\n+\t.tokens = {\n+\t\t(void *)&cmd_gro_set_gro,\n+\t\t(void *)&cmd_gro_set_mode,\n+\t\t(void *)&cmd_gro_set_flow_num,\n+\t\t(void *)&cmd_gro_set_item_num_per_flow,\n+\t\t(void *)&cmd_gro_set_portid,\n+\t\tNULL,\n+\t},\n+};\n+\n /* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */\n struct cmd_set_flush_rx {\n \tcmdline_fixed_string_t set;\n@@ -13732,6 +13855,8 @@ cmdline_parse_ctx_t main_ctx[] = {\n \t(cmdline_parse_inst_t *)&cmd_tso_show,\n \t(cmdline_parse_inst_t *)&cmd_tunnel_tso_set,\n \t(cmdline_parse_inst_t *)&cmd_tunnel_tso_show,\n+\t(cmdline_parse_inst_t *)&cmd_enable_gro,\n+\t(cmdline_parse_inst_t *)&cmd_gro_set,\n \t(cmdline_parse_inst_t *)&cmd_link_flow_control_set,\n \t(cmdline_parse_inst_t *)&cmd_link_flow_control_set_rx,\n \t(cmdline_parse_inst_t *)&cmd_link_flow_control_set_tx,\ndiff --git a/app/test-pmd/config.c b/app/test-pmd/config.c\nindex b0b340e..e7d0842 100644\n--- a/app/test-pmd/config.c\n+++ b/app/test-pmd/config.c\n@@ -71,6 +71,7 @@\n #ifdef RTE_LIBRTE_BNXT_PMD\n #include <rte_pmd_bnxt.h>\n #endif\n+#include <rte_gro.h>\n \n #include \"testpmd.h\"\n \n@@ -2414,6 +2415,41 @@ set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs)\n \ttx_pkt_nb_segs = (uint8_t) nb_segs;\n }\n \n+void\n+setup_gro(const char *mode, uint8_t port_id)\n+{\n+\tif (!rte_eth_dev_is_valid_port(port_id)) {\n+\t\tprintf(\"invalid port id %u\\n\", port_id);\n+\t\treturn;\n+\t}\n+\tif (test_done == 0) {\n+\t\tprintf(\"Before enable/disable GRO,\"\n+\t\t\t\t\" please stop forwarding first\\n\");\n+\t\treturn;\n+\t}\n+\tif (strcmp(mode, \"on\") == 0) {\n+\t\tif (gro_ports[port_id].enable) {\n+\t\t\tprintf(\"port %u has enabled GRO\\n\", port_id);\n+\t\t\treturn;\n+\t\t}\n+\t\tgro_ports[port_id].enable = 1;\n+\t\tgro_ports[port_id].param.gro_types = RTE_GRO_TCP_IPV4;\n+\n+\t\tif (gro_ports[port_id].param.max_flow_num == 0)\n+\t\t\tgro_ports[port_id].param.max_flow_num =\n+\t\t\t\tGRO_DEFAULT_FLOW_NUM;\n+\t\tif (gro_ports[port_id].param.max_item_per_flow == 0)\n+\t\t\tgro_ports[port_id].param.max_item_per_flow =\n+\t\t\t\tGRO_DEFAULT_ITEM_NUM_PER_FLOW;\n+\t} else {\n+\t\tif (gro_ports[port_id].enable == 0) {\n+\t\t\tprintf(\"port %u has disabled GRO\\n\", port_id);\n+\t\t\treturn;\n+\t\t}\n+\t\tgro_ports[port_id].enable = 0;\n+\t}\n+}\n+\n char*\n list_pkt_forwarding_modes(void)\n {\ndiff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c\nindex 66fc9a0..178ad75 100644\n--- a/app/test-pmd/csumonly.c\n+++ b/app/test-pmd/csumonly.c\n@@ -71,6 +71,7 @@\n #include <rte_prefetch.h>\n #include <rte_string_fns.h>\n #include <rte_flow.h>\n+#include <rte_gro.h>\n #include \"testpmd.h\"\n \n #define IP_DEFTTL  64   /* from RFC 1340. */\n@@ -658,6 +659,10 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)\n \t\t\t\t nb_pkt_per_burst);\n \tif (unlikely(nb_rx == 0))\n \t\treturn;\n+\tif (unlikely(gro_ports[fs->rx_port].enable))\n+\t\tnb_rx = rte_gro_reassemble_burst(pkts_burst,\n+\t\t\t\tnb_rx,\n+\t\t\t\t&(gro_ports[fs->rx_port].param));\n \n #ifdef RTE_TEST_PMD_RECORD_BURST_STATS\n \tfs->rx_burst_stats.pkt_burst_spread[nb_rx]++;\ndiff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c\nindex 0a23d82..a8a6ac1 100644\n--- a/app/test-pmd/testpmd.c\n+++ b/app/test-pmd/testpmd.c\n@@ -90,6 +90,7 @@\n #ifdef RTE_LIBRTE_LATENCY_STATS\n #include <rte_latencystats.h>\n #endif\n+#include <rte_gro.h>\n \n #include \"testpmd.h\"\n \n@@ -378,6 +379,8 @@ lcoreid_t bitrate_lcore_id;\n uint8_t bitrate_enabled;\n #endif\n \n+struct gro_status gro_ports[RTE_MAX_ETHPORTS];\n+\n /* Forward function declarations */\n static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);\n static void check_all_ports_link_status(uint32_t port_mask);\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex 364502d..377d933 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -34,6 +34,8 @@\n #ifndef _TESTPMD_H_\n #define _TESTPMD_H_\n \n+#include <rte_gro.h>\n+\n #define RTE_PORT_ALL            (~(portid_t)0x0)\n \n #define RTE_TEST_RX_DESC_MAX    2048\n@@ -428,6 +430,14 @@ extern struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];\n extern uint32_t burst_tx_delay_time; /**< Burst tx delay time(us) for mac-retry. */\n extern uint32_t burst_tx_retry_num;  /**< Burst tx retry number for mac-retry. */\n \n+#define GRO_DEFAULT_FLOW_NUM 4\n+#define GRO_DEFAULT_ITEM_NUM_PER_FLOW DEF_PKT_BURST\n+struct gro_status {\n+\tstruct rte_gro_param param;\n+\tuint8_t enable;\n+};\n+extern struct gro_status gro_ports[RTE_MAX_ETHPORTS];\n+\n static inline unsigned int\n lcore_num(void)\n {\n@@ -626,6 +636,7 @@ void get_2tuple_filter(uint8_t port_id, uint16_t index);\n void get_5tuple_filter(uint8_t port_id, uint16_t index);\n int rx_queue_id_is_invalid(queueid_t rxq_id);\n int tx_queue_id_is_invalid(queueid_t txq_id);\n+void setup_gro(const char *mode, uint8_t port_id);\n \n /* Functions to manage the set of filtered Multicast MAC addresses */\n void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr);\ndiff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst\nindex 2b9a1ea..528c833 100644\n--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst\n+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst\n@@ -884,6 +884,40 @@ Display the status of TCP Segmentation Offload::\n \n    testpmd> tso show (port_id)\n \n+gro\n+~~~~~~~~\n+\n+Enable or disable GRO in ``csum`` forwarding engine::\n+\n+   testpmd> gro (on|off) (port_id)\n+\n+If enabled, the csum forwarding engine will perform GRO on the TCP/IPv4\n+packets received from the given port.\n+\n+If disabled, packets received from the given port won't be performed\n+GRO. By default, GRO is disabled for all ports.\n+\n+.. note::\n+\n+   When enable GRO for a port, TCP/IPv4 packets received from the port\n+   will be performed GRO. After GRO, the merged packets are multi-segments.\n+   But csum forwarding engine doesn't support to calculate TCP checksum\n+   for multi-segment packets in SW. So please select TCP HW checksum\n+   calculation for the port which GROed packets are transmitted to.\n+\n+gro set\n+~~~~~~~~\n+\n+Set max flow number and max packet number per-flow for GRO::\n+\n+   testpmd> gro set (max_flow_num) (max_item_num_per_flow) (port_id)\n+\n+The product of ``max_flow_num`` and ``max_item_num_per_flow`` is the max\n+number of packets a GRO table can store.\n+\n+If current packet number is greater than or equal to the max value, GRO\n+will stop processing incoming packets.\n+\n mac_addr add\n ~~~~~~~~~~~~\n \n",
    "prefixes": [
        "dpdk-dev",
        "v11",
        "3/3"
    ]
}