get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 1248,
    "url": "https://patches.dpdk.org/api/patches/1248/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1415635166-1364-12-git-send-email-olivier.matz@6wind.com/",
    "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",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1415635166-1364-12-git-send-email-olivier.matz@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1415635166-1364-12-git-send-email-olivier.matz@6wind.com",
    "date": "2014-11-10T15:59:25",
    "name": "[dpdk-dev,11/12] testpmd: support TSO in csum forward engine",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "7834c8c8f66bc1248c559cc25484c2f51df59ec1",
    "submitter": {
        "id": 8,
        "url": "https://patches.dpdk.org/api/people/8/?format=api",
        "name": "Olivier Matz",
        "email": "olivier.matz@6wind.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1415635166-1364-12-git-send-email-olivier.matz@6wind.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/1248/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/1248/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 D96CC7FA8;\n\tMon, 10 Nov 2014 16:50:32 +0100 (CET)",
            "from mail-wg0-f49.google.com (mail-wg0-f49.google.com\n\t[74.125.82.49]) by dpdk.org (Postfix) with ESMTP id 09A3D7F80\n\tfor <dev@dpdk.org>; Mon, 10 Nov 2014 16:50:21 +0100 (CET)",
            "by mail-wg0-f49.google.com with SMTP id x13so9316105wgg.8\n\tfor <dev@dpdk.org>; Mon, 10 Nov 2014 08:00:03 -0800 (PST)",
            "from glumotte.dev.6wind.com (guy78-3-82-239-227-177.fbx.proxad.net.\n\t[82.239.227.177]) by mx.google.com with ESMTPSA id\n\tll2sm10966561wjb.11.2014.11.10.08.00.01 for <multiple recipients>\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tMon, 10 Nov 2014 08:00:03 -0800 (PST)"
        ],
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=mD8KkiOZpT1TVpztA37z9/QEb0ZSDzKoUHUT0z8Uf9c=;\n\tb=S0IIiCx4hvniPMPcV1B3HE7x/D/8JsndJQHqy1eLJRU01+uvEv7c1YEytg+gsd/0CL\n\tw4/0ZXocet/iVgD9ux3xgUsv9CZtCaswhNJOrT7D1WyFS4+witvCMV/dChYqRbo5ggjo\n\tbxZ+451dkzYqzIVN4BLmO5esnz2XUFM6vLBf7bJYiv3vVaNStnZ+z64J74+7wBPyMrtD\n\tRBCBmx/QFObV/xId8mPkl1y6SyQWUrS9hgCK0OblkX53nRh3MkC3OOQ7sKsvmILLFi/K\n\tuFhM4RB+M4LdZXD/yW6svpNiQ70ycMlM0tFasHjOh+MoQoqdNIto3ZMPKFDSK4Zrf62i\n\tFRMA==",
        "X-Gm-Message-State": "ALoCoQlLjhdSsZyyuwfE/KqsShQiQSSaEahTvUSeUgAdR5JCcK/sVq0m9smWRm3LnQGwNU5bk6Bw",
        "X-Received": "by 10.194.63.145 with SMTP id g17mr45594577wjs.80.1415635203524; \n\tMon, 10 Nov 2014 08:00:03 -0800 (PST)",
        "From": "Olivier Matz <olivier.matz@6wind.com>",
        "To": "dev@dpdk.org",
        "Date": "Mon, 10 Nov 2014 16:59:25 +0100",
        "Message-Id": "<1415635166-1364-12-git-send-email-olivier.matz@6wind.com>",
        "X-Mailer": "git-send-email 2.1.0",
        "In-Reply-To": "<1415635166-1364-1-git-send-email-olivier.matz@6wind.com>",
        "References": "<1415635166-1364-1-git-send-email-olivier.matz@6wind.com>",
        "Cc": "jigsaw@gmail.com",
        "Subject": "[dpdk-dev] [PATCH 11/12] testpmd: support TSO in csum forward engine",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <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": "Add two new commands in testpmd:\n\n- tso set <segsize> <portid>\n- tso show <portid>\n\nThese commands can be used enable TSO when transmitting TCP packets in\nthe csum forward engine. Ex:\n\n  set fwd csum\n  tx_checksum set ip hw 0\n  tso set 800 0\n  start\n\nSigned-off-by: Olivier Matz <olivier.matz@6wind.com>\n---\n app/test-pmd/cmdline.c  | 92 +++++++++++++++++++++++++++++++++++++++++++++++++\n app/test-pmd/csumonly.c | 53 +++++++++++++++++++++-------\n app/test-pmd/testpmd.h  |  1 +\n 3 files changed, 133 insertions(+), 13 deletions(-)",
    "diff": "diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c\nindex 0361e58..5460415 100644\n--- a/app/test-pmd/cmdline.c\n+++ b/app/test-pmd/cmdline.c\n@@ -318,6 +318,14 @@ static void cmd_help_long_parsed(void *parsed_result,\n \t\t\t\"tx_checksum show (port_id)\\n\"\n \t\t\t\"    Display tx checksum offload configuration\\n\\n\"\n \n+\t\t\t\"tso set (segsize) (portid)\\n\"\n+\t\t\t\"    Enable TCP Segmentation Offload in csum forward\"\n+\t\t\t\" engine.\\n\"\n+\t\t\t\"    Please check the NIC datasheet for HW limits.\\n\\n\"\n+\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\"set fwd (%s)\\n\"\n \t\t\t\"    Set packet forwarding mode.\\n\\n\"\n \n@@ -2862,6 +2870,88 @@ cmdline_parse_inst_t cmd_tx_cksum_show = {\n \t},\n };\n \n+/* *** ENABLE HARDWARE SEGMENTATION IN TX PACKETS *** */\n+struct cmd_tso_set_result {\n+\tcmdline_fixed_string_t tso;\n+\tcmdline_fixed_string_t mode;\n+\tuint16_t tso_segsz;\n+\tuint8_t port_id;\n+};\n+\n+static void\n+cmd_tso_set_parsed(void *parsed_result,\n+\t\t       __attribute__((unused)) struct cmdline *cl,\n+\t\t       __attribute__((unused)) void *data)\n+{\n+\tstruct cmd_tso_set_result *res = parsed_result;\n+\tstruct rte_eth_dev_info dev_info;\n+\n+\tif (port_id_is_invalid(res->port_id))\n+\t\treturn;\n+\n+\tif (!strcmp(res->mode, \"set\"))\n+\t\tports[res->port_id].tso_segsz = res->tso_segsz;\n+\n+\tif (ports[res->port_id].tso_segsz == 0)\n+\t\tprintf(\"TSO is disabled\\n\");\n+\telse\n+\t\tprintf(\"TSO segment size is %d\\n\",\n+\t\t\tports[res->port_id].tso_segsz);\n+\n+\t/* display warnings if configuration is not supported by the NIC */\n+\trte_eth_dev_info_get(res->port_id, &dev_info);\n+\tif ((ports[res->port_id].tso_segsz != 0) &&\n+\t\t(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) == 0) {\n+\t\tprintf(\"Warning: TSO enabled but not \"\n+\t\t\t\"supported by port %d\\n\", res->port_id);\n+\t}\n+}\n+\n+cmdline_parse_token_string_t cmd_tso_set_tso =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,\n+\t\t\t\ttso, \"tso\");\n+cmdline_parse_token_string_t cmd_tso_set_mode =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,\n+\t\t\t\tmode, \"set\");\n+cmdline_parse_token_num_t cmd_tso_set_tso_segsz =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,\n+\t\t\t\ttso_segsz, UINT16);\n+cmdline_parse_token_num_t cmd_tso_set_portid =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,\n+\t\t\t\tport_id, UINT8);\n+\n+cmdline_parse_inst_t cmd_tso_set = {\n+\t.f = cmd_tso_set_parsed,\n+\t.data = NULL,\n+\t.help_str = \"Set TSO segment size for csum engine (0 to disable): \"\n+\t\"tso set <tso_segsz> <port>\",\n+\t.tokens = {\n+\t\t(void *)&cmd_tso_set_tso,\n+\t\t(void *)&cmd_tso_set_mode,\n+\t\t(void *)&cmd_tso_set_tso_segsz,\n+\t\t(void *)&cmd_tso_set_portid,\n+\t\tNULL,\n+\t},\n+};\n+\n+cmdline_parse_token_string_t cmd_tso_show_mode =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,\n+\t\t\t\tmode, \"show\");\n+\n+\n+cmdline_parse_inst_t cmd_tso_show = {\n+\t.f = cmd_tso_set_parsed,\n+\t.data = NULL,\n+\t.help_str = \"Show TSO segment size for csum engine: \"\n+\t\"tso show <port>\",\n+\t.tokens = {\n+\t\t(void *)&cmd_tso_set_tso,\n+\t\t(void *)&cmd_tso_show_mode,\n+\t\t(void *)&cmd_tso_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@@ -7875,6 +7965,8 @@ cmdline_parse_ctx_t main_ctx[] = {\n \t(cmdline_parse_inst_t *)&cmd_tx_vlan_set_pvid,\n \t(cmdline_parse_inst_t *)&cmd_tx_cksum_set,\n \t(cmdline_parse_inst_t *)&cmd_tx_cksum_show,\n+\t(cmdline_parse_inst_t *)&cmd_tso_set,\n+\t(cmdline_parse_inst_t *)&cmd_tso_show,\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/csumonly.c b/app/test-pmd/csumonly.c\nindex abc525c..7995ff5 100644\n--- a/app/test-pmd/csumonly.c\n+++ b/app/test-pmd/csumonly.c\n@@ -222,14 +222,15 @@ get_udptcp_checksum(void *l3_hdr, void *l4_hdr, uint16_t ethertype)\n /*\n  * Parse an ethernet header to fill the ethertype, l2_len, l3_len and\n  * ipproto. This function is able to recognize IPv4/IPv6 with one optional vlan\n- * header.\n+ * header. The l4_len argument is only set in case of TCP (useful for TSO).\n  */\n static void\n parse_ethernet(struct ether_hdr *eth_hdr, uint16_t *ethertype, uint16_t *l2_len,\n-\tuint16_t *l3_len, uint8_t *l4_proto)\n+\tuint16_t *l3_len, uint8_t *l4_proto, uint16_t *l4_len)\n {\n \tstruct ipv4_hdr *ipv4_hdr;\n \tstruct ipv6_hdr *ipv6_hdr;\n+\tstruct tcp_hdr *tcp_hdr;\n \n \t*l2_len = sizeof(struct ether_hdr);\n \t*ethertype = eth_hdr->ether_type;\n@@ -257,6 +258,14 @@ parse_ethernet(struct ether_hdr *eth_hdr, uint16_t *ethertype, uint16_t *l2_len,\n \t\t*l4_proto = 0;\n \t\tbreak;\n \t}\n+\n+\tif (*l4_proto == IPPROTO_TCP) {\n+\t\ttcp_hdr = (struct tcp_hdr *)((char *)eth_hdr +\n+\t\t\t*l2_len + *l3_len);\n+\t\t*l4_len = (tcp_hdr->data_off & 0xf0) >> 2;\n+\t}\n+\telse\n+\t\t*l4_len = 0;\n }\n \n /* modify the IPv4 or IPv4 source address of a packet */\n@@ -279,7 +288,7 @@ change_ip_addresses(void *l3_hdr, uint16_t ethertype)\n  * depending on the testpmd command line configuration */\n static uint64_t\n process_inner_cksums(void *l3_hdr, uint16_t ethertype, uint16_t l3_len,\n-\tuint8_t l4_proto, uint16_t testpmd_ol_flags)\n+\tuint8_t l4_proto, uint16_t tso_segsz, uint16_t testpmd_ol_flags)\n {\n \tstruct ipv4_hdr *ipv4_hdr = l3_hdr;\n \tstruct udp_hdr *udp_hdr;\n@@ -291,11 +300,15 @@ process_inner_cksums(void *l3_hdr, uint16_t ethertype, uint16_t l3_len,\n \t\tipv4_hdr = l3_hdr;\n \t\tipv4_hdr->hdr_checksum = 0;\n \n-\t\tif (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM)\n+\t\tif (tso_segsz != 0 && l4_proto == IPPROTO_TCP) {\n \t\t\tol_flags |= PKT_TX_IP_CKSUM;\n-\t\telse\n-\t\t\tipv4_hdr->hdr_checksum = get_ipv4_cksum(ipv4_hdr);\n-\n+\t\t}\n+\t\telse {\n+\t\t\tif (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM)\n+\t\t\t\tol_flags |= PKT_TX_IP_CKSUM;\n+\t\t\telse\n+\t\t\t\tipv4_hdr->hdr_checksum = get_ipv4_cksum(ipv4_hdr);\n+\t\t}\n \t}\n \telse if (ethertype != _htons(ETHER_TYPE_IPv6))\n \t\treturn 0; /* packet type not supported nothing to do */\n@@ -320,7 +333,11 @@ process_inner_cksums(void *l3_hdr, uint16_t ethertype, uint16_t l3_len,\n \telse if (l4_proto == IPPROTO_TCP) {\n \t\ttcp_hdr = (struct tcp_hdr *)((char *)l3_hdr + l3_len);\n \t\ttcp_hdr->cksum = 0;\n-\t\tif (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) {\n+\t\tif (tso_segsz != 0) {\n+\t\t\tol_flags |= PKT_TX_TCP_SEG;\n+\t\t\ttcp_hdr->cksum = get_psd_sum(l3_hdr, ethertype);\n+\t\t}\n+\t\telse if (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) {\n \t\t\tol_flags |= PKT_TX_TCP_CKSUM;\n \t\t\ttcp_hdr->cksum = get_psd_sum(l3_hdr, ethertype);\n \t\t}\n@@ -393,6 +410,8 @@ process_outer_cksums(void *outer_l3_hdr, uint16_t outer_ethertype,\n  *  - modify the IPs\n  *  - reprocess the checksum in SW or HW, depending on testpmd command line\n  *    configuration\n+ *  - if TSO is enabled in testpmd command line, also flag the mbuf for TCP\n+ *    segmentation offload (this implies HW checksum)\n  * Then packets are transmitted on the output port.\n  *\n  * Supported packets are:\n@@ -418,7 +437,9 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)\n \tuint16_t testpmd_ol_flags;\n \tuint8_t l4_proto;\n \tuint16_t ethertype = 0, outer_ethertype = 0;\n-\tuint16_t  l2_len = 0, l3_len = 0, outer_l2_len = 0, outer_l3_len = 0;\n+\tuint16_t l2_len = 0, l3_len = 0, l4_len = 0;\n+\tuint16_t outer_l2_len = 0, outer_l3_len = 0;\n+\tuint16_t tso_segsz;\n \tint tunnel = 0;\n \tuint32_t rx_bad_ip_csum;\n \tuint32_t rx_bad_l4_csum;\n@@ -448,6 +469,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)\n \n \ttxp = &ports[fs->tx_port];\n \ttestpmd_ol_flags = txp->tx_ol_flags;\n+\ttso_segsz = txp->tso_segsz;\n \n \tfor (i = 0; i < nb_rx; i++) {\n \n@@ -463,7 +485,8 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)\n \t\t * and inner headers */\n \n \t\teth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);\n-\t\tparse_ethernet(eth_hdr, &ethertype, &l2_len, &l3_len, &l4_proto);\n+\t\tparse_ethernet(eth_hdr, &ethertype, &l2_len, &l3_len,\n+\t\t\t&l4_proto, &l4_len);\n \t\tl3_hdr = (char *)eth_hdr + l2_len;\n \n \t\t/* check if it's a supported tunnel (only vxlan for now) */\n@@ -491,7 +514,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)\n \t\t\t\t\tsizeof(struct vxlan_hdr));\n \n \t\t\t\tparse_ethernet(eth_hdr, &ethertype, &l2_len,\n-\t\t\t\t\t&l3_len, &l4_proto);\n+\t\t\t\t\t&l3_len, &l4_proto, &l4_len);\n \t\t\t\tl3_hdr = (char *)eth_hdr + l2_len;\n \t\t\t}\n \t\t}\n@@ -505,11 +528,12 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)\n \n \t\t/* step 3: depending on user command line configuration,\n \t\t * recompute checksum either in software or flag the\n-\t\t * mbuf to offload the calculation to the NIC */\n+\t\t * mbuf to offload the calculation to the NIC. If TSO\n+\t\t * is configured, prepare the mbuf for TCP segmentation. */\n \n \t\t/* process checksums of inner headers first */\n \t\tol_flags |= process_inner_cksums(l3_hdr, ethertype,\n-\t\t\tl3_len, l4_proto, testpmd_ol_flags);\n+\t\t\tl3_len, l4_proto, tso_segsz, testpmd_ol_flags);\n \n \t\t/* Then process outer headers if any. Note that the software\n \t\t * checksum will be wrong if one of the inner checksums is\n@@ -538,6 +562,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)\n \t\t\t\t\tsizeof(struct udp_hdr) +\n \t\t\t\t\tsizeof(struct vxlan_hdr) + l2_len;\n \t\t\t\tm->l3_len = l3_len;\n+\t\t\t\tm->l4_len = l4_len;\n \t\t\t}\n \t\t} else {\n \t\t\t/* this is only useful if an offload flag is\n@@ -545,7 +570,9 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)\n \t\t\t * case */\n \t\t\tm->l2_len = l2_len;\n \t\t\tm->l3_len = l3_len;\n+\t\t\tm->l4_len = l4_len;\n \t\t}\n+\t\tm->tso_segsz = tso_segsz;\n \t\tm->ol_flags = ol_flags;\n \n \t}\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex c753d37..c22863f 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -149,6 +149,7 @@ struct rte_port {\n \tstruct fwd_stream       *tx_stream; /**< Port TX stream, if unique */\n \tunsigned int            socket_id;  /**< For NUMA support */\n \tuint16_t                tx_ol_flags;/**< TX Offload Flags (TESTPMD_TX_OFFLOAD...). */\n+\tuint16_t                tso_segsz;  /**< MSS for segmentation offload. */\n \tuint16_t                tx_vlan_id; /**< Tag Id. in TX VLAN packets. */\n \tvoid                    *fwd_ctx;   /**< Forwarding mode context */\n \tuint64_t                rx_bad_ip_csum; /**< rx pkts with bad ip checksum  */\n",
    "prefixes": [
        "dpdk-dev",
        "11/12"
    ]
}