From: "Théo Lebrun" <theo.lebrun@bootlin.com>
To: Conor Dooley <conor.dooley@microchip.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
Nicolas Ferre <nicolas.ferre@microchip.com>,
Sean Anderson <sean.anderson@linux.dev>,
Antoine Tenart <atenart@kernel.org>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
"Nicolai Buchwitz" <nb@tipi-net.de>,
"Vladimir Kondratiev" <vladimir.kondratiev@mobileye.com>,
"Gregory CLEMENT" <gregory.clement@bootlin.com>,
"Tawfik Bayouk" <tawfik.bayouk@mobileye.com>,
"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>,
stable@vger.kernel.org, "Théo Lebrun" <theo.lebrun@bootlin.com>
Subject: [PATCH net] net: macb: take bp->lock around NCR read-modify-writes
Date: Fri, 18 Sep 2026 21:59:35 +0200 [thread overview]
Message-ID: <20260918-macb-ncr-rmw-v1-1-30c3494f93cd@bootlin.com> (raw)
NCR is read-modify-written from many contexts:
- macb_mac_link_down() clears RE|TE,
- macb_mac_link_up() sets RE|TE|PTPUNI,
- macb_hresp_error_task() clears then re-sets RE|TE,
- macb_start_xmit() / macb_tx_restart() / macb_tx_error_task() set
TSTART (already under bp->lock),
- macb_interrupt() might toggle RE (also under bp->lock).
The first three risk concurrent RMW with anyone from the list as they
don't grab bp->lock.
Theoretical bugfix only, it has never reproduced on hardware. Also note
it does *not* take the lock hoping to protect against full races
inbetween BH scheduling concurrently. We only want to ensure consistent
NCR RMW operations.
Fixes: 7897b071ac3b ("net: macb: convert to phylink")
Cc: stable@vger.kernel.org
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
drivers/net/ethernet/cadence/macb_main.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index b8234ac4b602..b58d3f01f2cc 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -777,6 +777,7 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode,
struct net_device *netdev = to_net_dev(config->dev);
struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
+ unsigned long flags;
unsigned int q;
u32 ctrl;
@@ -786,8 +787,10 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode,
bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP));
/* Disable Rx and Tx */
+ spin_lock_irqsave(&bp->lock, flags);
ctrl = macb_readl(bp, NCR) & ~(MACB_BIT(RE) | MACB_BIT(TE));
macb_writel(bp, NCR, ctrl);
+ spin_unlock_irqrestore(&bp->lock, flags);
netif_tx_stop_all_queues(netdev);
}
@@ -940,11 +943,13 @@ static void macb_mac_link_up(struct phylink_config *config,
}
/* Enable Rx and Tx; Enable PTP unicast */
+ spin_lock_irqsave(&bp->lock, flags);
ctrl = macb_readl(bp, NCR);
if (gem_has_ptp(bp))
ctrl |= MACB_BIT(PTPUNI);
macb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE));
+ spin_unlock_irqrestore(&bp->lock, flags);
netif_tx_wake_all_queues(netdev);
}
@@ -1995,6 +2000,7 @@ static void macb_hresp_error_task(struct work_struct *work)
struct macb *bp = from_work(bp, work, hresp_err_bh_work);
struct net_device *netdev = bp->netdev;
struct macb_queue *queue;
+ unsigned long flags;
unsigned int q;
u32 ctrl;
@@ -2003,9 +2009,11 @@ static void macb_hresp_error_task(struct work_struct *work)
MACB_TX_INT_FLAGS |
MACB_BIT(HRESP));
}
+ spin_lock_irqsave(&bp->lock, flags);
ctrl = macb_readl(bp, NCR);
ctrl &= ~(MACB_BIT(RE) | MACB_BIT(TE));
macb_writel(bp, NCR, ctrl);
+ spin_unlock_irqrestore(&bp->lock, flags);
netif_tx_stop_all_queues(netdev);
netif_carrier_off(netdev);
@@ -2022,8 +2030,10 @@ static void macb_hresp_error_task(struct work_struct *work)
MACB_TX_INT_FLAGS |
MACB_BIT(HRESP));
- ctrl |= MACB_BIT(RE) | MACB_BIT(TE);
- macb_writel(bp, NCR, ctrl);
+ spin_lock_irqsave(&bp->lock, flags);
+ ctrl = MACB_BIT(RE) | MACB_BIT(TE);
+ macb_writel(bp, NCR, macb_readl(bp, NCR) | ctrl);
+ spin_unlock_irqrestore(&bp->lock, flags);
netif_carrier_on(netdev);
netif_tx_start_all_queues(netdev);
---
base-commit: 994db8ab9d90c64dd641b7ead6efe2eaea7a50dc
change-id: 20260918-macb-ncr-rmw-be5137e60f0b
Best regards,
--
Théo Lebrun <theo.lebrun@bootlin.com>
next reply other threads:[~2026-09-18 19:59 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-18 19:59 Théo Lebrun [this message]
2026-09-18 20:31 ` [PATCH net] net: macb: take bp->lock around NCR read-modify-writes Nicolai Buchwitz
2026-09-21 14:36 ` Théo Lebrun
2026-09-22 8:00 ` netdev-bot+sashiko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260918-macb-ncr-rmw-v1-1-30c3494f93cd@bootlin.com \
--to=theo.lebrun@bootlin.com \
--cc=andrew+netdev@lunn.ch \
--cc=atenart@kernel.org \
--cc=conor.dooley@microchip.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=gregory.clement@bootlin.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nb@tipi-net.de \
--cc=netdev@vger.kernel.org \
--cc=nicolas.ferre@microchip.com \
--cc=pabeni@redhat.com \
--cc=sean.anderson@linux.dev \
--cc=stable@vger.kernel.org \
--cc=tawfik.bayouk@mobileye.com \
--cc=thomas.petazzoni@bootlin.com \
--cc=vladimir.kondratiev@mobileye.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox