From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wi0-f178.google.com (mail-wi0-f178.google.com [209.85.212.178]) by dpdk.org (Postfix) with ESMTP id 8D4F7B0B9 for ; Mon, 19 May 2014 15:57:01 +0200 (CEST) Received: by mail-wi0-f178.google.com with SMTP id cc10so1560830wib.11 for ; Mon, 19 May 2014 06:57:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8wDDH6EOYHaQgelqxiGqz1aGvYBRS4LQr/U3OfYMoA0=; b=Plx0q2eIEXNkbAggXNuNQFyx0Yo3WrrYvhUGBsX4nd4AWoU/wX3yaAVaw32uTNwoGp +RYMaxSzJ2sCh+ChvEugrcksrxQTQ2E5TnBLjHcQXOjG5zwEwjCK6zma3htTgO/qCVqI 2XEpAMytHcBYu4Jm/Q4y0XqYbe244tB4wfCItTAcq6vnjTgu9HBSpok31SfZeVUHa0Lp vEeOJFImQFM0AWZis1RznXdSxoQ5gGE9P4cTPh7PNil3oRVGeDcB6PxbBLDSHelSkHnC txv3HQyyvj8s2naM5lVIv3Jkjxzm/MHouWqQIEUBgEvltRfAKI5lcB19wfKnCAxAwcon pnzQ== X-Gm-Message-State: ALoCoQn9thzbW0KXGfkYADvQLXjBpzYF6IdVy1wWDzLd+/r4F9fhFYor/Y8FVe3/mtZgUcZMLPe3 X-Received: by 10.180.78.5 with SMTP id x5mr13462934wiw.12.1400507830315; Mon, 19 May 2014 06:57:10 -0700 (PDT) Received: from glumotte.dev.6wind.com (6wind.net2.nerim.net. [213.41.180.237]) by mx.google.com with ESMTPSA id t18sm15201828wiv.16.2014.05.19.06.57.08 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 19 May 2014 06:57:09 -0700 (PDT) From: Olivier Matz To: dev@dpdk.org Date: Mon, 19 May 2014 15:56:24 +0200 Message-Id: <1400507789-18453-13-git-send-email-olivier.matz@6wind.com> X-Mailer: git-send-email 1.9.2 In-Reply-To: <1400507789-18453-1-git-send-email-olivier.matz@6wind.com> References: <1400507789-18453-1-git-send-email-olivier.matz@6wind.com> Subject: [dpdk-dev] [PATCH v2 12/17] mbuf: generic support of TCP segmentation offload 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, 19 May 2014 13:57:02 -0000 Implement the generic part of TCP segmentation offload: - rte_mbuf modifications - testpmd for validation To delegate the TCP segmentation to the hardware, the user has to: - set the PKT_TX_TCP_SEG flag in mbuf->ol_flags (this flag implies PKT_TX_IP_CKSUM and PKT_TX_TCP_CKSUM) - fill the mbuf->hw_offload information: l2_len, l3_len, l4_len, mss - calculate the pseudo header checksum and set it in the TCP header, as required when doing hardware TCP checksum offload - set the IP checksum to 0 The API is inspired from ixgbe hardware (the next commit adds the support for ixgbe), but it seems generic enough to be used for other hw/drivers in the future. Signed-off-by: Olivier Matz --- app/test-pmd/cmdline.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ app/test-pmd/config.c | 8 ++++++++ app/test-pmd/csumonly.c | 16 ++++++++++++++++ app/test-pmd/testpmd.h | 2 ++ lib/librte_mbuf/rte_mbuf.h | 17 +++++++++++++++-- 5 files changed, 86 insertions(+), 2 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 8f155e9..c686901 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -2298,6 +2298,50 @@ cmdline_parse_inst_t cmd_tx_cksum_set = { }, }; +/* *** ENABLE HARDWARE SEGMENTATION IN TX PACKETS *** */ +struct cmd_tso_set_result { + cmdline_fixed_string_t tso; + cmdline_fixed_string_t set; + uint16_t mss; + uint8_t port_id; +}; + +static void +cmd_tso_set_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_tso_set_result *res = parsed_result; + tso_set(res->port_id, res->mss); +} + +cmdline_parse_token_string_t cmd_tso_set_tso = + TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result, + tso, "tso"); +cmdline_parse_token_string_t cmd_tso_set_set = + TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result, + set, "set"); +cmdline_parse_token_num_t cmd_tso_set_mss = + TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result, + mss, UINT16); +cmdline_parse_token_num_t cmd_tso_set_portid = + TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result, + port_id, UINT8); + +cmdline_parse_inst_t cmd_tso_set = { + .f = cmd_tso_set_parsed, + .data = NULL, + .help_str = "Enable hardware segmentation (set MSS to 0 to disable): " + "tso set ", + .tokens = { + (void *)&cmd_tso_set_tso, + (void *)&cmd_tso_set_set, + (void *)&cmd_tso_set_mss, + (void *)&cmd_tso_set_portid, + NULL, + }, +}; + /* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */ struct cmd_set_flush_rx { cmdline_fixed_string_t set; @@ -5197,6 +5241,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_tx_vlan_set, (cmdline_parse_inst_t *)&cmd_tx_vlan_reset, (cmdline_parse_inst_t *)&cmd_tx_cksum_set, + (cmdline_parse_inst_t *)&cmd_tso_set, (cmdline_parse_inst_t *)&cmd_link_flow_control_set, (cmdline_parse_inst_t *)&cmd_priority_flow_control_set, (cmdline_parse_inst_t *)&cmd_config_dcb, diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 018a278..184efdb 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1545,6 +1545,14 @@ tx_cksum_set(portid_t port_id, uint32_t ol_flags) } void +tso_set(portid_t port_id, uint16_t mss) +{ + if (port_id_is_invalid(port_id)) + return; + ports[port_id].tx_mss = mss; +} + +void fdir_add_signature_filter(portid_t port_id, uint8_t queue_id, struct rte_fdir_filter *fdir_filter) { diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c index e93d75f..9983618 100644 --- a/app/test-pmd/csumonly.c +++ b/app/test-pmd/csumonly.c @@ -220,10 +220,12 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) uint32_t ol_flags; uint32_t pkt_ol_flags; uint32_t tx_ol_flags; + uint16_t tx_mss; uint16_t l4_proto; uint16_t eth_type; uint8_t l2_len; uint8_t l3_len; + uint8_t l4_len; uint32_t rx_bad_ip_csum; uint32_t rx_bad_l4_csum; @@ -255,6 +257,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) txp = &ports[fs->tx_port]; tx_ol_flags = txp->tx_ol_flags; + tx_mss = txp->tx_mss; for (i = 0; i < nb_rx; i++) { @@ -272,6 +275,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) ((uintptr_t)ð_hdr->ether_type + sizeof(struct vlan_hdr))); } + l4_len = 0; /* Update the L3/L4 checksum error packet count */ rx_bad_ip_csum += ((pkt_ol_flags & PKT_RX_IP_CKSUM_BAD) != 0); @@ -347,6 +351,11 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) tcp_hdr->cksum = get_ipv4_udptcp_checksum(ipv4_hdr, (uint16_t*)tcp_hdr); } + + if (tx_mss != 0) { + ol_flags |= PKT_TX_TCP_SEG; + l4_len = (tcp_hdr->data_off & 0xf0) >> 2; + } } else if (l4_proto == IPPROTO_SCTP) { sctp_hdr = (struct sctp_hdr*) (rte_pktmbuf_mtod(mb, @@ -404,6 +413,11 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) tcp_hdr->cksum = get_ipv6_udptcp_checksum(ipv6_hdr, (uint16_t*)tcp_hdr); } + + if (tx_mss != 0) { + ol_flags |= PKT_TX_TCP_SEG; + l4_len = (tcp_hdr->data_off & 0xf0) >> 2; + } } else if (l4_proto == IPPROTO_SCTP) { sctp_hdr = (struct sctp_hdr*) (rte_pktmbuf_mtod(mb, @@ -434,6 +448,8 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) /* Combine the packet header write. VLAN is not consider here */ mb->hw_offload.l2_len = l2_len; mb->hw_offload.l3_len = l3_len; + mb->hw_offload.l4_len = l4_len; + mb->hw_offload.mss = tx_mss; mb->ol_flags = ol_flags; } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx); diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 68eccfa..b093911 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -135,6 +135,7 @@ struct rte_port { struct fwd_stream *tx_stream; /**< Port TX stream, if unique */ unsigned int socket_id; /**< For NUMA support */ uint32_t tx_ol_flags;/**< Offload Flags of TX packets. */ + uint16_t tx_mss; /**< MSS for segmentation offload. */ uint16_t tx_vlan_id; /**< Tag Id. in TX VLAN packets. */ void *fwd_ctx; /**< Forwarding mode context */ uint64_t rx_bad_ip_csum; /**< rx pkts with bad ip checksum */ @@ -486,6 +487,7 @@ void tx_vlan_reset(portid_t port_id); void set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value); void tx_cksum_set(portid_t port_id, uint32_t ol_flags); +void tso_set(portid_t port_id, uint16_t mss); void set_verbose_level(uint16_t vb_level); void set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs); diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index 1e63511..c65ab81 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -96,6 +96,17 @@ extern "C" { #define PKT_TX_SCTP_CKSUM 0x00080000 /**< SCTP cksum of TX pkt. computed by NIC. */ #define PKT_TX_UDP_CKSUM 0x000C0000 /**< UDP cksum of TX pkt. computed by NIC. */ #define PKT_TX_IEEE1588_TMST 0x00100000 /**< TX IEEE1588 packet to timestamp. */ +/** + * TCP segmentation offload. To enable this offload feature for a + * packet to be transmitted on hardware supporting TSO: + * - set the PKT_TX_TCP_SEG flag in mbuf->ol_flags (this flag implies + * PKT_TX_IP_CKSUM and PKT_TX_TCP_CKSUM) + * - fill the mbuf->hw_offload information: l2_len, l3_len, l4_len, mss + * - calculate the pseudo header checksum and set it in the TCP header, + * as required when doing hardware TCP checksum offload + * - set the IP checksum to 0 + */ +#define PKT_TX_TCP_SEG 0x00200000 /** * Get the name of a RX offload flag @@ -144,6 +155,7 @@ static inline const char *rte_get_tx_ol_flag_name(uint32_t mask) case PKT_TX_SCTP_CKSUM: return "PKT_TX_SCTP_CKSUM"; case PKT_TX_UDP_CKSUM: return "PKT_TX_UDP_CKSUM"; case PKT_TX_IEEE1588_TMST: return "PKT_TX_IEEE1588_TMST"; + case PKT_TX_TCP_SEG: return "PKT_TX_TCP_SEG"; default: return NULL; } } @@ -157,11 +169,12 @@ union rte_hw_offload { #define HW_OFFLOAD_L4_LEN_MASK 0xff uint32_t l2_len:7; /**< L2 (MAC) Header Length. */ uint32_t l3_len:9; /**< L3 (IP) Header Length. */ - uint32_t reserved:16; + uint32_t l4_len:8; /**< L4 (TCP/UDP) Header Length. */ + uint32_t reserved:8; uint16_t vlan_tci; /**< VLAN Tag Control Identifier (CPU order). */ - uint16_t reserved2; + uint16_t mss; /**< Maximum segment size. */ }; }; -- 1.9.2