From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B5F2842A9D; Tue, 9 May 2023 04:07:46 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8C9C6410D0; Tue, 9 May 2023 04:07:46 +0200 (CEST) Received: from EX-PRD-EDGE02.vmware.com (EX-PRD-EDGE02.vmware.com [208.91.3.34]) by mails.dpdk.org (Postfix) with ESMTP id 1D6B340EF0; Tue, 9 May 2023 04:07:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; s=s1024; d=vmware.com; h=from:to:cc:subject:date:message-id:mime-version:content-type; bh=A1ndabiRsmEwA1rd5L9YohJkoMbAZn5BdsVctBlCXXs=; b=h0Jg0mmr79rIUwPsUHY6B9WLM2ncrPB+XgHGsqHPf/fGBFYFRHugo/Uv+wcIQo GyNeZrdp0wk1uG1RfvUvN9m9/upr64iCHvX3UnIm56fNKWmwgWkQ3qQ/dX51zG pU6qpNJ5AEATfwRd0DUWgKatWMyUpva8+sbNwnaPtQaQcBA= Received: from sc9-mailhost3.vmware.com (10.113.161.73) by EX-PRD-EDGE02.vmware.com (10.188.245.7) with Microsoft SMTP Server id 15.1.2375.34; Mon, 8 May 2023 19:07:27 -0700 Received: from htb-1n-eng-dhcp122.eng.vmware.com (unknown [10.20.114.216]) by sc9-mailhost3.vmware.com (Postfix) with ESMTP id 7FC2220324; Mon, 8 May 2023 19:07:32 -0700 (PDT) Received: by htb-1n-eng-dhcp122.eng.vmware.com (Postfix, from userid 0) id 5AC5EAB1B4; Mon, 8 May 2023 19:07:32 -0700 (PDT) From: Ronak Doshi To: Jochen Behrens , Didier Pallard , Yong Wang CC: , Ronak Doshi , Subject: [PATCH net] net/vmxnet3: fix drop of empty segments in tx Date: Mon, 8 May 2023 19:07:24 -0700 Message-ID: <20230509020724.23918-1-doshir@vmware.com> X-Mailer: git-send-email 2.11.0 MIME-Version: 1.0 Content-Type: text/plain Received-SPF: None (EX-PRD-EDGE02.vmware.com: doshir@vmware.com does not designate permitted sender hosts) X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org When empty segments are dropped, some descriptor variable values are updated in the segment processing loop before it is exited. This can lead to a wedged queue where all subsequent packets are dropped for this queue. Also move the check for empty packet to catch the case of a zero length packet with multiple segments. Fixes: d863f19efa4f ("net/vmxnet3: skip empty segments in transmission") Cc: stable@dpdk.org Signed-off-by: Ronak Doshi Acked-by: Jochen Behrens --- drivers/net/vmxnet3/vmxnet3_rxtx.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c index a875ffec07..8208cefdff 100644 --- a/drivers/net/vmxnet3/vmxnet3_rxtx.c +++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c @@ -412,8 +412,8 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, nb_tx = 0; while (nb_tx < nb_pkts) { - Vmxnet3_GenericDesc *gdesc; - vmxnet3_buf_info_t *tbi; + Vmxnet3_GenericDesc *gdesc = NULL; + vmxnet3_buf_info_t *tbi = NULL; uint32_t first2fill, avail, dw2; struct rte_mbuf *txm = tx_pkts[nb_tx]; struct rte_mbuf *m_seg = txm; @@ -457,18 +457,18 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, continue; } + /* Skip empty packets */ + if (unlikely(rte_pktmbuf_pkt_len(txm) == 0)) { + txq->stats.drop_total++; + rte_pktmbuf_free(txm); + nb_tx++; + continue; + } + if (txm->nb_segs == 1 && rte_pktmbuf_pkt_len(txm) <= txq->txdata_desc_size) { struct Vmxnet3_TxDataDesc *tdd; - /* Skip empty packets */ - if (unlikely(rte_pktmbuf_pkt_len(txm) == 0)) { - txq->stats.drop_total++; - rte_pktmbuf_free(txm); - nb_tx++; - continue; - } - tdd = (struct Vmxnet3_TxDataDesc *) ((uint8 *)txq->data_ring.base + txq->cmd_ring.next2fill * @@ -481,6 +481,10 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, dw2 = (txq->cmd_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT; first2fill = txq->cmd_ring.next2fill; do { + /* Skip empty segments */ + if (unlikely(m_seg->data_len == 0)) + continue; + /* Remember the transmit buffer for cleanup */ tbi = txq->cmd_ring.buf_info + txq->cmd_ring.next2fill; @@ -490,10 +494,6 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, */ gdesc = txq->cmd_ring.base + txq->cmd_ring.next2fill; - /* Skip empty segments */ - if (unlikely(m_seg->data_len == 0)) - continue; - if (copy_size) { uint64 offset = (uint64)txq->cmd_ring.next2fill * @@ -514,6 +514,11 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, /* use the right gen for non-SOP desc */ dw2 = txq->cmd_ring.gen << VMXNET3_TXD_GEN_SHIFT; } while ((m_seg = m_seg->next) != NULL); + /* We must have exectuted the complete preceding loop at least + * once without skipping an empty segment, as we can't have + * a packet with only empty segments. + * Thus, tbi and gdesc have been initialized. + */ /* set the last buf_info for the pkt */ tbi->m = txm; -- 2.11.0