All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Théo Lebrun" <theo.lebrun@bootlin.com>
To: "Théo Lebrun" <theo.lebrun@bootlin.com>,
	"Conor Dooley" <conor.dooley@microchip.com>,
	"Andrew Lunn" <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	"Eric Dumazet" <edumazet@kernel.org>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Paolo Abeni" <pabeni@redhat.com>,
	"Richard Cochran" <richardcochran@gmail.com>,
	"Russell King" <linux@armlinux.org.uk>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Paolo Valerio" <pvalerio@redhat.com>,
	"Nicolai Buchwitz" <nb@tipi-net.de>,
	"Vladimir Kondratiev" <vladimir.kondratiev@mobileye.com>,
	"Gregory CLEMENT" <gregory.clement@bootlin.com>,
	"Benoît Monin" <benoit.monin@bootlin.com>,
	"Tawfik Bayouk" <tawfik.bayouk@mobileye.com>,
	"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>,
	stable+noautosel@kernel.org, Sashiko <sashiko-bot@kernel.org>
Subject: Re: [PATCH net-next v11 0/9] net: macb: implement context swapping
Date: Thu, 15 Oct 2026 16:55:32 +0200	[thread overview]
Message-ID: <DM5HYXXJV8GS.1IX8XO5IECV35@bootlin.com> (raw)
In-Reply-To: <20261013-macb-context-v11-0-b27785167566@bootlin.com>

Hello Théo,

Sashiko has 4 high comments, Clashiko has 3 low comments.

TL;DR: nothing worth a respin because it is all out of scope.

https://sashiko.dev/#/patchset/20261013-macb-context-v11-0-b27785167566%40bootlin.com
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261013-macb-context-v11-0-b27785167566%40bootlin.com

> commit 0eff5390c4748a085f669ce98d1bc433c0f36ace
> Author: Théo Lebrun <theo.lebrun@bootlin.com>
> net: macb: introduce macb_context struct for buffer management
>
> This commit introduces a macb_context structure to own all queue
> buffers and parameters, paving the way for supporting multiple contexts
> in parallel during buffer reallocation. It updates ring parameters and
> moves related fields out of the main macb struct into the context struct.
>
> > diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> > --- a/drivers/net/ethernet/cadence/macb_main.c
> > +++ b/drivers/net/ethernet/cadence/macb_main.c
> [ ... ]
> > @@ -2741,60 +2789,71 @@ static void gem_free_rx_buffers(struct macb *bp)
> [ ... ]
> >  static unsigned int macb_tx_ring_size_per_queue(struct macb *bp)
> >  {
> > - return macb_dma_desc_get_size(bp) * bp->tx_ring_size + bp->tx_bd_rd_prefetch;
> > + return macb_dma_desc_get_size(bp) * bp->ctx->tx_ring_size +
> > +    bp->tx_bd_rd_prefetch;
> >  }
>
> [Severity: High]
> Can this dereference a NULL pointer if the context was freed?
>
> If macb_open() fails, it now frees bp->ctx and leaves it NULL. Later, if
> the interface is closed and macb_free() calls this function:
>
> macb_close() -> macb_free() -> macb_tx_ring_size_per_queue()
>
> This will dereference bp->ctx.

Sashiko says there is an issue with a macb_open() failing followed by a
macb_close(). Indeed, but the interface won't be closed if its open
operation failed.

>
> [ ... ]
> > @@ -3856,8 +3946,8 @@ static int macb_set_ringparam(struct net_device *netdev,
> >      macb_close(bp->netdev);
> >   }
> >
> > - bp->rx_ring_size = new_rx_size;
> > - bp->tx_ring_size = new_tx_size;
> > + bp->configured_rx_ring_size = new_rx_size;
> > + bp->configured_tx_ring_size = new_tx_size;
> >
> >   if (reset)
> >      macb_open(bp->netdev);
> >
> >   return 0;
> >  }
>
> [Severity: High]
> Should we be checking the return value of macb_open() here?
>
> If macb_open() fails, it frees bp->ctx. However, this function
> unconditionally returns 0, masking the failure and leaving the device in
> an UP state in the network stack.
>
> A subsequent interface down event will trigger macb_close(), which calls
> macb_free(), resulting in the NULL pointer dereference in
> macb_tx_ring_size_per_queue() noted above.

