[<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