* [PATCH net] net: ethernet: cortina: Fix SKB leak
@ 2026-03-30 6:00 Linus Walleij
2026-04-01 2:14 ` Jakub Kicinski
2026-04-01 11:06 ` Li Xiasong
0 siblings, 2 replies; 3+ messages in thread
From: Linus Walleij @ 2026-03-30 6:00 UTC (permalink / raw)
To: Hans Ulli Kroll, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Michał Mirosław
Cc: netdev, Andreas Haarmann-Thiemann, Linus Walleij
From: Andreas Haarmann-Thiemann <eitschman@nebelreich.de>
Under sustained RX load (e.g. large file transfers over the network), the
device freezes completely and requires a hard power cycle. No kernel panic
or oops is produced; the system simply stops responding.
In gmac_rx() (drivers/net/ethernet/cortina/gemini.c), when
gmac_get_queue_page() returns NULL for the second page of a multi-page
fragment, the driver logs an error and continues — but does not free the
in-progress skb that was already being assembled via napi_build_skb() /
napi_get_frags():
gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE);
if (!gpage) {
dev_err(geth->dev, "could not find mapping\n");
/* BUG: skb leaked here */
port->stats.rx_dropped++;
continue;
}
This path is distinct from the similar block in gmac_cleanup_rxq(), which
correctly only logs "could not find page" without an skb in flight.
Each occurrence of this error path leaks one skb. Under sustained traffic
the leak exhausts kernel memory, causing the observed lockup.
Free the in-progress skb via napi_free_frags() before continuing, matching
the pattern already used elsewhere in the driver.
Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
Signed-off-by: Andreas Haarmann-Thiemann <eitschman@nebelreich.de>
Signed-off-by: Linus Walleij <linusw@kernel.org>
---
drivers/net/ethernet/cortina/gemini.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 4824232f4890..723d90d5fdf3 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1491,6 +1491,10 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE);
if (!gpage) {
dev_err(geth->dev, "could not find mapping\n");
+ if (skb) {
+ napi_free_frags(&port->napi);
+ skb = NULL;
+ }
continue;
}
page = gpage->page;
---
base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
change-id: 20260330-gemini-ethernet-fix-604c28c53da1
Best regards,
--
Linus Walleij <linusw@kernel.org>
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net] net: ethernet: cortina: Fix SKB leak
2026-03-30 6:00 [PATCH net] net: ethernet: cortina: Fix SKB leak Linus Walleij
@ 2026-04-01 2:14 ` Jakub Kicinski
2026-04-01 11:06 ` Li Xiasong
1 sibling, 0 replies; 3+ messages in thread
From: Jakub Kicinski @ 2026-04-01 2:14 UTC (permalink / raw)
To: Linus Walleij
Cc: Hans Ulli Kroll, Andrew Lunn, David S. Miller, Eric Dumazet,
Paolo Abeni, Michał Mirosław, netdev,
Andreas Haarmann-Thiemann
On Mon, 30 Mar 2026 08:00:29 +0200 Linus Walleij wrote:
> From: Andreas Haarmann-Thiemann <eitschman@nebelreich.de>
>
> Under sustained RX load (e.g. large file transfers over the network), the
> device freezes completely and requires a hard power cycle. No kernel panic
> or oops is produced; the system simply stops responding.
>
> In gmac_rx() (drivers/net/ethernet/cortina/gemini.c), when
> gmac_get_queue_page() returns NULL for the second page of a multi-page
> fragment, the driver logs an error and continues — but does not free the
> in-progress skb that was already being assembled via napi_build_skb() /
> napi_get_frags():
>
> gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE);
> if (!gpage) {
> dev_err(geth->dev, "could not find mapping\n");
> /* BUG: skb leaked here */
> port->stats.rx_dropped++;
> continue;
> }
>
> This path is distinct from the similar block in gmac_cleanup_rxq(), which
> correctly only logs "could not find page" without an skb in flight.
>
> Each occurrence of this error path leaks one skb. Under sustained traffic
> the leak exhausts kernel memory, causing the observed lockup.
>
> Free the in-progress skb via napi_free_frags() before continuing, matching
> the pattern already used elsewhere in the driver.
>
> Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
> Signed-off-by: Andreas Haarmann-Thiemann <eitschman@nebelreich.de>
> Signed-off-by: Linus Walleij <linusw@kernel.org>
Thanks for handling (what I assume to be) an external report Linus!
Not sure I'm connecting the dots here, tho.
Apparently skb is a static variable in this function(!?) so the skb
should be flushed on the next SOP?
Also I don't see how potential memory leak squares with the first
sentence of the commit which reads:
device freezes completely and requires a hard power cycle
how can kernel mem leak cause a device to wedge?
> diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
> index 4824232f4890..723d90d5fdf3 100644
> --- a/drivers/net/ethernet/cortina/gemini.c
> +++ b/drivers/net/ethernet/cortina/gemini.c
> @@ -1491,6 +1491,10 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
> gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE);
> if (!gpage) {
> dev_err(geth->dev, "could not find mapping\n");
> + if (skb) {
> + napi_free_frags(&port->napi);
> + skb = NULL;
> + }
> continue;
> }
> page = gpage->page;
>
> ---
> base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
> change-id: 20260330-gemini-ethernet-fix-604c28c53da1
>
> Best regards,
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net] net: ethernet: cortina: Fix SKB leak
2026-03-30 6:00 [PATCH net] net: ethernet: cortina: Fix SKB leak Linus Walleij
2026-04-01 2:14 ` Jakub Kicinski
@ 2026-04-01 11:06 ` Li Xiasong
1 sibling, 0 replies; 3+ messages in thread
From: Li Xiasong @ 2026-04-01 11:06 UTC (permalink / raw)
To: Linus Walleij
Cc: Hans Ulli Kroll, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Michał Mirosław, netdev,
Andreas Haarmann-Thiemann, yuehaibing, zhangchangzhong,
weiyongjun1
Hi,Linus
On 3/30/2026 2:00 PM, Linus Walleij wrote:
> From: Andreas Haarmann-Thiemann <eitschman@nebelreich.de>
>
> Under sustained RX load (e.g. large file transfers over the network), the
> device freezes completely and requires a hard power cycle. No kernel panic
> or oops is produced; the system simply stops responding.
>
> In gmac_rx() (drivers/net/ethernet/cortina/gemini.c), when
> gmac_get_queue_page() returns NULL for the second page of a multi-page
> fragment, the driver logs an error and continues — but does not free the
> in-progress skb that was already being assembled via napi_build_skb() /
> napi_get_frags():
>
> gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE);
> if (!gpage) {
> dev_err(geth->dev, "could not find mapping\n");
> /* BUG: skb leaked here */
> port->stats.rx_dropped++;
> continue;
> }
>
> This path is distinct from the similar block in gmac_cleanup_rxq(), which
> correctly only logs "could not find page" without an skb in flight.
>
> Each occurrence of this error path leaks one skb. Under sustained traffic
> the leak exhausts kernel memory, causing the observed lockup.
>
> Free the in-progress skb via napi_free_frags() before continuing, matching
> the pattern already used elsewhere in the driver.
>
> Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
> Signed-off-by: Andreas Haarmann-Thiemann <eitschman@nebelreich.de>
> Signed-off-by: Linus Walleij <linusw@kernel.org>
> ---
> drivers/net/ethernet/cortina/gemini.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
> index 4824232f4890..723d90d5fdf3 100644
> --- a/drivers/net/ethernet/cortina/gemini.c
> +++ b/drivers/net/ethernet/cortina/gemini.c
> @@ -1491,6 +1491,10 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
> gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE);
> if (!gpage) {
> dev_err(geth->dev, "could not find mapping\n");
> + if (skb) {
> + napi_free_frags(&port->napi);
> + skb = NULL;
Quick question out of curiosity.
In the fix at gmac_rx(), when gmac_get_queue_page() fails for the second
page of a multi-page fragment, the SKB is freed via napi_free_frags().
However, I noticed that port->stats.rx_dropped++ is not incremented here.
Comparing with the similar code path, when a stale SKB is found at SOF_BIT,
both napi_free_frags() and rx_dropped++ are called. Would it make sense to
add the drop counter here for consistency, or is there a reason to omit it.
Thanks for your time,
Li Xiasong
> + }
> continue;
> }
> page = gpage->page;
>
> ---
> base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
> change-id: 20260330-gemini-ethernet-fix-604c28c53da1
>
> Best regards,
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-04-01 11:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-30 6:00 [PATCH net] net: ethernet: cortina: Fix SKB leak Linus Walleij
2026-04-01 2:14 ` Jakub Kicinski
2026-04-01 11:06 ` Li Xiasong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox