From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 37422C368 for ; Thu, 23 Jul 2015 18:05:11 +0200 (CEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 23 Jul 2015 09:05:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,531,1432623600"; d="scan'208";a="769930801" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga002.jf.intel.com with ESMTP; 23 Jul 2015 09:05:08 -0700 Received: from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com [10.237.217.45]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id t6NG57sd029662; Thu, 23 Jul 2015 17:05:07 +0100 Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id t6NG57oe003945; Thu, 23 Jul 2015 17:05:07 +0100 Received: (from bricha3@localhost) by sivswdev01.ir.intel.com with id t6NG57u5003941; Thu, 23 Jul 2015 17:05:07 +0100 From: Bruce Richardson To: dev@dpdk.org Date: Thu, 23 Jul 2015 17:05:04 +0100 Message-Id: <1437667506-3890-4-git-send-email-bruce.richardson@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1437667506-3890-1-git-send-email-bruce.richardson@intel.com> References: <1437667506-3890-1-git-send-email-bruce.richardson@intel.com> Subject: [dpdk-dev] [PATCH 3/5] ixgbe: fix bug on release of mbufs from queue X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Jul 2015 16:05:12 -0000 The calculations of what mbufs were valid in the RX and TX queues were incorrect when freeing the mbufs for the vector PMD. This led to crashes due to invalid reference counts when mbuf debugging was turned on, and possibly other more subtle problems (such as mbufs being freed when in use) in other cases. To fix this, the following changes were made: * correct counts and post-loop values in the TX release function for the vector code. * create a new separate RX release function for the RX vector code, since the tracking of what mbufs are valid or not is different for that code path Fixes: c95584dc2b18 ("ixgbe: new vectorized functions for Rx/Tx") Signed-off-by: Bruce Richardson --- drivers/net/ixgbe/ixgbe_rxtx.c | 16 ++++++++++++ drivers/net/ixgbe/ixgbe_rxtx.h | 2 ++ drivers/net/ixgbe/ixgbe_rxtx_vec.c | 52 +++++++++++++++++++++++++------------- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c index 75c5555..a8bccab 100644 --- a/drivers/net/ixgbe/ixgbe_rxtx.c +++ b/drivers/net/ixgbe/ixgbe_rxtx.c @@ -2270,6 +2270,14 @@ ixgbe_rx_queue_release_mbufs(struct ixgbe_rx_queue *rxq) { unsigned i; +#ifdef RTE_IXGBE_INC_VECTOR + /* SSE Vector driver has a different way of releasing mbufs. */ + if (rxq->rx_using_sse) { + ixgbe_rx_queue_release_mbufs_vec(rxq); + return; + } +#endif + if (rxq->sw_ring != NULL) { for (i = 0; i < rxq->nb_rx_desc; i++) { if (rxq->sw_ring[i].mbuf != NULL) { @@ -4013,6 +4021,14 @@ ixgbe_set_rx_function(struct rte_eth_dev *dev) dev->rx_pkt_burst = ixgbe_recv_pkts; } + + if (adapter->rx_vec_allowed) { + unsigned i; + for (i = 0; i < dev->data->nb_rx_queues; i++) { + struct ixgbe_rx_queue *rxq = dev->data->rx_queues[i]; + rxq->rx_using_sse = 1; + } + } } /** diff --git a/drivers/net/ixgbe/ixgbe_rxtx.h b/drivers/net/ixgbe/ixgbe_rxtx.h index 64e6bb9..2ed6816 100644 --- a/drivers/net/ixgbe/ixgbe_rxtx.h +++ b/drivers/net/ixgbe/ixgbe_rxtx.h @@ -121,6 +121,7 @@ struct ixgbe_rx_queue { uint16_t rx_next_avail; /**< idx of next staged pkt to ret to app */ uint16_t rx_free_trigger; /**< triggers rx buffer allocation */ #endif + uint16_t rx_using_sse; /**< indicates that vector RX is in use */ #ifdef RTE_IXGBE_INC_VECTOR uint16_t rxrearm_nb; /**< number of remaining to be re-armed */ uint16_t rxrearm_start; /**< the idx we start the re-arming from */ @@ -284,6 +285,7 @@ uint16_t ixgbe_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); int ixgbe_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev); int ixgbe_rxq_vec_setup(struct ixgbe_rx_queue *rxq); +void ixgbe_rx_queue_release_mbufs_vec(struct ixgbe_rx_queue *rxq); #ifdef RTE_IXGBE_INC_VECTOR diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec.c b/drivers/net/ixgbe/ixgbe_rxtx_vec.c index 47ff990..a6a506f 100644 --- a/drivers/net/ixgbe/ixgbe_rxtx_vec.c +++ b/drivers/net/ixgbe/ixgbe_rxtx_vec.c @@ -726,25 +726,43 @@ ixgbe_tx_queue_release_mbufs(struct ixgbe_tx_queue *txq) { unsigned i; struct ixgbe_tx_entry_v *txe; - uint16_t nb_free, max_desc; + const uint16_t max_desc = (uint16_t)(txq->nb_tx_desc - 1); - if (txq->sw_ring != NULL) { - /* release the used mbufs in sw_ring */ - nb_free = txq->nb_tx_free; - max_desc = (uint16_t)(txq->nb_tx_desc - 1); - for (i = txq->tx_next_dd - (txq->tx_rs_thresh - 1); - nb_free < max_desc && i != txq->tx_tail; - i = (i + 1) & max_desc) { - txe = (struct ixgbe_tx_entry_v *)&txq->sw_ring[i]; - if (txe->mbuf != NULL) - rte_pktmbuf_free_seg(txe->mbuf); - } - /* reset tx_entry */ - for (i = 0; i < txq->nb_tx_desc; i++) { - txe = (struct ixgbe_tx_entry_v *)&txq->sw_ring[i]; - txe->mbuf = NULL; - } + if (txq->sw_ring == NULL || txq->nb_tx_free == max_desc) + return; + + /* release the used mbufs in sw_ring */ + for (i = txq->tx_next_dd - (txq->tx_rs_thresh - 1); + i != txq->tx_tail; + i = (i + 1) & max_desc) { + txe = &((struct ixgbe_tx_entry_v *)txq->sw_ring)[i]; + rte_pktmbuf_free_seg(txe->mbuf); } + txq->nb_tx_free = max_desc; + + /* reset tx_entry */ + for (i = 0; i < txq->nb_tx_desc; i++) { + txe = (struct ixgbe_tx_entry_v *)&txq->sw_ring[i]; + txe->mbuf = NULL; + } +} + +void __attribute__((cold)) +ixgbe_rx_queue_release_mbufs_vec(struct ixgbe_rx_queue *rxq) +{ + const unsigned mask = rxq->nb_rx_desc - 1; + unsigned i; + + if (rxq->sw_ring == NULL || rxq->rxrearm_nb >= rxq->nb_rx_desc) + return; + + /* free all mbufs that are valid in the ring */ + for (i = rxq->rx_tail; i != rxq->rxrearm_start; i = (i+1) & mask) + rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf); + rxq->rxrearm_nb = rxq->nb_rx_desc; + + /* set all entries to NULL */ + memset(rxq->sw_ring, 0, sizeof(rxq->sw_ring[0]) * rxq->nb_rx_desc); } static void __attribute__((cold)) -- 1.8.3.1