Skip to content

Commit d6d2b0e

Browse files
LorenzoBianconikuba-moo
authored andcommitted
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: e12182d ("net: airoha: Enable Rx Scatter-Gather") Signed-off-by: Lorenzo Bianconi <[email protected]> Link: https://patch.msgid.link/20250515-airoha-fix-rx-process-error-condition-v2-1-657e92c894b9@kernel.org Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 43f0999 commit d6d2b0e

File tree

1 file changed

+9
-13
lines changed

1 file changed

+9
-13
lines changed

drivers/net/ethernet/airoha/airoha_eth.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,6 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
614614
struct airoha_queue_entry *e = &q->entry[q->tail];
615615
struct airoha_qdma_desc *desc = &q->desc[q->tail];
616616
u32 hash, reason, msg1 = le32_to_cpu(desc->msg1);
617-
dma_addr_t dma_addr = le32_to_cpu(desc->addr);
618617
struct page *page = virt_to_head_page(e->buf);
619618
u32 desc_ctrl = le32_to_cpu(desc->ctrl);
620619
struct airoha_gdm_port *port;
@@ -623,22 +622,16 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
623622
if (!(desc_ctrl & QDMA_DESC_DONE_MASK))
624623
break;
625624

626-
if (!dma_addr)
627-
break;
628-
629-
len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl);
630-
if (!len)
631-
break;
632-
633625
q->tail = (q->tail + 1) % q->ndesc;
634626
q->queued--;
635627

636-
dma_sync_single_for_cpu(eth->dev, dma_addr,
628+
dma_sync_single_for_cpu(eth->dev, e->dma_addr,
637629
SKB_WITH_OVERHEAD(q->buf_size), dir);
638630

631+
len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl);
639632
data_len = q->skb ? q->buf_size
640633
: SKB_WITH_OVERHEAD(q->buf_size);
641-
if (data_len < len)
634+
if (!len || data_len < len)
642635
goto free_frag;
643636

644637
p = airoha_qdma_get_gdm_port(eth, desc);
@@ -701,9 +694,12 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
701694
q->skb = NULL;
702695
continue;
703696
free_frag:
704-
page_pool_put_full_page(q->page_pool, page, true);
705-
dev_kfree_skb(q->skb);
706-
q->skb = NULL;
697+
if (q->skb) {
698+
dev_kfree_skb(q->skb);
699+
q->skb = NULL;
700+
} else {
701+
page_pool_put_full_page(q->page_pool, page, true);
702+
}
707703
}
708704
airoha_qdma_fill_rx_queue(q);
709705

0 commit comments

Comments
 (0)