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 0577D41E63; Tue, 9 May 2023 04:21:16 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D7C5B410D0; Tue, 9 May 2023 04:21:15 +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 8ED7340EF0; Tue, 9 May 2023 04:21:14 +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=sM6vQMUC/BTx4dODm4t2CVxgJvjGqkxJjRqU+1Re4fg=; b=s2513evNF6kXSp9HOOI9AQTVFbq8KJZpyNz8zEy3UsHeCuChHRiJnZEKtnA0gX dHoaim+1eoe/ED03NWlcXwa55NUzMsT+jy7akuUfGZ/eDXQbdImvhcr4UoWwef vj3NSBS99JVPOD2iPn0lIAjnzsJUeq3Bee3ojBx+2jIammk= Received: from sc9-mailhost2.vmware.com (10.113.161.72) by EX-PRD-EDGE02.vmware.com (10.188.245.7) with Microsoft SMTP Server id 15.1.2375.34; Mon, 8 May 2023 19:21:02 -0700 Received: from htb-1n-eng-dhcp122.eng.vmware.com (unknown [10.20.114.216]) by sc9-mailhost2.vmware.com (Postfix) with ESMTP id B185B20361; Mon, 8 May 2023 19:21:07 -0700 (PDT) Received: by htb-1n-eng-dhcp122.eng.vmware.com (Postfix, from userid 0) id A95A0AE87A; Mon, 8 May 2023 19:21:07 -0700 (PDT) From: Ronak Doshi To: Jochen Behrens , Didier Pallard , Yong Wang CC: , Ronak Doshi , Subject: [PATCH net v2] net/vmxnet3: fix drop of empty segments in tx Date: Mon, 8 May 2023 19:21:06 -0700 Message-ID: <20230509022106.25455-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 -- Change log v2: fixed typo --- 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..f4cade0954 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 executed 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