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>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
Sean Anderson <sean.anderson@linux.dev>,
Antoine Tenart <atenart@kernel.org>,
Eric Dumazet <edumazet@kernel.org>,
Nicolas Ferre <nicolas.ferre@microchip.com>,
Russell King <linux@armlinux.org.uk>
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>,
"Maxime Chevallier" <maxime.chevallier@bootlin.com>,
"Théo Lebrun" <theo.lebrun@bootlin.com>,
stable@vger.kernel.org
Subject: [PATCH net v2 1/3] net: macb: never give hardware a NULL RX buffer
Date: Fri, 25 Sep 2026 15:59:34 +0200 [thread overview]
Message-ID: <20260925-macb-close-v2-1-360efa565914@bootlin.com> (raw)
In-Reply-To: <20260925-macb-close-v2-0-360efa565914@bootlin.com>
The refill logic is simple: iterate over all pending rx slots, allocate
SKB (& DMA map) if needed and hand it off to the hardware by clearing
the RX_USED flag.
If the refill operation fails mid-way, it early returns leaving the
remaining slots untouched. In an initialised ring that is safe: a slot
is either owned by the hardware holding a valid buffer, or
software-owned (RX_USED set) waiting for refill to hand it a new one.
When slots have never been initialised however, we are in trouble.
After dma_alloc_coherent() of the rx ring buffer, all slots have NULL
pointers and RX_USED cleared meaning HW will try using them. Ensure
this does not happen by setting the RX_USED flag on all slots before
calling refill at buffer alloc, in gem_init_rx_ring(). That way even if
refill fails on an alloc/dma_map, the HW won't try using NULL pointers
as buffers.
Note we tweak gem_rx() and macb_rx_pending(): their previous stop
condition was only if desc was RX_USED. Now it must be either RX_USED
or we got out of the range of successfully allocated descriptors
(detected using the rx_tail and rx_prepared_head cursors).
Otherwise gem_rx() could consume unallocated buffers.
Theoretical bugfix, never encountered in practice. To reproduce,
introduce memory pressure (less than 512 SKBs of free memory) and open
the interface.
Note that this codepath also hits at resume, on HRESP errors and on
set_ringparam (while interface is running).
Fixes: 4df95131ea80 ("net/macb: change RX path for GEM")
Cc: stable@vger.kernel.org
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
drivers/net/ethernet/cadence/macb_main.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 8e5c034dc3a4..7f25574928d7 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -1596,6 +1596,13 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,
dma_addr_t addr;
bool rxused;
+ /* Only descriptors in [rx_tail, rx_prepared_head) were armed
+ * for hardware. Outside, we might have RX_USED descriptors for
+ * alloc failures.
+ */
+ if (queue->rx_tail == queue->rx_prepared_head)
+ break;
+
entry = macb_rx_ring_wrap(bp, queue->rx_tail);
desc = macb_rx_desc(queue, entry);
@@ -1859,6 +1866,10 @@ static bool macb_rx_pending(struct macb_queue *queue)
struct macb_dma_desc *desc;
unsigned int entry;
+ /* No armed descriptor left: nothing can be pending. */
+ if (macb_is_gem(bp) && queue->rx_tail == queue->rx_prepared_head)
+ return false;
+
entry = macb_rx_ring_wrap(bp, queue->rx_tail);
desc = macb_rx_desc(queue, entry);
@@ -2795,9 +2806,14 @@ static int macb_alloc(struct macb *bp)
static void gem_init_rx_ring(struct macb_queue *queue)
{
+ unsigned int i;
+
queue->rx_tail = 0;
queue->rx_prepared_head = 0;
+ for (i = 0; i < queue->bp->rx_ring_size; i++)
+ macb_rx_desc(queue, i)->addr |= MACB_BIT(RX_USED);
+
gem_rx_refill(queue);
}
--
2.55.0
next prev parent reply other threads:[~2026-09-25 13:59 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-25 13:59 [PATCH net v2 0/3] net: macb: fix close races (and RX refill error handling) Théo Lebrun
2026-09-25 13:59 ` Théo Lebrun [this message]
2026-09-25 13:59 ` [PATCH net v2 2/3] net: macb: propagate RX ring refill errors Théo Lebrun
2026-09-25 14:20 ` Nicolai Buchwitz
2026-09-25 13:59 ` [PATCH net v2 3/3] net: macb: quiesce IRQs and drain BH on interface close 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=20260925-macb-close-v2-1-360efa565914@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@kernel.org \
--cc=gregory.clement@bootlin.com \
--cc=horms@kernel.org \
--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=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
all inboxes | Powered by JetHome®