* [PATCH] r8169: avoid OOM when allocating RX buffers @ 2026-02-16 18:52 Fabian Druschke 2026-02-16 19:35 ` Eric Dumazet 2026-02-16 20:13 ` Andrew Lunn 0 siblings, 2 replies; 5+ messages in thread From: Fabian Druschke @ 2026-02-16 18:52 UTC (permalink / raw) To: Heiner Kallweit, nic_swsd Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, stable, Fabian Druschke From: Fabian Druschke <fdruschke@outlook.com> r8169 allocates order-2 pages for RX buffers during rtl_open(). Under heavy memory fragmentation this allocation may trigger the global OOM killer, causing unrelated user processes to be killed. Use a GFP mask that avoids OOM killer invocation so the allocation can fail gracefully and rtl_open() returns -ENOMEM instead. Cc: stable@vger.kernel.org Signed-off-by: Fabian Druschke <fdruschke@outlook.com> --- drivers/net/ethernet/realtek/r8169_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 3507c2e28110..3525e889ec1c 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -3952,7 +3952,8 @@ static struct page *rtl8169_alloc_rx_data(struct rtl8169_private *tp, dma_addr_t mapping; struct page *data; - data = alloc_pages_node(node, GFP_KERNEL, get_order(R8169_RX_BUF_SIZE)); + gfp_t gfp = GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN; + data = alloc_pages_node(node, gfp, get_order(R8169_RX_BUF_SIZE)); if (!data) return NULL; -- 2.52.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] r8169: avoid OOM when allocating RX buffers 2026-02-16 18:52 [PATCH] r8169: avoid OOM when allocating RX buffers Fabian Druschke @ 2026-02-16 19:35 ` Eric Dumazet 2026-02-16 20:13 ` Andrew Lunn 1 sibling, 0 replies; 5+ messages in thread From: Eric Dumazet @ 2026-02-16 19:35 UTC (permalink / raw) To: Fabian Druschke Cc: Heiner Kallweit, nic_swsd, David S . Miller, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, stable, Fabian Druschke On Mon, Feb 16, 2026 at 7:53 PM Fabian Druschke <fabian@druschke.network> wrote: > > From: Fabian Druschke <fdruschke@outlook.com> > > r8169 allocates order-2 pages for RX buffers during rtl_open(). Under heavy > memory fragmentation this allocation may trigger the global OOM killer, > causing unrelated user processes to be killed. > > Use a GFP mask that avoids OOM killer invocation so the allocation can fail > gracefully and rtl_open() returns -ENOMEM instead. > > Cc: stable@vger.kernel.org > Signed-off-by: Fabian Druschke <fdruschke@outlook.com> > --- > drivers/net/ethernet/realtek/r8169_main.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c > index 3507c2e28110..3525e889ec1c 100644 > --- a/drivers/net/ethernet/realtek/r8169_main.c > +++ b/drivers/net/ethernet/realtek/r8169_main.c > @@ -3952,7 +3952,8 @@ static struct page *rtl8169_alloc_rx_data(struct rtl8169_private *tp, > dma_addr_t mapping; > struct page *data; > > - data = alloc_pages_node(node, GFP_KERNEL, get_order(R8169_RX_BUF_SIZE)); > + gfp_t gfp = GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN; > + data = alloc_pages_node(node, gfp, get_order(R8169_RX_BUF_SIZE)); > if (!data) > return NULL; Control path prefers to wait a bit so that the NIC can be setup, this could be used for instance to enable swaping over the network. Note that this is GFP_KERNEL here, not GFP_KERNEL_ACCOUNT , OOM seems reasonable here. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] r8169: avoid OOM when allocating RX buffers 2026-02-16 18:52 [PATCH] r8169: avoid OOM when allocating RX buffers Fabian Druschke 2026-02-16 19:35 ` Eric Dumazet @ 2026-02-16 20:13 ` Andrew Lunn 2026-02-17 21:50 ` Fabian Druschke 1 sibling, 1 reply; 5+ messages in thread From: Andrew Lunn @ 2026-02-16 20:13 UTC (permalink / raw) To: Fabian Druschke Cc: Heiner Kallweit, nic_swsd, David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, stable, Fabian Druschke On Mon, Feb 16, 2026 at 07:52:45PM +0100, Fabian Druschke wrote: > From: Fabian Druschke <fdruschke@outlook.com> > > r8169 allocates order-2 pages for RX buffers during rtl_open(). Under heavy > memory fragmentation this allocation may trigger the global OOM killer, > causing unrelated user processes to be killed. > > Use a GFP mask that avoids OOM killer invocation so the allocation can fail > gracefully and rtl_open() returns -ENOMEM instead. > > Cc: stable@vger.kernel.org > Signed-off-by: Fabian Druschke <fdruschke@outlook.com> > --- > drivers/net/ethernet/realtek/r8169_main.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c > index 3507c2e28110..3525e889ec1c 100644 > --- a/drivers/net/ethernet/realtek/r8169_main.c > +++ b/drivers/net/ethernet/realtek/r8169_main.c > @@ -3952,7 +3952,8 @@ static struct page *rtl8169_alloc_rx_data(struct rtl8169_private *tp, > dma_addr_t mapping; > struct page *data; > > - data = alloc_pages_node(node, GFP_KERNEL, get_order(R8169_RX_BUF_SIZE)); > + gfp_t gfp = GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN; > + data = alloc_pages_node(node, gfp, get_order(R8169_RX_BUF_SIZE)); > if (!data) > return NULL; ~/linux/drivers/net$ grep -r alloc_pages_node ethernet/chelsio/cxgb4/cxgb4_main.c: newpage = alloc_pages_node(node, __GFP_NOWARN | GFP_KERNEL | ethernet/chelsio/cxgb4/sge.c: pg = alloc_pages_node(node, gfp | __GFP_COMP, s->fl_pg_order); ethernet/chelsio/cxgb4/sge.c: pg = alloc_pages_node(node, gfp, 0); ethernet/amd/xgbe/xgbe-desc.c: pages = alloc_pages_node(node, gfp, order); ethernet/fungible/funcore/fun_queue.c: rqinfo->page = alloc_pages_node(node, GFP_KERNEL, 0); ethernet/fungible/funeth/funeth_rx.c: p = __alloc_pages_node(node, gfp | __GFP_NOWARN, 0); ethernet/mellanox/mlx5/core/pagealloc.c: page = alloc_pages_node(nid, GFP_HIGHUSER, 0); ethernet/mellanox/mlx5/core/en_main.c: struct page *page = alloc_pages_node(node, GFP_KERNEL, 0); ethernet/mellanox/mlx4/icm.c: page = alloc_pages_node(node, gfp_mask, order); ethernet/realtek/r8169_main.c: data = alloc_pages_node(node, GFP_KERNEL, get_order(R8169_RX_BUF_SIZE)); ethernet/google/gve/gve_main.c: *page = alloc_pages_node(priv->numa_node, gfp_flags, 0); ethernet/google/gve/gve_rx.c: struct page *page = alloc_pages_node(priv->numa_node, ethernet/google/gve/gve_rx_dqo.c: struct page *page = alloc_pages_node(rx->gve->numa_node, GFP_ATOMIC, 0); ethernet/hisilicon/hns3/hns3_enet.c: page = alloc_pages_node(dev_to_node(ring_to_dev(ring)), :~/linux/drivers/net$ grep -r __GFP_RETRY_MAYFAIL veth.c: GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL); What makes the r8169 special? Andrew ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] r8169: avoid OOM when allocating RX buffers 2026-02-16 20:13 ` Andrew Lunn @ 2026-02-17 21:50 ` Fabian Druschke 2026-02-17 22:33 ` Jakub Kicinski 0 siblings, 1 reply; 5+ messages in thread From: Fabian Druschke @ 2026-02-17 21:50 UTC (permalink / raw) To: Andrew Lunn, Fabian Druschke Cc: Heiner Kallweit, nic_swsd, David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, stable Ahoy! Thanks for clarification! Didn't know it was intended behaviour. We've encountered this issue specifically with this Realtek NIC on ShredOS due to lack of mlx5, mlx4 etc. For NICs like ixgbe we didn't encounter this issue so i was thinking about a bug. Thanks though! BR, On 16/02/2026 21:13, Andrew Lunn wrote: > On Mon, Feb 16, 2026 at 07:52:45PM +0100, Fabian Druschke wrote: >> From: Fabian Druschke <fdruschke@outlook.com> >> >> r8169 allocates order-2 pages for RX buffers during rtl_open(). Under heavy >> memory fragmentation this allocation may trigger the global OOM killer, >> causing unrelated user processes to be killed. >> >> Use a GFP mask that avoids OOM killer invocation so the allocation can fail >> gracefully and rtl_open() returns -ENOMEM instead. >> >> Cc: stable@vger.kernel.org >> Signed-off-by: Fabian Druschke <fdruschke@outlook.com> >> --- >> drivers/net/ethernet/realtek/r8169_main.c | 3 ++- >> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c >> index 3507c2e28110..3525e889ec1c 100644 >> --- a/drivers/net/ethernet/realtek/r8169_main.c >> +++ b/drivers/net/ethernet/realtek/r8169_main.c >> @@ -3952,7 +3952,8 @@ static struct page *rtl8169_alloc_rx_data(struct rtl8169_private *tp, >> dma_addr_t mapping; >> struct page *data; >> >> - data = alloc_pages_node(node, GFP_KERNEL, get_order(R8169_RX_BUF_SIZE)); >> + gfp_t gfp = GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN; >> + data = alloc_pages_node(node, gfp, get_order(R8169_RX_BUF_SIZE)); >> if (!data) >> return NULL; > ~/linux/drivers/net$ grep -r alloc_pages_node > ethernet/chelsio/cxgb4/cxgb4_main.c: newpage = alloc_pages_node(node, __GFP_NOWARN | GFP_KERNEL | > ethernet/chelsio/cxgb4/sge.c: pg = alloc_pages_node(node, gfp | __GFP_COMP, s->fl_pg_order); > ethernet/chelsio/cxgb4/sge.c: pg = alloc_pages_node(node, gfp, 0); > ethernet/amd/xgbe/xgbe-desc.c: pages = alloc_pages_node(node, gfp, order); > ethernet/fungible/funcore/fun_queue.c: rqinfo->page = alloc_pages_node(node, GFP_KERNEL, 0); > ethernet/fungible/funeth/funeth_rx.c: p = __alloc_pages_node(node, gfp | __GFP_NOWARN, 0); > ethernet/mellanox/mlx5/core/pagealloc.c: page = alloc_pages_node(nid, GFP_HIGHUSER, 0); > ethernet/mellanox/mlx5/core/en_main.c: struct page *page = alloc_pages_node(node, GFP_KERNEL, 0); > ethernet/mellanox/mlx4/icm.c: page = alloc_pages_node(node, gfp_mask, order); > ethernet/realtek/r8169_main.c: data = alloc_pages_node(node, GFP_KERNEL, get_order(R8169_RX_BUF_SIZE)); > ethernet/google/gve/gve_main.c: *page = alloc_pages_node(priv->numa_node, gfp_flags, 0); > ethernet/google/gve/gve_rx.c: struct page *page = alloc_pages_node(priv->numa_node, > ethernet/google/gve/gve_rx_dqo.c: struct page *page = alloc_pages_node(rx->gve->numa_node, GFP_ATOMIC, 0); > ethernet/hisilicon/hns3/hns3_enet.c: page = alloc_pages_node(dev_to_node(ring_to_dev(ring)), > > :~/linux/drivers/net$ grep -r __GFP_RETRY_MAYFAIL > veth.c: GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL); > > What makes the r8169 special? > > Andrew ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] r8169: avoid OOM when allocating RX buffers 2026-02-17 21:50 ` Fabian Druschke @ 2026-02-17 22:33 ` Jakub Kicinski 0 siblings, 0 replies; 5+ messages in thread From: Jakub Kicinski @ 2026-02-17 22:33 UTC (permalink / raw) To: Fabian Druschke Cc: Andrew Lunn, Fabian Druschke, Heiner Kallweit, nic_swsd, David S . Miller, Eric Dumazet, Paolo Abeni, netdev, linux-kernel, stable On Tue, 17 Feb 2026 22:50:30 +0100 Fabian Druschke wrote: > Ahoy! Thanks for clarification! Didn't know it was intended behaviour. > > We've encountered this issue specifically with this Realtek NIC on > ShredOS due to lack of mlx5, mlx4 etc. > > For NICs like ixgbe we didn't encounter this issue so i was thinking > about a bug. Most / all "professional grade"(??) NICs support scatter, where larger frames are written into multiple chunks, 4kB each. order-2 allocations on the fast path are a bad idea. One way to alleviate the performance implications would be to use page pool, but that doesn't help with the initial fill, just the datapath :( reminder: please avoid top posting when replying on the mailing list ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-02-17 22:33 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-16 18:52 [PATCH] r8169: avoid OOM when allocating RX buffers Fabian Druschke 2026-02-16 19:35 ` Eric Dumazet 2026-02-16 20:13 ` Andrew Lunn 2026-02-17 21:50 ` Fabian Druschke 2026-02-17 22:33 ` Jakub Kicinski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox