This is an automatically generated commit. When doing `git bisect`, consider `git bisect --skip`. Signed-off-by: Kenneth Kasilag <kenneth@kasilag.me> Link: https://github.com/openwrt/openwrt/pull/21019 Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
73 lines
2.5 KiB
Diff
73 lines
2.5 KiB
Diff
From d6d2b0e1538d5c381ec0ca95afaf772c096ea5dc Mon Sep 17 00:00:00 2001
|
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
|
Date: Thu, 15 May 2025 08:33:06 +0200
|
|
Subject: [PATCH] net: airoha: Fix page recycling in airoha_qdma_rx_process()
|
|
|
|
Do not recycle the page twice in airoha_qdma_rx_process routine in case
|
|
of error. Just run dev_kfree_skb() if the skb has been allocated and marked
|
|
for recycling. Run page_pool_put_full_page() directly if the skb has not
|
|
been allocated yet.
|
|
Moreover, rely on DMA address from queue entry element instead of reading
|
|
it from the DMA descriptor for DMA syncing in airoha_qdma_rx_process().
|
|
|
|
Fixes: e12182ddb6e71 ("net: airoha: Enable Rx Scatter-Gather")
|
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
|
Link: https://patch.msgid.link/20250515-airoha-fix-rx-process-error-condition-v2-1-657e92c894b9@kernel.org
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
---
|
|
drivers/net/ethernet/airoha/airoha_eth.c | 22 +++++++++-------------
|
|
1 file changed, 9 insertions(+), 13 deletions(-)
|
|
|
|
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
|
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
|
@@ -636,7 +636,6 @@ static int airoha_qdma_rx_process(struct
|
|
struct airoha_queue_entry *e = &q->entry[q->tail];
|
|
struct airoha_qdma_desc *desc = &q->desc[q->tail];
|
|
u32 hash, reason, msg1 = le32_to_cpu(desc->msg1);
|
|
- dma_addr_t dma_addr = le32_to_cpu(desc->addr);
|
|
struct page *page = virt_to_head_page(e->buf);
|
|
u32 desc_ctrl = le32_to_cpu(desc->ctrl);
|
|
struct airoha_gdm_port *port;
|
|
@@ -645,22 +644,16 @@ static int airoha_qdma_rx_process(struct
|
|
if (!(desc_ctrl & QDMA_DESC_DONE_MASK))
|
|
break;
|
|
|
|
- if (!dma_addr)
|
|
- break;
|
|
-
|
|
- len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl);
|
|
- if (!len)
|
|
- break;
|
|
-
|
|
q->tail = (q->tail + 1) % q->ndesc;
|
|
q->queued--;
|
|
|
|
- dma_sync_single_for_cpu(eth->dev, dma_addr,
|
|
+ dma_sync_single_for_cpu(eth->dev, e->dma_addr,
|
|
SKB_WITH_OVERHEAD(q->buf_size), dir);
|
|
|
|
+ len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl);
|
|
data_len = q->skb ? q->buf_size
|
|
: SKB_WITH_OVERHEAD(q->buf_size);
|
|
- if (data_len < len)
|
|
+ if (!len || data_len < len)
|
|
goto free_frag;
|
|
|
|
p = airoha_qdma_get_gdm_port(eth, desc);
|
|
@@ -723,9 +716,12 @@ static int airoha_qdma_rx_process(struct
|
|
q->skb = NULL;
|
|
continue;
|
|
free_frag:
|
|
- page_pool_put_full_page(q->page_pool, page, true);
|
|
- dev_kfree_skb(q->skb);
|
|
- q->skb = NULL;
|
|
+ if (q->skb) {
|
|
+ dev_kfree_skb(q->skb);
|
|
+ q->skb = NULL;
|
|
+ } else {
|
|
+ page_pool_put_full_page(q->page_pool, page, true);
|
|
+ }
|
|
}
|
|
airoha_qdma_fill_rx_queue(q);
|
|
|