From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 66C6FA04FA; Thu, 26 Dec 2019 09:24:31 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id B9BCA1BF6D; Thu, 26 Dec 2019 09:24:30 +0100 (CET) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by dpdk.org (Postfix) with ESMTP id 78D3B1BF02 for ; Thu, 26 Dec 2019 09:24:29 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Dec 2019 00:24:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,358,1571727600"; d="scan'208";a="268790251" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by FMSMGA003.fm.intel.com with ESMTP; 26 Dec 2019 00:24:28 -0800 Received: from FMSMSX109.amr.corp.intel.com (10.18.116.9) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 26 Dec 2019 00:24:28 -0800 Received: from shsmsx102.ccr.corp.intel.com (10.239.4.154) by fmsmsx109.amr.corp.intel.com (10.18.116.9) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 26 Dec 2019 00:24:28 -0800 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.19]) by shsmsx102.ccr.corp.intel.com ([169.254.2.109]) with mapi id 14.03.0439.000; Thu, 26 Dec 2019 16:24:26 +0800 From: "Xing, Beilei" To: "Di, ChenxuX" , "dev@dpdk.org" CC: "Yang, Qiming" , "Di, ChenxuX" Thread-Topic: [dpdk-dev] [PATCH v4 2/5] net/i40e: cleanup Tx buffers Thread-Index: AQHVugPJGmVz+TwUhEOQXPGOCHKfrafMCH6g Date: Thu, 26 Dec 2019 08:24:26 +0000 Message-ID: <94479800C636CB44BD422CB454846E013CEB33E6@SHSMSX101.ccr.corp.intel.com> References: <20191203055134.72874-1-chenxux.di@intel.com> <20191224023906.60789-1-chenxux.di@intel.com> <20191224023906.60789-3-chenxux.di@intel.com> In-Reply-To: <20191224023906.60789-3-chenxux.di@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v4 2/5] net/i40e: cleanup Tx buffers X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Chenxu Di > Sent: Tuesday, December 24, 2019 10:39 AM > To: dev@dpdk.org > Cc: Yang, Qiming ; Di, ChenxuX > > Subject: [dpdk-dev] [PATCH v4 2/5] net/i40e: cleanup Tx buffers >=20 > Add support to the i40e driver for the API rte_eth_tx_done_cleanup to for= ce > free consumed buffers on Tx ring. >=20 > Signed-off-by: Chenxu Di > --- > drivers/net/i40e/i40e_ethdev.c | 1 + > drivers/net/i40e/i40e_ethdev_vf.c | 1 + > drivers/net/i40e/i40e_rxtx.c | 122 ++++++++++++++++++++++++++++++ > drivers/net/i40e/i40e_rxtx.h | 1 + > 4 files changed, 125 insertions(+) >=20 > diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethde= v.c > index 5999c964b..fad47a942 100644 > --- a/drivers/net/i40e/i40e_ethdev.c > +++ b/drivers/net/i40e/i40e_ethdev.c > @@ -522,6 +522,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops =3D = { > .mac_addr_set =3D i40e_set_default_mac_addr, > .mtu_set =3D i40e_dev_mtu_set, > .tm_ops_get =3D i40e_tm_ops_get, > + .tx_done_cleanup =3D i40e_tx_done_cleanup, > }; >=20 > /* store statistics names and its offset in stats structure */ diff --gi= t > a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c > index 5dba0928b..0ca5417d7 100644 > --- a/drivers/net/i40e/i40e_ethdev_vf.c > +++ b/drivers/net/i40e/i40e_ethdev_vf.c > @@ -215,6 +215,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = =3D { > .rss_hash_conf_get =3D i40evf_dev_rss_hash_conf_get, > .mtu_set =3D i40evf_dev_mtu_set, > .mac_addr_set =3D i40evf_set_default_mac_addr, > + .tx_done_cleanup =3D i40e_tx_done_cleanup, > }; >=20 > /* > diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c = index > 17dc8c78f..e75733b8e 100644 > --- a/drivers/net/i40e/i40e_rxtx.c > +++ b/drivers/net/i40e/i40e_rxtx.c > @@ -2455,6 +2455,128 @@ i40e_tx_queue_release_mbufs(struct > i40e_tx_queue *txq) > } > } >=20 > +int i40e_tx_done_cleanup(void *q, uint32_t free_cnt) { > + struct i40e_tx_queue *txq =3D (struct i40e_tx_queue *)q; > + struct i40e_tx_entry *sw_ring; > + volatile struct i40e_tx_desc *txr; > + uint16_t tx_first; /* First segment analyzed. */ > + uint16_t tx_id; /* Current segment being processed. */ > + uint16_t tx_last; /* Last segment in the current packet. */ > + uint16_t tx_next; /* First segment of the next packet. */ > + int count; > + > + if (txq =3D=3D NULL) > + return -ENODEV; > + > + count =3D 0; > + sw_ring =3D txq->sw_ring; > + txr =3D txq->tx_ring; > + > + /* > + * tx_tail is the last sent packet on the sw_ring. Goto the end > + * of that packet (the last segment in the packet chain) and > + * then the next segment will be the start of the oldest segment > + * in the sw_ring. This is the first packet that will be > + * attempted to be freed. > + */ > + > + /* Get last segment in most recently added packet. */ > + tx_first =3D sw_ring[txq->tx_tail].last_id; Should be tx_last more readable here? And then tx_first =3D sw_ring[tx_last= ].next_id? > + > + /* Get the next segment, which is the oldest segment in ring. */ > + tx_first =3D sw_ring[tx_first].next_id; > + > + /* Set the current index to the first. */ > + tx_id =3D tx_first; > + > + /* > + * Loop through each packet. For each packet, verify that an > + * mbuf exists and that the last segment is free. If so, free > + * it and move on. > + */ > + while (1) { > + tx_last =3D sw_ring[tx_id].last_id; > + > + if (sw_ring[tx_last].mbuf) { > + if ((txr[tx_last].cmd_type_offset_bsz & > + > rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) !=3D Is the logic reversed? '!=3D' means the mbuf is still in use. > + > rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE)) { > + /* > + * Increment the number of packets > + * freed. > + */ > + count++; Should 'count++' be after free mbuf? > + > + /* Get the start of the next packet. */ > + tx_next =3D sw_ring[tx_last].next_id; > + > + /* > + * Loop through all segments in a > + * packet. > + */ > + do { > + > rte_pktmbuf_free_seg(sw_ring[tx_id].mbuf); > + sw_ring[tx_id].mbuf =3D NULL; > + sw_ring[tx_id].last_id =3D tx_id; > + > + /* Move to next segemnt. */ Typo: segemnt -> segment > + tx_id =3D sw_ring[tx_id].next_id; > + > + } while (tx_id !=3D tx_next); > + > + if (unlikely(count =3D=3D (int)free_cnt)) > + break; > + } else { > + /* > + * mbuf still in use, nothing left to > + * free. > + */ > + break; > + } > + } else { > + /* > + * There are multiple reasons to be here: > + * 1) All the packets on the ring have been > + * freed - tx_id is equal to tx_first > + * and some packets have been freed. > + * - Done, exit > + * 2) Interfaces has not sent a rings worth of > + * packets yet, so the segment after tail is > + * still empty. Or a previous call to this > + * function freed some of the segments but > + * not all so there is a hole in the list. > + * Hopefully this is a rare case. > + * - Walk the list and find the next mbuf. If > + * there isn't one, then done. > + */ > + if (likely(tx_id =3D=3D tx_first && count !=3D 0)) > + break; > + > + /* > + * Walk the list and find the next mbuf, if any. > + */ > + do { > + /* Move to next segemnt. */ Typo: segemnt -> segment > + tx_id =3D sw_ring[tx_id].next_id; > + > + if (sw_ring[tx_id].mbuf) > + break; > + > + } while (tx_id !=3D tx_first); > + > + /* > + * Determine why previous loop bailed. If there > + * is not an mbuf, done. > + */ > + if (sw_ring[tx_id].mbuf =3D=3D NULL) > + break; > + } > + } > + > + return count; > +} > + > void > i40e_reset_tx_queue(struct i40e_tx_queue *txq) { diff --git > a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h index > 2106bb355..8f11f011a 100644 > --- a/drivers/net/i40e/i40e_rxtx.h > +++ b/drivers/net/i40e/i40e_rxtx.h > @@ -212,6 +212,7 @@ void i40e_dev_free_queues(struct rte_eth_dev *dev); > void i40e_reset_rx_queue(struct i40e_rx_queue *rxq); void > i40e_reset_tx_queue(struct i40e_tx_queue *txq); void > i40e_tx_queue_release_mbufs(struct i40e_tx_queue *txq); > +int i40e_tx_done_cleanup(void *txq, uint32_t free_cnt); > int i40e_alloc_rx_queue_mbufs(struct i40e_rx_queue *rxq); void > i40e_rx_queue_release_mbufs(struct i40e_rx_queue *rxq); >=20 > -- > 2.17.1