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 BFE2E430D4; Wed, 23 Aug 2023 01:43:12 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A11AC406BA; Wed, 23 Aug 2023 01:43:12 +0200 (CEST) Received: from forward501b.mail.yandex.net (forward501b.mail.yandex.net [178.154.239.145]) by mails.dpdk.org (Postfix) with ESMTP id 4D51C4021E for ; Wed, 23 Aug 2023 01:43:11 +0200 (CEST) Received: from mail-nwsmtp-smtp-production-main-54.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-54.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1380:0:640:6985:0]) by forward501b.mail.yandex.net (Yandex) with ESMTP id 8E6E35EEB4; Wed, 23 Aug 2023 02:43:10 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-54.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id 6hTYRHsDTmI0-SpKF6xC5; Wed, 23 Aug 2023 02:43:10 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1692747790; bh=qcIOVwM5doRnce2n6mt7EBQBN2EahLz6abnd5qeeL3c=; h=From:In-Reply-To:Cc:Date:References:To:Subject:Message-ID; b=LfdvSDN+Eya27QSwUOGohBVCzqF8s1i9Z/W93zug7eg5tXMDTQ0xHYLlsBYtNm5aV 530WLUj4ZnHi/L4eryc45n5Am88rZdyT8rMbTRcrMkTyvWrEGUkQ35QMKq6jlVOwGL f/63j0FZu+aKeAeG7zHQdZ2ZL9I8RhHkmBI43vkA= Authentication-Results: mail-nwsmtp-smtp-production-main-54.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru Message-ID: <0e9a7f5e-74ab-3a18-57ad-055f7ce1d916@yandex.ru> Date: Wed, 23 Aug 2023 00:43:06 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 Subject: Re: [PATCH v11 2/4] net/i40e: implement mbufs recycle mode Content-Language: en-US To: Feifei Wang , Yuying Zhang , Beilei Xing Cc: dev@dpdk.org, nd@arm.com, Honnappa Nagarahalli , Ruifeng Wang References: <20220420081650.2043183-1-feifei.wang2@arm.com> <20230822072710.1945027-1-feifei.wang2@arm.com> <20230822072710.1945027-3-feifei.wang2@arm.com> From: Konstantin Ananyev In-Reply-To: <20230822072710.1945027-3-feifei.wang2@arm.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit 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 22/08/2023 08:27, Feifei Wang пишет: > Define specific function implementation for i40e driver. > Currently, mbufs recycle mode can support 128bit > vector path and avx2 path. And can be enabled both in > fast free and no fast free mode. > > Suggested-by: Honnappa Nagarahalli > Signed-off-by: Feifei Wang > Reviewed-by: Ruifeng Wang > Reviewed-by: Honnappa Nagarahalli > --- > drivers/net/i40e/i40e_ethdev.c | 1 + > drivers/net/i40e/i40e_ethdev.h | 2 + > .../net/i40e/i40e_recycle_mbufs_vec_common.c | 147 ++++++++++++++++++ > drivers/net/i40e/i40e_rxtx.c | 32 ++++ > drivers/net/i40e/i40e_rxtx.h | 4 + > drivers/net/i40e/meson.build | 1 + > 6 files changed, 187 insertions(+) > create mode 100644 drivers/net/i40e/i40e_recycle_mbufs_vec_common.c > > diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c > index 8271bbb394..50ba9aac94 100644 > --- a/drivers/net/i40e/i40e_ethdev.c > +++ b/drivers/net/i40e/i40e_ethdev.c > @@ -496,6 +496,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = { > .flow_ops_get = i40e_dev_flow_ops_get, > .rxq_info_get = i40e_rxq_info_get, > .txq_info_get = i40e_txq_info_get, > + .recycle_rxq_info_get = i40e_recycle_rxq_info_get, > .rx_burst_mode_get = i40e_rx_burst_mode_get, > .tx_burst_mode_get = i40e_tx_burst_mode_get, > .timesync_enable = i40e_timesync_enable, > diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h > index 6f65d5e0ac..af758798e1 100644 > --- a/drivers/net/i40e/i40e_ethdev.h > +++ b/drivers/net/i40e/i40e_ethdev.h > @@ -1355,6 +1355,8 @@ void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, > struct rte_eth_rxq_info *qinfo); > void i40e_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, > struct rte_eth_txq_info *qinfo); > +void i40e_recycle_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, > + struct rte_eth_recycle_rxq_info *recycle_rxq_info); > int i40e_rx_burst_mode_get(struct rte_eth_dev *dev, uint16_t queue_id, > struct rte_eth_burst_mode *mode); > int i40e_tx_burst_mode_get(struct rte_eth_dev *dev, uint16_t queue_id, > diff --git a/drivers/net/i40e/i40e_recycle_mbufs_vec_common.c b/drivers/net/i40e/i40e_recycle_mbufs_vec_common.c > new file mode 100644 > index 0000000000..5663ecccde > --- /dev/null > +++ b/drivers/net/i40e/i40e_recycle_mbufs_vec_common.c > @@ -0,0 +1,147 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright (c) 2023 Arm Limited. > + */ > + > +#include > +#include > + > +#include "base/i40e_prototype.h" > +#include "base/i40e_type.h" > +#include "i40e_ethdev.h" > +#include "i40e_rxtx.h" > + > +#pragma GCC diagnostic ignored "-Wcast-qual" > + > +void > +i40e_recycle_rx_descriptors_refill_vec(void *rx_queue, uint16_t nb_mbufs) > +{ > + struct i40e_rx_queue *rxq = rx_queue; > + struct i40e_rx_entry *rxep; > + volatile union i40e_rx_desc *rxdp; > + uint16_t rx_id; > + uint64_t paddr; > + uint64_t dma_addr; > + uint16_t i; > + > + rxdp = rxq->rx_ring + rxq->rxrearm_start; > + rxep = &rxq->sw_ring[rxq->rxrearm_start]; > + > + for (i = 0; i < nb_mbufs; i++) { > + /* Initialize rxdp descs. */ > + paddr = (rxep[i].mbuf)->buf_iova + RTE_PKTMBUF_HEADROOM; > + dma_addr = rte_cpu_to_le_64(paddr); > + /* flush desc with pa dma_addr */ > + rxdp[i].read.hdr_addr = 0; > + rxdp[i].read.pkt_addr = dma_addr; > + } > + > + /* Update the descriptor initializer index */ > + rxq->rxrearm_start += nb_mbufs; > + rx_id = rxq->rxrearm_start - 1; > + > + if (unlikely(rxq->rxrearm_start >= rxq->nb_rx_desc)) { > + rxq->rxrearm_start = 0; > + rx_id = rxq->nb_rx_desc - 1; > + } > + > + rxq->rxrearm_nb -= nb_mbufs; > + > + rte_io_wmb(); > + /* Update the tail pointer on the NIC */ > + I40E_PCI_REG_WRITE_RELAXED(rxq->qrx_tail, rx_id); > +} > + > +uint16_t > +i40e_recycle_tx_mbufs_reuse_vec(void *tx_queue, > + struct rte_eth_recycle_rxq_info *recycle_rxq_info) > +{ > + struct i40e_tx_queue *txq = tx_queue; > + struct i40e_tx_entry *txep; > + struct rte_mbuf **rxep; > + int i, n; > + uint16_t nb_recycle_mbufs; > + uint16_t avail = 0; > + uint16_t mbuf_ring_size = recycle_rxq_info->mbuf_ring_size; > + uint16_t mask = recycle_rxq_info->mbuf_ring_size - 1; > + uint16_t refill_requirement = recycle_rxq_info->refill_requirement; > + uint16_t refill_head = *recycle_rxq_info->refill_head; > + uint16_t receive_tail = *recycle_rxq_info->receive_tail; > + > + /* Get available recycling Rx buffers. */ > + avail = (mbuf_ring_size - (refill_head - receive_tail)) & mask; > + > + /* Check Tx free thresh and Rx available space. */ > + if (txq->nb_tx_free > txq->tx_free_thresh || avail <= txq->tx_rs_thresh) > + return 0; > + > + /* check DD bits on threshold descriptor */ > + if ((txq->tx_ring[txq->tx_next_dd].cmd_type_offset_bsz & > + rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) != > + rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE)) > + return 0; > + > + n = txq->tx_rs_thresh; > + nb_recycle_mbufs = n; > + > + /* Mbufs recycle mode can only support no ring buffer wrapping around. > + * Two case for this: > + * > + * case 1: The refill head of Rx buffer ring needs to be aligned with > + * mbuf ring size. In this case, the number of Tx freeing buffers > + * should be equal to refill_requirement. > + * > + * case 2: The refill head of Rx ring buffer does not need to be aligned > + * with mbuf ring size. In this case, the update of refill head can not > + * exceed the Rx mbuf ring size. > + */ > + if (refill_requirement != n || > + (!refill_requirement && (refill_head + n > mbuf_ring_size))) > + return 0; > + > + /* First buffer to free from S/W ring is at index > + * tx_next_dd - (tx_rs_thresh-1). > + */ > + txep = &txq->sw_ring[txq->tx_next_dd - (n - 1)]; > + rxep = recycle_rxq_info->mbuf_ring; > + rxep += refill_head; > + > + if (txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) { > + /* Avoid txq contains buffers from unexpected mempool. */ > + if (unlikely(recycle_rxq_info->mp > + != txep[0].mbuf->pool)) > + return 0; > + > + /* Directly put mbufs from Tx to Rx. */ > + for (i = 0; i < n; i++) > + rxep[i] = txep[i].mbuf; > + } else { > + for (i = 0; i < n; i++) { > + rxep[i] = rte_pktmbuf_prefree_seg(txep[i].mbuf); > + > + /* If Tx buffers are not the last reference or from > + * unexpected mempool, previous copied buffers are > + * considered as invalid. > + */ > + if (unlikely((rxep[i] == NULL && refill_requirement) || Could you pls remind me why it is ok to have rxep[i]==NULL when refill_requirement is not set? > + recycle_rxq_info->mp != txep[i].mbuf->pool)) > + nb_recycle_mbufs = 0; > + } > + /* If Tx buffers are not the last reference or > + * from unexpected mempool, all recycled buffers > + * are put into mempool. > + */ > + if (nb_recycle_mbufs == 0) > + for (i = 0; i < n; i++) { > + if (rxep[i] != NULL) > + rte_mempool_put(rxep[i]->pool, rxep[i]); > + } > + } > + > + /* Update counters for Tx. */ > + txq->nb_tx_free = (uint16_t)(txq->nb_tx_free + txq->tx_rs_thresh); > + txq->tx_next_dd = (uint16_t)(txq->tx_next_dd + txq->tx_rs_thresh); > + if (txq->tx_next_dd >= txq->nb_tx_desc) > + txq->tx_next_dd = (uint16_t)(txq->tx_rs_thresh - 1); > + > + return nb_recycle_mbufs; > +}