From patchwork Wed Feb 3 15:49:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ferruh Yigit X-Patchwork-Id: 87698 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 53B36A0A0E; Wed, 3 Feb 2021 16:49:27 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B835B24062E; Wed, 3 Feb 2021 16:49:26 +0100 (CET) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by mails.dpdk.org (Postfix) with ESMTP id F3B1524062D; Wed, 3 Feb 2021 16:49:24 +0100 (CET) IronPort-SDR: zSOxbxK44gNWhGExcLoYTbTroc8HQYSSxu8FoNvr5ydBgAqB/FBx80CurxuXBxS2oxmMH0wrv/ FnecikMip7mg== X-IronPort-AV: E=McAfee;i="6000,8403,9884"; a="168741990" X-IronPort-AV: E=Sophos;i="5.79,398,1602572400"; d="scan'208";a="168741990" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Feb 2021 07:49:23 -0800 IronPort-SDR: y5chQ0i7zMmPC+uXrgMh5ym/e8yN5wuIlWjfwWOLcNF48FNgb0vQBnNuhQmTIyV456PiHjqjOd ZCy4flJZfDfA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,398,1602572400"; d="scan'208";a="507795404" Received: from silpixa00399752.ir.intel.com (HELO silpixa00399752.ger.corp.intel.com) ([10.237.222.27]) by orsmga004.jf.intel.com with ESMTP; 03 Feb 2021 07:49:22 -0800 From: Ferruh Yigit To: Cian Ferriter Cc: Ferruh Yigit , dev@dpdk.org, stable@dpdk.org Date: Wed, 3 Feb 2021 15:49:20 +0000 Message-Id: <20210203154920.2449179-1-ferruh.yigit@intel.com> X-Mailer: git-send-email 2.29.2 MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH] net/pcap: fix infinite Rx with large files 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 Sender: "dev" Packet forwarding is not working when infinite Rx feature is used with large .pcap files that has high number of packets. The problem is number of allocated mbufs are less than the infinite Rx ring size, and all mbufs consumed to fill the ring, so there is no mbuf left for forwarding. Current logic can not detect that infinite Rx ring is not filled completely and no more mbufs left, and setup continues which leads silent fail on packet forwarding. There isn't much can be done when there is not enough mbuf for the given .pcap file, so additional checks added to detect the case and fail explicitly with an error log. Bugzilla ID: 595 Fixes: a3f5252e5cbd ("net/pcap: enable infinitely Rx a pcap file") Cc: stable@dpdk.org Reported-by: Cian Ferriter Signed-off-by: Ferruh Yigit Acked-by: Cian Ferriter --- drivers/net/pcap/rte_eth_pcap.c | 40 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c index ff02ade70d1a..98f80368ca1d 100644 --- a/drivers/net/pcap/rte_eth_pcap.c +++ b/drivers/net/pcap/rte_eth_pcap.c @@ -735,6 +735,17 @@ eth_stats_reset(struct rte_eth_dev *dev) return 0; } +static inline void +infinite_rx_ring_free(struct rte_ring *pkts) +{ + struct rte_mbuf *bufs; + + while (!rte_ring_dequeue(pkts, (void **)&bufs)) + rte_pktmbuf_free(bufs); + + rte_ring_free(pkts); +} + static int eth_dev_close(struct rte_eth_dev *dev) { @@ -753,7 +764,6 @@ eth_dev_close(struct rte_eth_dev *dev) if (internals->infinite_rx) { for (i = 0; i < dev->data->nb_rx_queues; i++) { struct pcap_rx_queue *pcap_q = &internals->rx_queue[i]; - struct rte_mbuf *pcap_buf; /* * 'pcap_q->pkts' can be NULL if 'eth_dev_close()' @@ -762,11 +772,7 @@ eth_dev_close(struct rte_eth_dev *dev) if (pcap_q->pkts == NULL) continue; - while (!rte_ring_dequeue(pcap_q->pkts, - (void **)&pcap_buf)) - rte_pktmbuf_free(pcap_buf); - - rte_ring_free(pcap_q->pkts); + infinite_rx_ring_free(pcap_q->pkts); } } @@ -835,21 +841,25 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, while (eth_pcap_rx(pcap_q, bufs, 1)) { /* Check for multiseg mbufs. */ if (bufs[0]->nb_segs != 1) { - rte_pktmbuf_free(*bufs); - - while (!rte_ring_dequeue(pcap_q->pkts, - (void **)bufs)) - rte_pktmbuf_free(*bufs); - - rte_ring_free(pcap_q->pkts); - PMD_LOG(ERR, "Multiseg mbufs are not supported in infinite_rx " - "mode."); + infinite_rx_ring_free(pcap_q->pkts); + PMD_LOG(ERR, + "Multiseg mbufs are not supported in infinite_rx mode."); return -EINVAL; } rte_ring_enqueue_bulk(pcap_q->pkts, (void * const *)bufs, 1, NULL); } + + if (rte_ring_count(pcap_q->pkts) < pcap_pkt_count) { + infinite_rx_ring_free(pcap_q->pkts); + PMD_LOG(ERR, + "Not enough mbuf to fill the infinite_rx ring. " + "At least %" PRIu64 " mbufs per queue is required to fill the ring", + pcap_pkt_count); + return -EINVAL; + } + /* * Reset the stats for this queue since eth_pcap_rx calls above * didn't result in the application receiving packets.