lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240502045410.3524155-10-dw@davidwei.uk>
Date: Wed,  1 May 2024 21:54:10 -0700
From: David Wei <dw@...idwei.uk>
To: netdev@...r.kernel.org,
	Michael Chan <michael.chan@...adcom.com>,
	Pavan Chebbi <pavan.chebbi@...adcom.com>,
	Andy Gospodarek <andrew.gospodarek@...adcom.com>,
	Adrian Alvarado <adrian.alvarado@...adcom.com>,
	Mina Almasry <almasrymina@...gle.com>,
	Shailend Chand <shailend@...gle.com>
Cc: Jakub Kicinski <kuba@...nel.org>,
	"David S. Miller" <davem@...emloft.net>,
	Eric Dumazet <edumazet@...gle.com>,
	Paolo Abeni <pabeni@...hat.com>
Subject: [RFC PATCH net-next v2 9/9] bnxt: swap rx ring mem during queue_stop()

After stopping an rx ring in bnxt_queue_stop(), swap the preallocated
ring memory into the existing rx ring that the hardware is aware of. As
discussed in the last patch, the hardware ring is associated with the
address of static arrays in struct bnxt_rx_ring_info. For example:

struct bnxt_rx_ring_info              struct bnxt_ring_mem_info

struct rx_bd *rx_desc_ring[MAX]   <-> void **pg_arr
struct bnxt_sw_rx_bd *rx_buf_ring <-> void **vmem

The pg_tbl that is registered w/ the hardware via HWRM contains an array
of dma mappings to the pg_arr above. We can't touch this association
during reset, so can't simply swap the ring and its clone directly.

Instead, swap the ring memory only then update the pg_tbl. Functionally
it should be the same as the existing bnxt_rx_ring_reset(), except the
allocations happen before resetting the ring using a clone struct
bnxt_rx_ring_info.

Signed-off-by: David Wei <dw@...idwei.uk>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 54 +++++++++++++++++------
 1 file changed, 41 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index d848b9ceabf0..4dd4aa0911b1 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -15024,8 +15024,6 @@ static int bnxt_queue_start(struct net_device *dev, int idx, void *qmem)
 	struct bnxt_rx_ring_info *rxr = qmem;
 	struct bnxt *bp = netdev_priv(dev);
 
-	bnxt_alloc_one_rx_ring(bp, rxr);
-
 	if (bp->flags & BNXT_FLAG_AGG_RINGS)
 		bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod);
 	bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod);
@@ -15038,26 +15036,56 @@ static int bnxt_queue_start(struct net_device *dev, int idx, void *qmem)
 
 static int bnxt_queue_stop(struct net_device *dev, int idx, void **out_qmem)
 {
+	struct bnxt_rx_ring_info *orig, *rplc;
 	struct bnxt *bp = netdev_priv(dev);
-	struct bnxt_rx_ring_info *rxr;
+	struct bnxt_ring_mem_info *rmem;
 	struct bnxt_cp_ring_info *cpr;
-	int rc;
+	int i, rc;
 
 	rc = bnxt_hwrm_rx_ring_reset(bp, idx);
 	if (rc)
 		return rc;
 
-	rxr = &bp->rx_ring[idx];
-	bnxt_free_one_rx_ring_skbs(bp, rxr);
-	rxr->rx_prod = 0;
-	rxr->rx_agg_prod = 0;
-	rxr->rx_sw_agg_prod = 0;
-	rxr->rx_next_cons = 0;
-
-	cpr = &rxr->bnapi->cp_ring;
+	/* HW ring is registered w/ the original bnxt_rx_ring_info so we cannot
+	 * do a direct swap between orig and rplc. Instead, swap the
+	 * dynamically allocated queue memory and then update pg_tbl.
+	 */
+	orig = &bp->rx_ring[idx];
+	rplc = orig->rplc;
+
+	swap(orig->rx_prod, rplc->rx_prod);
+	swap(orig->rx_agg_prod, rplc->rx_agg_prod);
+	swap(orig->rx_sw_agg_prod, rplc->rx_sw_agg_prod);
+	swap(orig->rx_next_cons, rplc->rx_next_cons);
+
+	for (i = 0; i < MAX_RX_PAGES; i++) {
+		swap(orig->rx_desc_ring[i], rplc->rx_desc_ring[i]);
+		swap(orig->rx_desc_mapping[i], rplc->rx_desc_mapping[i]);
+
+		swap(orig->rx_agg_desc_ring[i], rplc->rx_agg_desc_ring[i]);
+		swap(orig->rx_agg_desc_mapping[i], rplc->rx_agg_desc_mapping[i]);
+	}
+	swap(orig->rx_buf_ring, rplc->rx_buf_ring);
+	swap(orig->rx_agg_ring, rplc->rx_agg_ring);
+	swap(orig->rx_agg_bmap, rplc->rx_agg_bmap);
+	swap(orig->rx_agg_bmap_size, rplc->rx_agg_bmap_size);
+	swap(orig->rx_tpa, rplc->rx_tpa);
+	swap(orig->rx_tpa_idx_map, rplc->rx_tpa_idx_map);
+	swap(orig->page_pool, rplc->page_pool);
+
+	rmem = &orig->rx_ring_struct.ring_mem;
+	for (i = 0; i < rmem->nr_pages; i++)
+		rmem->pg_tbl[i] = cpu_to_le64(rmem->dma_arr[i]);
+
+	rmem = &rplc->rx_ring_struct.ring_mem;
+	for (i = 0; i < rmem->nr_pages; i++)
+		rmem->pg_tbl[i] = cpu_to_le64(rmem->dma_arr[i]);
+
+	cpr = &orig->bnapi->cp_ring;
 	cpr->sw_stats.rx.rx_resets++;
 
-	*out_qmem = rxr;
+	*out_qmem = rplc;
+	orig->rplc = NULL;
 
 	return 0;
 }
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