[openwrt/openwrt] realtek: make NAPI polling thread safe

LEDE Commits lede-commits at lists.infradead.org
Sun Sep 7 02:36:08 PDT 2025


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/2420a7755665d50c7bbd0fefb13a36eb0457bcbd

commit 2420a7755665d50c7bbd0fefb13a36eb0457bcbd
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Fri Sep 5 02:53:41 2025 -0400

    realtek: make NAPI polling thread safe
    
    At the end of RX NAPI polling the counter and mask registers are
    cleaned up. Although this might run in parallel there is no
    synchronization and the register modifications are some wild mix.
    RTL83xx enables only the interrupt of a single ring while RTL93xx
    just reactivates all interrupts (even for other NAPI threads).
    Make use of the driver lock and only modify the interrupt bits that
    the current thread owns.
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/19960
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c | 5 ++++-
 target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c
index 1ed3718cb3..d2d4d0bf7c 100644
--- a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c
+++ b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c
@@ -1300,6 +1300,7 @@ static int rtl838x_poll_rx(struct napi_struct *napi, int budget)
 {
 	struct rtl838x_rx_q *rx_q = container_of(napi, struct rtl838x_rx_q, napi);
 	struct rtl838x_eth_priv *priv = rx_q->priv;
+	unsigned long flags;
 	int ring = rx_q->id;
 	int work_done = 0;
 
@@ -1312,10 +1313,12 @@ static int rtl838x_poll_rx(struct napi_struct *napi, int budget)
 
 	if (work_done < budget && napi_complete_done(napi, work_done)) {
 		/* Re-enable rx interrupts */
+		spin_lock_irqsave(&priv->lock, flags);
 		if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID)
-			sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_msk);
+			sw_w32_mask(0, RTL93XX_DMA_IF_INTR_RX_MASK(ring), priv->r->dma_if_intr_rx_done_msk);
 		else
 			sw_w32_mask(0, RTL83XX_DMA_IF_INTR_RX_MASK(ring), priv->r->dma_if_intr_msk);
+		spin_unlock_irqrestore(&priv->lock, flags);
 	}
 
 	return work_done;
diff --git a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h
index 458718750c..f1e4b17609 100644
--- a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h
+++ b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h
@@ -52,6 +52,7 @@
 #define RTL83XX_DMA_IF_INTR_RX_DONE_MASK	GENMASK(15, 8)
 #define RTL83XX_DMA_IF_INTR_RX_RUN_OUT_MASK	GENMASK(7, 0)
 #define RTL83XX_DMA_IF_INTR_RX_MASK(ring)	(BIT(ring) | BIT(ring + 8))
+#define RTL93XX_DMA_IF_INTR_RX_MASK(ring)	(BIT(ring))
 
 /* MAC address settings */
 #define RTL838X_MAC				(0xa9ec)




More information about the lede-commits mailing list