Просмотр исходного кода

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 <[email protected]>
Link: https://github.com/openwrt/openwrt/pull/19960
Signed-off-by: Robert Marko <[email protected]>
Markus Stockhausen 3 месяцев назад
Родитель
Сommit
2420a77556

+ 4 - 1
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;

+ 1 - 0
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)