From: Paolo Abeni <pabeni@redhat.com>
To: theo.lebrun@bootlin.com
Cc: conor.dooley@microchip.com, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, richardcochran@gmail.com,
linux@armlinux.org.uk, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, nicolas.ferre@microchip.com,
claudiu.beznea@tuxon.dev, pvalerio@redhat.com, nb@tipi-net.de,
vladimir.kondratiev@mobileye.com, gregory.clement@bootlin.com,
benoit.monin@bootlin.com, tawfik.bayouk@mobileye.com,
thomas.petazzoni@bootlin.com, maxime.chevallier@bootlin.com
Subject: Re: [PATCH net-next v3 07/15] net: macb: introduce macb_context struct for buffer management
Date: Wed, 8 Jul 2026 12:27:16 +0200 [thread overview]
Message-ID: <20260708102716.169767-1-pabeni@redhat.com> (raw)
In-Reply-To: <20260701-macb-context-v3-7-00268d5b1502@bootlin.com>
From: AI Reviewer <ai@example.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://netdev-ai.bots.linux.dev/sashiko/
---
net: macb: introduce macb_context struct for buffer management
This patch moves per-queue ring buffers and ring-size parameters out of
struct macb / struct macb_queue into a new struct macb_context that is
allocated on open and freed on close, so future patches can swap in a
new context while the interface is running.
> diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> index 951a7f080225..dfb1d49d841c 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
[ ... ]
> @@ -1257,6 +1288,7 @@ static void macb_tx_error_task(struct work_struct *work)
> struct macb_queue *queue = container_of(work, struct macb_queue,
> tx_error_task);
> unsigned int q = queue - queue->bp->queues;
> + struct macb_txq *txq = macb_txq(queue);
> struct macb *bp = queue->bp;
[High]
Can macb_tx_error_task() dereference a freed context?
macb_tx_error_task is scheduled from macb_interrupt():
schedule_work(&queue->tx_error_task);
After this patch, the very first thing the worker does is:
struct macb_txq *txq = macb_txq(queue);
which expands to &bp->ctx->txq[q] and dereferences bp->ctx.
Looking at macb_close():
macb_reset_hw(bp);
...
macb_free(bp);
kfree(bp->ctx);
bp->ctx = NULL;
There is no cancel_work_sync(&queue->tx_error_task), and macb_reset_hw()
does not drain the workqueue. If an interrupt scheduled the work just
before close, or the work was already pending, the worker can run after
kfree(bp->ctx) and hit a NULL dereference (and a use-after-free if
macb_open() re-allocates ctx concurrently via ethtool ring reconfig).
The same reasoning applies to bp->hresp_err_bh_work, which is queued
from macb_interrupt() and whose handler calls
mog_init_rings()/macb_init_buffers() that read bp->ctx->tx_ring_size and
bp->ctx->{tx,rx}q[q]. cancel_work_sync(&bp->hresp_err_bh_work) is only
called from macb_remove(), not macb_close().
Pre-patch these fields lived inside the embedded struct macb_queue so a
late worker would touch stale-but-addressable memory; post-patch the
first indirection through bp->ctx faults.
Would adding cancel_work_sync(&queue->tx_error_task) per queue and
cancel_work_sync(&bp->hresp_err_bh_work) before kfree(bp->ctx) in
macb_close() close this window?
[ ... ]
> @@ -3690,8 +3778,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);
[Medium]
Should the return value of macb_open() be checked here?
This patch adds a new failure point inside macb_open():
bp->ctx = kzalloc_obj(*bp->ctx);
if (!bp->ctx) {
err = -ENOMEM;
goto pm_exit;
}
On failure, bp->ctx remains NULL and the interface stays down, but
macb_set_ringparam() ignores the return value and reports success to
userspace. The commit message says the motivation is to improve
reliability under memory pressure, but this caller silently swallows the
new allocation failure.
[ ... ]
> @@ -5039,6 +5125,12 @@ static int at91ether_open(struct net_device *netdev)
> if (ret < 0)
> return ret;
>
> + bp->ctx = kzalloc_obj(*bp->ctx);
> + if (!bp->ctx) {
> + ret = -ENOMEM;
> + goto pm_exit;
> + }
> +
> /* Clear internal statistics */
> ctl = macb_readl(bp, NCR);
> macb_writel(bp, NCR, ctl | MACB_BIT(CLRSTAT));
[Low]
Should bp->ctx->rx_ring_size, tx_ring_size and rx_buffer_size be
initialized on this path?
macb_open() sets them from configured_{rx,tx}_ring_size and calls
macb_init_rx_buffer_size(), but at91ether_open() leaves them at zero
after kzalloc_obj().
Helpers such as macb_rx_ring_wrap() compute:
return index & (bp->ctx->rx_ring_size - 1);
which becomes index & 0xFFFFFFFF when rx_ring_size is 0. It happens to
be harmless today because the at91ether path constrains indices to
[0, AT91ETHER_MAX_RX_DESCR-1] independently and macb_get_regs() reports
zeroed head/tail for the tx-less at91ether, but pre-patch macb_init_dflt()
unconditionally set bp->rx_ring_size = DEFAULT_RX_RING_SIZE.
Any future shared helper that used tx_ring_size as a stride or divisor
would misbehave on at91ether.
[ ... ]
> @@ -5076,6 +5171,9 @@ static int at91ether_close(struct net_device *netdev)
>
> at91ether_stop(bp);
>
> + kfree(bp->ctx);
> + bp->ctx = NULL;
> +
> pm_runtime_put(&bp->pdev->dev);
>
> return 0;
[High]
Is there IRQ synchronization missing before freeing bp->ctx on this
path?
at91ether_stop() disables MAC RX/TX and writes IDR to mask further
interrupts, but does not synchronize with a handler already running or
already dispatched on another CPU. at91ether_interrupt() calls
at91ether_rx(), which after this patch does:
struct macb_rxq *rxq = &bp->ctx->rxq[0];
...
desc = macb_rx_desc(queue, rxq->tail);
...
p_recv = rxq->buffers + rxq->tail * AT91ETHER_MAX_RBUFF_SZ;
If the handler is in flight when kfree(bp->ctx); bp->ctx = NULL runs,
the next access through bp->ctx faults. The macb_open()/macb_close()
path is somewhat protected by napi_disable() before macb_free(), but
at91ether does not use NAPI and has no equivalent barrier.
Would a synchronize_irq(bp->netdev->irq) between at91ether_stop() and
kfree(bp->ctx) close this?
--
This is an AI-generated review.
next prev parent reply other threads:[~2026-07-08 10:29 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 15:59 [PATCH net-next v3 00/15] net: macb: implement context swapping Théo Lebrun
2026-07-01 15:59 ` [PATCH net-next v3 01/15] net: macb: drop "consistent" from alloc/free function names Théo Lebrun
2026-07-02 10:41 ` Nicolai Buchwitz
2026-07-03 11:28 ` Conor Dooley
2026-07-03 16:32 ` Théo Lebrun
2026-07-03 16:34 ` Conor Dooley
2026-07-01 15:59 ` [PATCH net-next v3 02/15] net: macb: unify device pointer naming convention Théo Lebrun
2026-07-03 11:29 ` Conor Dooley
2026-07-01 15:59 ` [PATCH net-next v3 03/15] net: macb: unify variable naming convention in at91ether functions Théo Lebrun
2026-07-02 10:42 ` Nicolai Buchwitz
2026-07-03 11:30 ` Conor Dooley
2026-07-01 15:59 ` [PATCH net-next v3 04/15] net: macb: unify queue index variable naming convention and types Théo Lebrun
2026-07-02 10:43 ` Nicolai Buchwitz
2026-07-03 11:34 ` Conor Dooley
2026-07-03 17:10 ` Théo Lebrun
2026-07-01 15:59 ` [PATCH net-next v3 05/15] net: macb: enforce reverse christmas tree (RCT) convention Théo Lebrun
2026-07-02 10:48 ` Nicolai Buchwitz
2026-07-03 11:35 ` Conor Dooley
2026-07-01 15:59 ` [PATCH net-next v3 06/15] net: macb: allocate tieoff descriptor once across device lifetime Théo Lebrun
2026-07-02 10:54 ` Nicolai Buchwitz
2026-07-01 15:59 ` [PATCH net-next v3 07/15] net: macb: introduce macb_context struct for buffer management Théo Lebrun
2026-07-03 11:39 ` Conor Dooley
2026-07-08 10:27 ` Paolo Abeni [this message]
2026-07-01 15:59 ` [PATCH net-next v3 08/15] net: macb: avoid macb_init_rx_buffer_size() modifying state Théo Lebrun
2026-07-01 15:59 ` [PATCH net-next v3 09/15] net: macb: make `struct macb` subset reachable from macb_context struct Théo Lebrun
2026-07-01 15:59 ` [PATCH net-next v3 10/15] net: macb: change caps helpers signatures Théo Lebrun
2026-07-03 11:43 ` Conor Dooley
2026-07-01 15:59 ` [PATCH net-next v3 11/15] net: macb: change function signatures to take contexts Théo Lebrun
2026-07-03 11:45 ` Conor Dooley
2026-07-01 15:59 ` [PATCH net-next v3 12/15] net: macb: introduce macb_context_alloc() helper Théo Lebrun
2026-07-01 15:59 ` [PATCH net-next v3 13/15] net: macb: re-read ISR inside IRQ handler locked section Théo Lebrun
2026-07-03 12:09 ` Conor Dooley
2026-07-01 15:59 ` [PATCH net-next v3 14/15] net: macb: use context swapping in .set_ringparam() Théo Lebrun
2026-07-02 10:37 ` Nicolai Buchwitz
2026-07-01 15:59 ` [PATCH net-next v3 15/15] net: macb: use context swapping in .ndo_change_mtu() Théo Lebrun
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=20260708102716.169767-1-pabeni@redhat.com \
--to=pabeni@redhat.com \
--cc=andrew+netdev@lunn.ch \
--cc=benoit.monin@bootlin.com \
--cc=claudiu.beznea@tuxon.dev \
--cc=conor.dooley@microchip.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=gregory.clement@bootlin.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=maxime.chevallier@bootlin.com \
--cc=nb@tipi-net.de \
--cc=netdev@vger.kernel.org \
--cc=nicolas.ferre@microchip.com \
--cc=pvalerio@redhat.com \
--cc=richardcochran@gmail.com \
--cc=tawfik.bayouk@mobileye.com \
--cc=theo.lebrun@bootlin.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.