From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from rcdn-iport-8.cisco.com (rcdn-iport-8.cisco.com [173.37.86.79]) by dpdk.org (Postfix) with ESMTP id CF3081B33E; Thu, 2 Nov 2017 02:59:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=3402; q=dns/txt; s=iport; t=1509587953; x=1510797553; h=from:to:cc:subject:date:message-id; bh=bZiuJhnrcfivTVtfjvQuwmR1czc2arL96HFoeBfNWuM=; b=TMVRbj2RASeAF2Bh6wOzU5OxwnCK0O2qOqgOIebDZHBAWA+uwPGj7+5A j2p0iGNvUuO9ZhgFPXY3nySxuAr2Ww0RQIV63V/aVYpgmtJr7S2iWJmfW v4Zb9r1yFKLPpkR1FNyv+QWaiQGffiT2wtrtDsjiJTmWk4VwL8c0/cj1c Y=; X-IronPort-AV: E=Sophos;i="5.44,331,1505779200"; d="scan'208";a="313477157" Received: from rcdn-core-3.cisco.com ([173.37.93.154]) by rcdn-iport-8.cisco.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Nov 2017 01:59:11 +0000 Received: from cisco.com (savbu-usnic-a.cisco.com [10.193.184.48]) by rcdn-core-3.cisco.com (8.14.5/8.14.5) with ESMTP id vA21xBK8022321; Thu, 2 Nov 2017 01:59:11 GMT Received: by cisco.com (Postfix, from userid 392789) id 5915220F2001; Wed, 1 Nov 2017 18:59:11 -0700 (PDT) From: John Daley To: ferruh.yigit@intel.com Cc: dev@dpdk.org, John Daley , stable@dpdk.org Date: Wed, 1 Nov 2017 18:59:08 -0700 Message-Id: <20171102015908.6953-1-johndale@cisco.com> X-Mailer: git-send-email 2.12.0 Subject: [dpdk-dev] [PATCH] net/enic: fix TSO for packets greater than 9208 bytes X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Nov 2017 01:59:13 -0000 A check was previously added to drop Tx packets greater than what the Nic is capable of sending since such packets can freeze the send queue. The check did not account for TSO packets however, so TSO was limited to 9208 bytes. Check packet length only for non-TSO packets. Also insure that TSO packet segment size plus the headers do not exceed what the Nic is capable of since this also can freeze the send queue. Use the PKT_TX_TCP_SEG ol_flag instead of m->tso_segsz which is the preferred way to check for TSO. Fixes: ed6e564c214e ("net/enic: fix memory leak with oversized Tx packets") Cc: stable@dpdk.org Signed-off-by: John Daley --- Note that there is some more work to do on enic TSO- the header length is calculated by looking at the packet instead of just trusting mbuf tso offload header lengths. The 'tx_oversized' stat is used for more than just oversized packets- it gets rolled into 'oerrors' so doesn't matter but the name should be changed. Some TSO tunneling support can be added for newer hardware. These changes will come in the next relase, but hope that this patch can be accepted in 17.11 because it solves existing customer problem. drivers/net/enic/enic_rxtx.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c index a39172f14..e938193b5 100644 --- a/drivers/net/enic/enic_rxtx.c +++ b/drivers/net/enic/enic_rxtx.c @@ -546,12 +546,15 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint64_t bus_addr; uint8_t offload_mode; uint16_t header_len; + uint64_t tso; + rte_atomic64_t *tx_oversized; enic_cleanup_wq(enic, wq); wq_desc_avail = vnic_wq_desc_avail(wq); head_idx = wq->head_idx; desc_count = wq->ring.desc_count; ol_flags_mask = PKT_TX_VLAN_PKT | PKT_TX_IP_CKSUM | PKT_TX_L4_MASK; + tx_oversized = &enic->soft_stats.tx_oversized; nb_pkts = RTE_MIN(nb_pkts, ENIC_TX_XMIT_MAX); @@ -561,10 +564,12 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, data_len = tx_pkt->data_len; ol_flags = tx_pkt->ol_flags; nb_segs = tx_pkt->nb_segs; + tso = ol_flags & PKT_TX_TCP_SEG; - if (pkt_len > ENIC_TX_MAX_PKT_SIZE) { + /* drop packet if it's too big to send */ + if (unlikely(!tso && (pkt_len > ENIC_TX_MAX_PKT_SIZE))) { rte_pktmbuf_free(tx_pkt); - rte_atomic64_inc(&enic->soft_stats.tx_oversized); + rte_atomic64_inc(tx_oversized); continue; } @@ -587,13 +592,21 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, offload_mode = WQ_ENET_OFFLOAD_MODE_CSUM; header_len = 0; - if (tx_pkt->tso_segsz) { + if (tso) { header_len = tso_header_len(tx_pkt); - if (header_len) { - offload_mode = WQ_ENET_OFFLOAD_MODE_TSO; - mss = tx_pkt->tso_segsz; + + /* Drop if non-TCP packet or TSO seg size is too big */ + if (unlikely((header_len == 0) || ((tx_pkt->tso_segsz + + header_len) > ENIC_TX_MAX_PKT_SIZE))) { + rte_pktmbuf_free(tx_pkt); + rte_atomic64_inc(tx_oversized); + continue; } + + offload_mode = WQ_ENET_OFFLOAD_MODE_TSO; + mss = tx_pkt->tso_segsz; } + if ((ol_flags & ol_flags_mask) && (header_len == 0)) { if (ol_flags & PKT_TX_IP_CKSUM) mss |= ENIC_CALC_IP_CKSUM; -- 2.12.0