mirror of
https://github.com/breeze303/nss-packages.git
synced 2025-12-16 16:57:29 +00:00
nss-dp: edma-v1: convert rx/tx store to idr implementation
Add patch to convert rx/tx store to idr implementation Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
parent
76602b9c18
commit
2c27cb4ce1
@ -0,0 +1,239 @@
|
||||
From e80ad87476fe55f602c4e76f6b1068036b34b7a0 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 24 Jun 2022 15:04:44 +0200
|
||||
Subject: [PATCH 1/3] edma_v1: convert rx/tx_store to idr implementation
|
||||
|
||||
Convert rx/tx store to idr implementation to correctly scale in
|
||||
preparation for support of multiqueue implementation.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
hal/dp_ops/edma_dp/edma_v1/edma_cfg.c | 32 +++++++++----
|
||||
hal/dp_ops/edma_dp/edma_v1/edma_data_plane.h | 8 +++-
|
||||
hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c | 49 ++++++++++++++------
|
||||
3 files changed, 63 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/hal/dp_ops/edma_dp/edma_v1/edma_cfg.c b/hal/dp_ops/edma_dp/edma_v1/edma_cfg.c
|
||||
index fbd315a..2e98aaf 100644
|
||||
--- a/hal/dp_ops/edma_dp/edma_v1/edma_cfg.c
|
||||
+++ b/hal/dp_ops/edma_dp/edma_v1/edma_cfg.c
|
||||
@@ -72,8 +72,12 @@ static void edma_cleanup_rxfill_ring_res(struct edma_hw *ehw,
|
||||
* Get sk_buff and free it
|
||||
*/
|
||||
store_idx = rxph->opaque;
|
||||
- skb = ehw->rx_skb_store[store_idx];
|
||||
- ehw->rx_skb_store[store_idx] = NULL;
|
||||
+
|
||||
+ spin_lock_bh(&ehw->rx_skb_idr_lock);
|
||||
+ skb = idr_find(&ehw->rx_skb_idr, store_idx);
|
||||
+ idr_remove(&ehw->rx_skb_idr, store_idx);
|
||||
+ spin_unlock_bh(&ehw->rx_skb_idr_lock);
|
||||
+
|
||||
dev_kfree_skb_any(skb);
|
||||
cons_idx++;
|
||||
if (cons_idx == rxfill_ring->count)
|
||||
@@ -173,8 +177,12 @@ static void edma_cleanup_rxdesc_ring_res(struct edma_hw *ehw,
|
||||
dma_unmap_single(&pdev->dev, rxdesc_desc->buffer_addr,
|
||||
ehw->rx_alloc_size, DMA_FROM_DEVICE);
|
||||
store_idx = rxph->opaque;
|
||||
- skb = ehw->rx_skb_store[store_idx];
|
||||
- ehw->rx_skb_store[store_idx] = NULL;
|
||||
+
|
||||
+ spin_lock_bh(&ehw->rx_skb_idr_lock);
|
||||
+ skb = idr_find(&ehw->rx_skb_idr, store_idx);
|
||||
+ idr_remove(&ehw->rx_skb_idr, store_idx);
|
||||
+ spin_unlock_bh(&ehw->rx_skb_idr_lock);
|
||||
+
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
/*
|
||||
@@ -270,8 +278,11 @@ static void edma_cleanup_txdesc_ring_res(struct edma_hw *ehw,
|
||||
while (cons_idx != prod_idx) {
|
||||
txdesc = EDMA_TXDESC_DESC(txdesc_ring, cons_idx);
|
||||
store_idx = txdesc->buffer_addr;
|
||||
- skb = ehw->tx_skb_store[store_idx];
|
||||
- ehw->tx_skb_store[store_idx] = NULL;
|
||||
+
|
||||
+ spin_lock_bh(&ehw->tx_skb_idr_lock);
|
||||
+ skb = idr_find(&ehw->tx_skb_idr, store_idx);
|
||||
+ idr_remove(&ehw->tx_skb_idr, store_idx);
|
||||
+ spin_unlock_bh(&ehw->tx_skb_idr_lock);
|
||||
|
||||
buf_len = (txdesc->word1 & EDMA_TXDESC_DATA_LENGTH_MASK) >>
|
||||
EDMA_TXDESC_DATA_LENGTH_SHIFT;
|
||||
@@ -675,10 +686,11 @@ static void edma_configure_rings(struct edma_hw *ehw)
|
||||
/*
|
||||
* Initialize the store
|
||||
*/
|
||||
- for (i = 0; i < EDMA_RING_SIZE; i++) {
|
||||
- ehw->tx_skb_store[i] = NULL;
|
||||
- ehw->rx_skb_store[i] = NULL;
|
||||
- }
|
||||
+ idr_init(&ehw->rx_skb_idr);
|
||||
+ spin_lock_init(&ehw->rx_skb_idr_lock);
|
||||
+
|
||||
+ idr_init(&ehw->tx_skb_idr);
|
||||
+ spin_lock_init(&ehw->tx_skb_idr_lock);
|
||||
|
||||
/*
|
||||
* Configure TXDESC ring
|
||||
diff --git a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.h b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.h
|
||||
index 0b28fe8..2bbe478 100644
|
||||
--- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.h
|
||||
+++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.h
|
||||
@@ -44,6 +44,8 @@
|
||||
#define EDMA_RXPH_SRC_INFO_TYPE_GET(rxph) (((rxph)->src_info >> 8) & 0xf0)
|
||||
#define EDMA_RXPH_SERVICE_CODE_GET(rxph) (((rxph)->rx_pre4) & 0xff)
|
||||
|
||||
+#define EDMA_TX_IDR_MAX EDMA_RING_SIZE * EDMA_MAX_TXDESC_RINGS
|
||||
+#define EDMA_RX_IDR_MAX EDMA_RING_SIZE * EDMA_MAX_RXDESC_RINGS
|
||||
/*
|
||||
* Tx descriptor
|
||||
*/
|
||||
@@ -202,8 +204,10 @@ struct edma_hw {
|
||||
/*
|
||||
* Store for tx and rx skbs
|
||||
*/
|
||||
- struct sk_buff *rx_skb_store[EDMA_RING_SIZE];
|
||||
- struct sk_buff *tx_skb_store[EDMA_RING_SIZE];
|
||||
+ struct idr rx_skb_idr;
|
||||
+ spinlock_t rx_skb_idr_lock;
|
||||
+ struct idr tx_skb_idr;
|
||||
+ spinlock_t tx_skb_idr_lock;
|
||||
|
||||
struct edma_rxfill_ring *rxfill_ring;
|
||||
/* Rx Fill Ring, SW is producer */
|
||||
diff --git a/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c b/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c
|
||||
index 5780a30..8cded66 100644
|
||||
--- a/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c
|
||||
+++ b/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c
|
||||
@@ -37,9 +37,9 @@ int edma_alloc_rx_buffer(struct edma_hw *ehw,
|
||||
uint16_t cons, next, counter;
|
||||
struct edma_rxfill_desc *rxfill_desc;
|
||||
uint32_t reg_data = 0;
|
||||
- uint32_t store_index = 0;
|
||||
uint32_t alloc_size = ehw->rx_alloc_size;
|
||||
struct edma_rx_preheader *rxph = NULL;
|
||||
+ int store_index;
|
||||
|
||||
/*
|
||||
* Read RXFILL ring producer index
|
||||
@@ -82,12 +82,16 @@ int edma_alloc_rx_buffer(struct edma_hw *ehw,
|
||||
/*
|
||||
* Store the skb in the rx store
|
||||
*/
|
||||
- store_index = next;
|
||||
- if (ehw->rx_skb_store[store_index] != NULL) {
|
||||
+ spin_lock_bh(&ehw->rx_skb_idr_lock);
|
||||
+ store_index = idr_alloc(&ehw->rx_skb_idr,
|
||||
+ skb, 0, EDMA_RX_IDR_MAX, GFP_ATOMIC);
|
||||
+ spin_unlock_bh(&ehw->rx_skb_idr_lock);
|
||||
+
|
||||
+ if (store_index < 0) {
|
||||
dev_kfree_skb_any(skb);
|
||||
break;
|
||||
}
|
||||
- ehw->rx_skb_store[store_index] = skb;
|
||||
+
|
||||
memcpy((uint8_t *)&rxph->opaque, (uint8_t *)&store_index, 4);
|
||||
/*
|
||||
* Save buffer size in RXFILL descriptor
|
||||
@@ -106,7 +110,9 @@ int edma_alloc_rx_buffer(struct edma_hw *ehw,
|
||||
|
||||
if (!rxfill_desc->buffer_addr) {
|
||||
dev_kfree_skb_any(skb);
|
||||
- ehw->rx_skb_store[store_index] = NULL;
|
||||
+ spin_lock_bh(&ehw->rx_skb_idr_lock);
|
||||
+ idr_remove(&ehw->rx_skb_idr, store_index);
|
||||
+ spin_unlock_bh(&ehw->rx_skb_idr_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -173,15 +179,19 @@ uint32_t edma_clean_tx(struct edma_hw *ehw,
|
||||
* buffer address (opaque) of txcmpl
|
||||
*/
|
||||
store_index = txcmpl->buffer_addr;
|
||||
- skb = ehw->tx_skb_store[store_index];
|
||||
- ehw->tx_skb_store[store_index] = NULL;
|
||||
+ spin_lock_bh(&ehw->tx_skb_idr_lock);
|
||||
+ skb = idr_find(&ehw->tx_skb_idr, store_index);
|
||||
|
||||
if (unlikely(!skb)) {
|
||||
pr_warn("Invalid skb: cons_idx:%u prod_idx:%u status %x\n",
|
||||
cons_idx, prod_idx, txcmpl->status);
|
||||
+ spin_unlock_bh(&ehw->tx_skb_idr_lock);
|
||||
goto next_txcmpl_desc;
|
||||
}
|
||||
|
||||
+ idr_remove(&ehw->tx_skb_idr, store_index);
|
||||
+ spin_unlock_bh(&ehw->tx_skb_idr_lock);
|
||||
+
|
||||
len = skb_headlen(skb);
|
||||
daddr = (dma_addr_t)virt_to_phys(skb->data);
|
||||
|
||||
@@ -322,14 +332,19 @@ static uint32_t edma_clean_rx(struct edma_hw *ehw,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
store_index = rxph->opaque;
|
||||
- skb = ehw->rx_skb_store[store_index];
|
||||
- ehw->rx_skb_store[store_index] = NULL;
|
||||
+ spin_lock_bh(&ehw->rx_skb_idr_lock);
|
||||
+ skb = idr_find(&ehw->rx_skb_idr, store_index);
|
||||
+
|
||||
if (unlikely(!skb)) {
|
||||
+ spin_unlock_bh(&ehw->rx_skb_idr_lock);
|
||||
pr_warn("WARN: empty skb reference in rx_store:%d\n",
|
||||
cons_idx);
|
||||
goto next_rx_desc;
|
||||
}
|
||||
|
||||
+ idr_remove(&ehw->rx_skb_idr, store_index);
|
||||
+ spin_unlock_bh(&ehw->rx_skb_idr_lock);
|
||||
+
|
||||
/*
|
||||
* Check src_info from Rx preheader
|
||||
*/
|
||||
@@ -539,7 +554,7 @@ enum edma_tx edma_ring_xmit(struct edma_hw *ehw,
|
||||
uint16_t buf_len;
|
||||
uint16_t hw_next_to_use, hw_next_to_clean, chk_idx;
|
||||
uint32_t data;
|
||||
- uint32_t store_index = 0;
|
||||
+ int store_index = 0;
|
||||
struct edma_tx_preheader *txph = NULL;
|
||||
|
||||
/*
|
||||
@@ -616,13 +631,16 @@ enum edma_tx edma_ring_xmit(struct edma_hw *ehw,
|
||||
/*
|
||||
* Store the skb in tx_store
|
||||
*/
|
||||
- store_index = hw_next_to_use & (txdesc_ring->count - 1);
|
||||
- if (unlikely(ehw->tx_skb_store[store_index] != NULL)) {
|
||||
+ spin_lock_bh(&ehw->tx_skb_idr_lock);
|
||||
+ store_index = idr_alloc(&ehw->tx_skb_idr,
|
||||
+ skb, 0, EDMA_RX_IDR_MAX, GFP_ATOMIC);
|
||||
+ spin_unlock_bh(&ehw->tx_skb_idr_lock);
|
||||
+
|
||||
+ if (unlikely(store_index < 0)) {
|
||||
spin_unlock_bh(&txdesc_ring->tx_lock);
|
||||
return EDMA_TX_DESC;
|
||||
}
|
||||
|
||||
- ehw->tx_skb_store[store_index] = skb;
|
||||
memcpy(skb->data, &store_index, 4);
|
||||
|
||||
/*
|
||||
@@ -645,7 +663,10 @@ enum edma_tx edma_ring_xmit(struct edma_hw *ehw,
|
||||
*/
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
- ehw->tx_skb_store[store_index] = NULL;
|
||||
+ spin_lock_bh(&ehw->tx_skb_idr_lock);
|
||||
+ idr_remove(&ehw->tx_skb_idr, store_index);
|
||||
+ spin_unlock_bh(&ehw->tx_skb_idr_lock);
|
||||
+
|
||||
spin_unlock_bh(&txdesc_ring->tx_lock);
|
||||
return EDMA_TX_OK;
|
||||
}
|
||||
--
|
||||
2.36.1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user