From: Nicolai Buchwitz <nb@tipi-net.de>
To: netdev-bot+sashiko@kernel.org
Cc: opendmb@gmail.com, florian.fainelli@broadcom.com,
bcm-kernel-feedback-list@broadcom.com, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
pabeni@redhat.com, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, dave.stevenson@raspberrypi.com,
justin.chen@broadcom.com, pierremarinleclercq88@gmail.com,
f.fainelli@gmail.com
Subject: Re: [PATCH net-next v4 7/8] net: bcmgenet: allow the MTU to be changed
Date: Tue, 13 Oct 2026 15:44:59 +0200 [thread overview]
Message-ID: <92aa4715d68679c8c33d4c40bdd75ae5@tipi-net.de> (raw)
In-Reply-To: <179188315964.434549.2607094947649815116@kernel.org>
On 13.10.2026 11:19, netdev-bot+sashiko@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential
> issue(s) to consider.
>
> Critical: 0 · High: 0 (1) · Medium: 2 · Low: 1
>
> If you believe none of the issues are legitimate, please reply to each
> issue of Medium severity or higher and explain why the AI is wrong.
> If any of them are legitimate and you plan to respin, please let
> patchwork
> know by including "pw-bot: cr" as a separate line at the end of your
> reply
> (one such reply per series is enough).
>
> - [Medium] An RX filter update can be lost during the MTU change.
> - [Medium] The live MTU change leaves the PHY state machine running
> (bcmgenet_netif_stop(dev, false)), but nothing stops the PHY link…
> - [Low] The patch fixes two existing bugs, but neither the commit
> message
> nor a Fixes: tag mentions them.
>
> Pre-existing issues:
> - [High] This problem wasn't introduced by this patch, but the patch
> adds
> priv->datapath_up and leaves this path unguarded.
>
> --
>
> net: bcmgenet: allow the MTU to be changed
>
> This commit sets dev->max_mtu for GENET v2 and later, derived from the
> packet ready threshold and the one page descriptor limit. It adds an
> ndo_change_mtu that rebuilds the DMA rings and MTU registers in place
> while
> the PHY keeps running, and retries the old MTU if allocation fails. A
> new
> priv->datapath_up flag tracks whether the datapath has already been
> torn
> down.
>
> Link: https://github.com/raspberrypi/linux/issues/5561
>
>> diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
>> b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
>> index e00661b2414b9..f158d6bc314b9 100644
>> --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
>> +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
>
> [ ... ]
>
>> @@ -3179,8 +3185,12 @@ static int bcmgenet_init_rx_queues(struct
>> net_device *dev)
>> /* Initialize Rx priority queues */
>> for (i = 0; i <= priv->hw_params->rx_queues; i++) {
>> ret = bcmgenet_init_rx_ring(priv, i, end - start, start, end);
>> - if (ret)
>> + if (ret) {
>> + /* Only the rings before this one hold a NAPI */
>> + while (i--)
>> + netif_napi_del(&priv->rx_rings[i].napi);
>> return ret;
>> + }
>
> [Severity: Low]
> This isn't a bug, but this unwind and the new priv->datapath_up
> handling in
> bcmgenet_close(), bcmgenet_suspend() and bcmgenet_resume() look like
> they
> also fix two existing problems. The commit message doesn't mention
> either
> of them.
>
> Before this patch, if bcmgenet_init_rx_ring() failed for ring i, the
> NAPIs
> of rings 0..i-1 stayed listed after a failed bcmgenet_open() or
> bcmgenet_resume(). The next netif_napi_add() would then hit the
> already-listed warning.
>
> Also, bcmgenet_close() used to call bcmgenet_netif_stop()
> unconditionally.
> A close after a failed resume would call napi_disable() on NAPIs that
> were
> already disabled during suspend, and then kfree() rx_cbs/tx_cbs a
> second
> time. That path has nothing to do with the MTU, but the new comment in
> bcmgenet_close() only says:
>
> /* A failed MTU change can have torn the datapath down already */
>
> Could these fixes be split into separate patches with Fixes: tags so
> they
> can go to net and stable? The rx unwind is needed for the MTU retry,
> which
> calls bcmgenet_init_dma() twice in a row, so it could come first in the
> series.
The Rx NAPI unwind stays here. The retry path calls bcmgenet_init_dma()
twice in a row, so this patch would be broken without it. A Fixes: tag
would also pull the whole MTU feature into stable.
>
> [ ... ]
>
>> @@ -3622,7 +3633,11 @@ static int bcmgenet_close(struct net_device
>> *dev)
>>
>> netif_dbg(priv, ifdown, dev, "bcmgenet_close\n");
>>
>> - bcmgenet_netif_stop(dev, false);
>> + /* A failed MTU change can have torn the datapath down already */
>> + if (priv->datapath_up) {
>> + bcmgenet_netif_stop(dev, false);
>> + priv->datapath_up = false;
>> + }
>
> [ ... ]
>
>> +static int bcmgenet_change_mtu(struct net_device *dev, int new_mtu)
>> +{
>
> [ ... ]
>
>> + /* The watchdog trips on an idle queue once the rings are gone */
>> + netif_device_detach(dev);
>> +
>> + /* Only the buffers and the MTU registers change, leave the PHY up
>> */
>> + bcmgenet_netif_stop(dev, false);
>> + priv->datapath_up = false;
>> +
>> + WRITE_ONCE(dev->mtu, new_mtu);
>> + priv->rx_buf_len = bcmgenet_rx_buf_len(new_mtu);
>> + bcmgenet_set_mtu_regs(priv, new_mtu);
>
> [Severity: Medium]
> Can the first link-up enable the MAC again in the middle of this
> reconfiguration?
Yes, nothing prevents it. In v5 I will hold phydev->lock across the
rebuild so
bcmgenet_mac_config() cannot run inside it.
(Although I couldnt't reproduce it on a CM4 in ~550 MTU changes, 173 of
them with CMD_SW_RESET still set...)
>
> After ifup and before the first link-up, UMAC_CMD still has
> CMD_SW_RESET
> set from init_umac()->reset_umac(). In that state umac_enable_set()
> returns
> without writing anything:
>
> drivers/net/ethernet/broadcom/genet/bcmgenet.c:umac_enable_set() {
> ...
> if (reg & CMD_SW_RESET) {
> spin_unlock_bh(&priv->reg_lock);
> return;
> }
> ...
> }
>
> So the MAC disable inside bcmgenet_netif_stop() has no effect.
>
> The PHY state machine keeps running here. A link-up in this window runs
> bcmgenet_mii_setup()->bcmgenet_mac_config() under phydev->lock, not
> RTNL:
>
> drivers/net/ethernet/broadcom/genet/bcmmii.c:bcmgenet_mac_config() {
> ...
> if (reg & CMD_SW_RESET) {
> reg &= ~CMD_SW_RESET;
> bcmgenet_umac_writel(priv, reg, UMAC_CMD);
> udelay(2);
> reg |= CMD_TX_EN | CMD_RX_EN;
> }
> ...
> }
>
> The MAC would then be enabled while bcmgenet_set_mtu_regs() rewrites
> UMAC_MAX_FRAME_LEN and the RBUF/TBUF thresholds. That function's own
> comment says "Call with the MAC disabled". It would also be enabled
> while
> bcmgenet_init_dma(priv, true) flushes the RBUF and rebuilds the rings.
>
> Open and resume program these registers before phy_start(), so only the
> new path is exposed. The window includes the 10-20 ms sleep in the DMA
> teardown, so a network manager that sets the MTU right after ifup could
> hit it. Does anything prevent this?
>
>> +
>> + ret = bcmgenet_init_dma(priv, true);
>
> [ ... ]
>
>> + bcmgenet_hfb_restore(priv);
>> + bcmgenet_netif_start(dev, false);
>> +
>> + /* bcmgenet_netif_start() only restores the link interrupt */
>> + if (bcmgenet_has_mdio_intr(priv))
>> + bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_MDIO_EVENT,
>> + INTRL2_CPU_MASK_CLEAR);
>> +
>> + /* A link event latched while the interrupts were off is gone.
>> Internal
>> + * PHYs on GENET v1-v4 are not polled, so resync the state machine.
>> + */
>> + phy_mac_interrupt(dev->phydev);
>> +
>> + priv->datapath_up = true;
>> + netif_device_attach(dev);
>
> [Severity: Medium]
> Can a concurrent RX address list update get lost here?
>
> bcmgenet_netif_start() programs the RX filters through
> bcmgenet_set_rx_mode() under netif_addr_lock_bh() and then drops the
> lock.
> The device stays detached until the netif_device_attach() above. A
> unicast
> or multicast list change in that window reaches __dev_set_rx_mode(),
> which
> drops it:
>
> net/core/dev_addr_lists.c:__dev_set_rx_mode() {
> ...
> if (!netif_device_present(dev))
> return;
> ...
> }
>
> netif_device_attach() doesn't resync the RX mode, and bcmgenet has no
> ndo_change_rx_flags, so nothing queues the update for later.
>
> RTNL is held here. However, IPV6_ADD_MEMBERSHIP
> (ipv6_sock_mc_join()->__ipv6_dev_mc_inc()->dev_mc_add()) runs under the
> socket lock and mc_lock, not RTNL, so it can race with this. The new
> group
> would then sit in dev->mc without reaching the MDF filter until some
> unrelated RX mode change.
>
> Would it help to call bcmgenet_set_rx_mode() again after
> netif_device_attach()?
Yes. v5 will do that under netif_addr_lock_bh().
>
> [ ... ]
>
>> @@ -4510,6 +4602,7 @@ static int bcmgenet_suspend(struct device *d)
>> } else {
>> /* Teardown the interface */
>> bcmgenet_netif_stop(dev, true);
>> + priv->datapath_up = false;
>> }
>
> [Severity: High]
> This isn't a bug introduced by this patch, but the new
> priv->datapath_up
> flag tracks exactly this state, and bcmgenet_suspend() still never
> checks
> it. Can a second system suspend hang after a failed resume?
>
> The sequence would be:
>
> 1. A non-WoL suspend runs bcmgenet_netif_stop(dev, true). Its
> napi_disable() calls leave NAPI_STATE_SCHED|NPSVC set.
> bcmgenet_fini_dma() then deletes the NAPIs and frees rx_cbs/tx_cbs
> without NULLing them.
>
> 2. bcmgenet_resume() fails in bcmgenet_init_dma() (kzalloc failure,
> Tx/Rx
> DMA halt timeout, or Rx buffer allocation failure):
>
> ret = bcmgenet_init_dma(priv, false);
> if (ret) {
> netdev_err(dev, "failed to initialize DMA\n");
> goto out_clk_disable;
> }
>
> The device is left detached, netif_running() is still true and
> datapath_up is false.
>
> 3. On the next system suspend, bcmgenet_suspend() sees netif_running()
> and
> reaches bcmgenet_disable_tx_napi(). In this branch that happens
> through
> bcmgenet_netif_stop(), and the WoL branch calls it directly.
>
> napi_disable_locked() would then loop forever in:
>
> while (val & (NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC)) {
> usleep_range(20, 200);
> val = READ_ONCE(n->state);
> }
>
> That happens because the earlier disable left those bits set. Even if
> suspend got past that point, bcmgenet_fini_dma() would kfree() rx_cbs
> and
> tx_cbs a second time.
>
> bcmgenet_close() is now guarded by priv->datapath_up. Should the
> teardown
> in both branches of bcmgenet_suspend() check it too?
Agreed. But that is pre-existing, so I will do this in a follow up,
together
with the dangling rx_cbs/tx_cbs which make the second teardown a double
free.
---
pw-bot: cr
next prev parent reply other threads:[~2026-10-13 13:45 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-12 9:00 [PATCH net-next v4 0/8] net: bcmgenet: support larger MTUs Nicolai Buchwitz
2026-10-12 9:00 ` [PATCH net-next v4 1/8] net: bcmgenet: ring the doorbell when the last frame of a batch is dropped Nicolai Buchwitz
2026-10-12 21:29 ` Florian Fainelli
2026-10-12 9:00 ` [PATCH net-next v4 2/8] net: bcmgenet: let the caller decide whether to start the PHY Nicolai Buchwitz
2026-10-12 9:00 ` [PATCH net-next v4 3/8] net: bcmgenet: allow a continuation descriptor without the alignment pad Nicolai Buchwitz
2026-10-13 9:19 ` netdev-bot+sashiko
2026-10-12 9:00 ` [PATCH net-next v4 4/8] net: bcmgenet: rename ENET_MAX_MTU_SIZE to ENET_MAX_FRAME_LEN Nicolai Buchwitz
2026-10-12 9:00 ` [PATCH net-next v4 5/8] net: bcmgenet: derive the receive buffer length from the MTU Nicolai Buchwitz
2026-10-12 21:45 ` Florian Fainelli
2026-10-12 9:00 ` [PATCH net-next v4 6/8] net: bcmgenet: pad transmit frames out of the packet ready window Nicolai Buchwitz
2026-10-12 21:48 ` Florian Fainelli
2026-10-13 9:19 ` netdev-bot+sashiko
2026-10-12 9:00 ` [PATCH net-next v4 7/8] net: bcmgenet: allow the MTU to be changed Nicolai Buchwitz
2026-10-12 21:38 ` Florian Fainelli
2026-10-13 9:19 ` netdev-bot+sashiko
2026-10-13 13:44 ` Nicolai Buchwitz [this message]
2026-10-12 9:00 ` [PATCH net-next v4 8/8] net: bcmgenet: reassemble jumbo frames from status block fragments Nicolai Buchwitz
2026-10-12 21:49 ` Florian Fainelli
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=92aa4715d68679c8c33d4c40bdd75ae5@tipi-net.de \
--to=nb@tipi-net.de \
--cc=andrew+netdev@lunn.ch \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=dave.stevenson@raspberrypi.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=f.fainelli@gmail.com \
--cc=florian.fainelli@broadcom.com \
--cc=justin.chen@broadcom.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev-bot+sashiko@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=opendmb@gmail.com \
--cc=pabeni@redhat.com \
--cc=pierremarinleclercq88@gmail.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
all inboxes | Powered by JetHome®