From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0C2F6A04F7; Tue, 7 Jan 2020 02:57:59 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 9A5C01D8E6; Tue, 7 Jan 2020 02:57:58 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id AE3291D8DA; Tue, 7 Jan 2020 02:57:56 +0100 (CET) X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Jan 2020 17:57:55 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,404,1571727600"; d="scan'208";a="253562244" Received: from yexl-server.sh.intel.com (HELO localhost) ([10.67.117.17]) by fmsmga002.fm.intel.com with ESMTP; 06 Jan 2020 17:57:54 -0800 Date: Tue, 7 Jan 2020 09:52:15 +0800 From: Ye Xiaolong To: Xiaoyun Li Cc: qi.z.zhang@intel.com, beilei.xing@intel.com, ciara.loftus@intel.com, dev@dpdk.org, stable@dpdk.org Message-ID: <20200107015215.GC49980@intel.com> References: <20191223025547.88798-1-xiaoyun.li@intel.com> <20191226064544.48322-1-xiaoyun.li@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20191226064544.48322-1-xiaoyun.li@intel.com> User-Agent: Mutt/1.9.4 (2018-02-28) Subject: Re: [dpdk-dev] [PATCH v3] net/i40e: fix TSO pkt exceeds allowed buf size issue 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" On 12/26, Xiaoyun Li wrote: >Hardware limits that max buffer size per tx descriptor should be >(16K-1)B. So when TSO enabled, the mbuf data size may exceed the >limit and cause malicious behavior to the NIC. This patch fixes >this issue by using more tx descs for this kind of large buffer. > >Fixes: 4861cde46116 ("i40e: new poll mode driver") >Cc: stable@dpdk.org > >Signed-off-by: Xiaoyun Li >--- >v3: > * Reused the existing macros to define I40E_MAX_DATA_PER_TXD >v2: > * Each pkt can have several segments so the needed tx descs should sum > * all segments up. >--- > drivers/net/i40e/i40e_rxtx.c | 45 +++++++++++++++++++++++++++++++++++- > 1 file changed, 44 insertions(+), 1 deletion(-) > >diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c >index 17dc8c78f..bbdba39b3 100644 >--- a/drivers/net/i40e/i40e_rxtx.c >+++ b/drivers/net/i40e/i40e_rxtx.c >@@ -989,6 +989,24 @@ i40e_set_tso_ctx(struct rte_mbuf *mbuf, union i40e_tx_offload tx_offload) > return ctx_desc; > } > >+/* HW requires that Tx buffer size ranges from 1B up to (16K-1)B. */ >+#define I40E_MAX_DATA_PER_TXD \ >+ (I40E_TXD_QW1_TX_BUF_SZ_MASK >> I40E_TXD_QW1_TX_BUF_SZ_SHIFT) >+/* Calculate the number of TX descriptors needed for each pkt */ >+static inline uint16_t >+i40e_calc_pkt_desc(struct rte_mbuf *tx_pkt) >+{ >+ struct rte_mbuf *txd = tx_pkt; >+ uint16_t count = 0; >+ >+ while (txd != NULL) { >+ count += DIV_ROUND_UP(txd->data_len, I40E_MAX_DATA_PER_TXD); >+ txd = txd->next; >+ } >+ >+ return count; >+} >+ > uint16_t > i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) > { >@@ -1046,8 +1064,15 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) > * The number of descriptors that must be allocated for > * a packet equals to the number of the segments of that > * packet plus 1 context descriptor if needed. >+ * Recalculate the needed tx descs when TSO enabled in case >+ * the mbuf data size exceeds max data size that hw allows >+ * per tx desc. > */ >- nb_used = (uint16_t)(tx_pkt->nb_segs + nb_ctx); >+ if (ol_flags & PKT_TX_TCP_SEG) >+ nb_used = (uint16_t)(i40e_calc_pkt_desc(tx_pkt) + >+ nb_ctx); >+ else >+ nb_used = (uint16_t)(tx_pkt->nb_segs + nb_ctx); > tx_last = (uint16_t)(tx_id + nb_used - 1); > > /* Circular ring */ >@@ -1160,6 +1185,24 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) > slen = m_seg->data_len; > buf_dma_addr = rte_mbuf_data_iova(m_seg); > >+ while ((ol_flags & PKT_TX_TCP_SEG) && >+ unlikely(slen > I40E_MAX_DATA_PER_TXD)) { >+ txd->buffer_addr = >+ rte_cpu_to_le_64(buf_dma_addr); >+ txd->cmd_type_offset_bsz = >+ i40e_build_ctob(td_cmd, >+ td_offset, I40E_MAX_DATA_PER_TXD, >+ td_tag); >+ >+ buf_dma_addr += I40E_MAX_DATA_PER_TXD; >+ slen -= I40E_MAX_DATA_PER_TXD; >+ >+ txe->last_id = tx_last; >+ tx_id = txe->next_id; >+ txe = txn; >+ txd = &txr[tx_id]; >+ txn = &sw_ring[txe->next_id]; >+ } > PMD_TX_LOG(DEBUG, "mbuf: %p, TDD[%u]:\n" > "buf_dma_addr: %#"PRIx64";\n" > "td_cmd: %#x;\n" >-- >2.17.1 > Applied to dpdk-next-net-intel, Thanks.