We ignore that on purpose. Check out the last two commits. The whole
point of this series is to introduce context swapping, to fix the
set_ringparam operation (and others).

---

> commit b435a89b7b7a33cd5d0880d8a83b893da802f106
> Author: Théo Lebrun <theo.lebrun@bootlin.com>
>
> net: macb: change function signatures to take contexts
>
> This commit changes many function signatures in the MACB driver to take a
> macb_context pointer instead of macb or macb_queue. This refactoring prepares
> the driver for supporting parallel MACB contexts while reducing the bug
> surface area by preventing the use of the wrong context.
>
> > diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> > --- a/drivers/net/ethernet/cadence/macb_main.c
> > +++ b/drivers/net/ethernet/cadence/macb_main.c
> [ ... ]
> >   for (tail = txq->tail; tail != txq->head; tail++) {
> >      u32   ctrl;
> >
> > -    desc = macb_tx_desc(queue, tail);
> > +    desc = macb_tx_desc(ctx, q, tail);
>
> [Severity: High]
> Does this traversal and unmapping of the TX ring lack necessary synchronization?
>
> When macb_tx_error_task is triggered in a workqueue due to a TX error, it
> calls netif_tx_stop_all_queues(). This sets QUEUE_STATE_DRV_XOFF but does
> not wait for a concurrent macb_start_xmit on another CPU.

This is out of scope. We ignore suspend, the HRESP error task and the TX
error task on purpose.

[...]

> >      ctrl = desc->ctrl;
> >      tx_skb = macb_tx_skb(queue, tail);
> >      skb = tx_skb->skb;
> [ ... ]
> >   netif_tx_stop_all_queues(netdev);
> >   netif_carrier_off(netdev);
> >
> > - bp->macbgem_ops.mog_init_rings(bp);
> > + bp->macbgem_ops.mog_init_rings(ctx);
>
> [Severity: High]
> Could this ring reinitialization lead to a use-after-free or data corruption?
>
> When a hardware HRESP error triggers macb_hresp_error_task via system_bh_wq,
> mog_init_rings is called to reset ring pointers and reallocate SKB arrays.
> However, it does not appear to synchronize with software datapath operations
> using napi_disable() and spin_lock(&queue->tx_ptr_lock).

This is out of scope. We ignore suspend, the HRESP error task and the TX
error task on purpose.

[...]

---

> commit c7aa30e3b67cf259fbc73811fb17ffc27d9be6eb
> Author: Théo Lebrun <theo.lebrun@bootlin.com>
>
>     net: macb: use context swapping in .set_ringparam()
>
> This patch introduces a context swapping mechanism for macb's set_ringparam
> ethtool operation. It avoids freeing buffers during interface close and
> reallocating them on open, instead pre-allocating a new context to prevent
> failures under memory pressure. The swap logic is synchronized against MAC
> callbacks and NAPI execution using a new mac_cfg_lock mutex and the quiesce
> state.
>
> > diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> > index 32a24c91c045a..6bacf3e3caabb 100644
> > --- a/drivers/net/ethernet/cadence/macb_main.c
> > +++ b/drivers/net/ethernet/cadence/macb_main.c
> [ ... ]
> > @@ -2010,29 +2038,37 @@ static int macb_rx_poll(struct napi_struct *napi, int budget)
> >
> >  static void macb_tx_restart(struct macb_queue *queue)
> >  {
> > - struct macb_context *ctx = queue->bp->ctx;
> > - struct macb_txq *txq = macb_txq(queue);
> >   struct macb *bp = queue->bp;
> >   unsigned int head_idx, tbqp;
> > + struct macb_context *ctx;
> > + struct macb_txq *txq;
> >   unsigned long flags;
> >
> >   spin_lock_irqsave(&queue->tx_ptr_lock, flags);
> >
> > + spin_lock(&bp->lock);
> > +
> > + /* context swap ongoing? */
> > + if (bp->irq_quiesced)
> > +    goto out_unlock;
> > +
> > + ctx = queue->bp->ctx;
> > + txq = macb_txq(queue);
> > +
> >   if (txq->head == txq->tail)
> > -    goto out_tx_ptr_unlock;
> > +    goto out_unlock;
>
> [Severity: High]
> Does macb_tx_error_task() in drivers/net/ethernet/cadence/macb_main.c also
> need to acquire queue->tx_ptr_lock when updating txq->head and txq->tail?

This is out of scope. We ignore suspend, the HRESP error task and the TX
error task on purpose.

[...]

---

> commit 59119f040d96bc1d81d6e0708a9c738cad768fcd
> Author: Théo Lebrun <theo.lebrun@bootlin.com>
>
> net: macb: use context swapping in .set_ringparam()
>
> The old close/reopen sequence in macb_set_ringparam() is replaced. A new
> context with the requested ring sizes is now allocated before the
> interface is stopped, and it is swapped in with the new helpers
> macb_context_swap_start() and macb_context_swap_end(). A new mac_cfg_lock
> mutex serializes the swap against the phylink MAC callbacks, and a new
> bp->link_up boolean tracks link state under that lock.
>
> > diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
> > index ec2e2fbc1146a..b7b4b6a382980 100644
> > --- a/drivers/net/ethernet/cadence/macb.h
> > +++ b/drivers/net/ethernet/cadence/macb.h
>
> [ ... ]
>
> > @@ -1419,10 +1421,13 @@ struct macb {
> >   u32         tx_lpi_timer;
> >
> >   /* ISR must not drive NAPI & BH mechanisms. True when the interface
> > -  * is closed. Protected by bp->lock.
> > +  * is closed or during context-swap. Protected by bp->lock.
> >    */
> >   bool        irq_quiesced;
> >
> > + /* Redundant to netif_carrier_ok(), but set under bp->mac_cfg_lock. */
> > + bool        link_up;
>
> [Severity: Low]
> [Finding: main-2-3]
> [Sources: opus-5-5]
> Is the "redundant to netif_carrier_ok()" claim accurate?
> macb_hresp_error_task() changes the carrier and the hardware enable bits
> without taking mac_cfg_lock, and it never reads or updates bp->link_up:

Technically the "Redundant to netif_carrier_ok()" phrase is wrong yes
but I hope it is evident that if it was actually redundant, we wouldn't
have introduced a separate flag.

Fixing the many known races inbetween the HRESP task and the rest of the
driver execution is out of scope of this series.

[...]

> > @@ -3995,16 +4140,20 @@ static int macb_set_ringparam(struct net_device *netdev,
> >      return 0;
> >   }
> >
> > - if (netif_running(bp->netdev)) {
> > -    reset = 1;
> > -    macb_close(bp->netdev);
> > + if (running) {
> > +    new_ctx = macb_context_alloc(bp, netdev->mtu,
> > +                  new_rx_size, new_tx_size);
> > +    if (IS_ERR(new_ctx))
> > +       return PTR_ERR(new_ctx);
> > +
> > +    macb_context_swap_start(bp);
> >   }
> >
> >   bp->configured_rx_ring_size = new_rx_size;
> >   bp->configured_tx_ring_size = new_tx_size;
>

[... pre existing finding ...]

>
> >
> > - if (reset)
> > -    macb_open(bp->netdev);
> > + if (running)
> > +    macb_context_swap_end(bp, new_ctx);
> >
> >   return 0;
> >  }
>
> [Severity: Low]
> [Finding: gpt-6-astra-1-2]
> [Sources: gpt-6-astra, opus-5-5]
> The code change looks correct, but the commit message describes the old
> behaviour only as:
>
>   Under memory pressure this does not fly: we free our buffers at close
>   and cannot reallocate new ones at open.

I've cut the rambling. The point here is that the commit message is
somewhat underselling what we gain from context swapping. I couldn't
agree more, context swapping is great!

Clashiko wants to point out all the advantages and add a Fixes trailer.
I consider all that useless and see this patch as a new feature rather
than a bugfix.

[...]

---

> commit 9410fd54d1f3a19a62c932c210f14be133012c06
> Author: Théo Lebrun <theo.lebrun@bootlin.com>
>
> net: macb: use context swapping in .ndo_change_mtu()
>
> This patch makes macb_change_mtu() handle a running interface by swapping
> contexts: it allocates a new context sized for the new MTU, quiesces and
> reconfigures the hardware, then frees the old context. Before this, the
> function returned -EBUSY. AT91 EMAC devices are rejected defensively, since
> they use a separate ndo struct and should never reach this path.
>
> > diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> > index 6bacf3e3caabb..f087f278f9e56 100644
> > --- a/drivers/net/ethernet/cadence/macb_main.c
> > +++ b/drivers/net/ethernet/cadence/macb_main.c
> > @@ -3658,11 +3658,29 @@ static int macb_close(struct net_device *netdev)
> >
> >  static int macb_change_mtu(struct net_device *netdev, int new_mtu)
> >  {
> > - if (netif_running(netdev))
> > -    return -EBUSY;
> > + struct macb *bp = netdev_priv(netdev);
> > + bool running = netif_running(netdev);
> > + struct macb_context *new_ctx;
> > +
> > + if (running) {
> > +    /* Context swapping is not supported for AT91. */
> > +    if (bp->caps & MACB_CAPS_MACB_IS_EMAC)
> > +       return -EBUSY;
>
> [Severity: Low]
> [Finding: main-2-0]
> [Sources: opus-5-5]
> This isn't a bug, but should this comment say "AT91 EMAC" instead of
> "AT91"?
>
> MACB_CAPS_MACB_IS_EMAC is set only by emac_config. Other AT91-family
> configs, such as at91sam9260_config, sama5d2_config and sama5d3_config,
> don't set it. Those parts use macb_netdev_ops, so they do get context
> swapping on a live MTU change. The commit message already says "AT91 EMAC".

On this one, I agree: AT91 is confusing, the proper way to describe the
old IP we support would be 'EMAC' or 'RM9200' (only board we support
that uses that IP revision).

I won't respin just for this comment tweak. If we wanted to fully remove
the confusion, we would also rename all functions from at91ether_* to
something else, like macb_emac_* or something of the sort. This feels
out of scope.

Thanks,

--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


      parent reply	other threads:[~2026-10-15 14:55 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13 13:16 [PATCH net-next v11 0/9] net: macb: implement context swapping Théo Lebrun
2026-10-13 13:16 ` [PATCH net-next v11 1/9] net: macb: close race between NAPI polls & ndo_stop Théo Lebrun
2026-10-13 13:54   ` Nicolai Buchwitz
2026-10-13 13:16 ` [PATCH net-next v11 2/9] net: macb: introduce macb_context struct for buffer management Théo Lebrun
2026-10-13 13:16 ` [PATCH net-next v11 3/9] net: macb: avoid macb_init_rx_buffer_size() modifying state Théo Lebrun
2026-10-13 13:16 ` [PATCH net-next v11 4/9] net: macb: make `struct macb` subset reachable from macb_context struct Théo Lebrun
2026-10-13 13:16 ` [PATCH net-next v11 5/9] net: macb: change caps helpers signatures Théo Lebrun
2026-10-13 13:16 ` [PATCH net-next v11 6/9] net: macb: change function signatures to take contexts Théo Lebrun
2026-10-13 13:16 ` [PATCH net-next v11 7/9] net: macb: introduce macb_context_alloc() helper Théo Lebrun
2026-10-13 13:16 ` [PATCH net-next v11 8/9] net: macb: use context swapping in .set_ringparam() Théo Lebrun
2026-10-13 13:16 ` [PATCH net-next v11 9/9] net: macb: use context swapping in .ndo_change_mtu() Théo Lebrun
2026-10-13 13:20 ` [PATCH net-next v11 0/9] net: macb: implement context swapping netdev-bot+sinfo
2026-10-13 13:29   ` Théo Lebrun
2026-10-13 19:04 ` Nicolai Buchwitz
2026-10-15 14:33   ` Théo Lebrun
2026-10-15 14:55 ` Théo Lebrun [this message]

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=DM5HYXXJV8GS.1IX8XO5IECV35@bootlin.com \
    --to=theo.lebrun@bootlin.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=benoit.monin@bootlin.com \
    --cc=conor.dooley@microchip.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=gregory.clement@bootlin.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=nb@tipi-net.de \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pvalerio@redhat.com \
    --cc=richardcochran@gmail.com \
    --cc=sashiko-bot@kernel.org \
    --cc=stable+noautosel@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.