[PATCH net-next v2 12/14] net: macb: re-read ISR inside IRQ handler locked section

Théo Lebrun
2026-04-10T19:52:39Z

The IRQ handler reads ISR register into the `status` stack variable.
If empty, it early returns. Else, it grabs bp->lock and iterates on
the status bits.

If we tried grabbing bp->lock while already acquired, we might have
slept and the status might have been updated. Our most likely
competitor in this race (condition) is a swap operation, used in
change_mtu and set_ringparam. It is the only MACB codepath that resets
interrupts and HW inside a bp->lock critical section. Other codepaths
that clear HW IRQ status do so outside the bp->lock critical section.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
drivers/net/ethernet/cadence/macb_main.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index ba7463a857dd..81beb67b206a 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -2190,6 +2190,13 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)

spin_lock(&bp->lock);

+ /* `status` stack variable might be stalled => re-read it */
+ status = queue_readl(queue, ISR);
+ if (unlikely(!status)) {
+ spin_unlock(&bp->lock);
+ return IRQ_NONE;
+ }
+
while (status) {
/* close possible race with dev_close */
if (unlikely(!netif_running(netdev))) {

--
2.53.0