* [PATCH net v5 0/2] gve: fix RX page refcount overflow with the pagecnt bias @ 2026-11-09 10:04 Amaan Cheval 2026-11-09 10:04 ` [PATCH net v5 1/2] gve: refuse XDP on queue formats without XDP support Amaan Cheval 2026-11-09 10:04 ` [PATCH net v5 2/2] gve: fix RX page refcount overflow from INT_MAX pagecnt_bias Amaan Cheval 0 siblings, 2 replies; 5+ messages in thread From: Amaan Cheval @ 2026-11-09 10:04 UTC (permalink / raw) To: netdev Cc: joshwash, hramamurthy, andrew+netdev, davem, edumazet, kuba, pabeni, bcf, jordanrhee, przemyslaw.kitszel, maciej.fijalkowski, pkaligineedi, maolson, csully, willemb, yangchun, npl, awogbemila, shailend, nktgrg, maxyuan, bpf, john.fastabend, hawk, sdf, daniel, ast, linux-kernel, stable, Amaan Cheval gve's GQI and DQO-QPL RX paths bias every RX page's refcount to INT_MAX, so a single get_page() from the stack, e.g. splice() of received data, overflows it: splice/tee fail with EIO/EFAULT and GQI can reset the NIC. Patch 2 lowers the bias to USHRT_MAX, as other drivers do. With the smaller bias the driver gives up its last reference on a page once every USHRT_MAX handoffs instead of once every INT_MAX, which is only safe while every consumer holds its reference until the buffer is recycled. That is not the case for an XDP_REDIRECT from DQO-QPL to an AF_XDP socket in copy mode, a path the driver never meant to support: commit d8a8ca14c937 dropped the queue_format check that used to refuse it. Patch 1 refuses XDP on any queue format the driver advertises no XDP features for, which today means DQO-QPL, so patch 2 depends on it. Trees before 6.17 still have the old check, so there patch 2 stands alone. Harshitha mentioned on v2 that Google would send a patch blocking XDP on DQO-QPL; if one is already in flight I'm happy to drop patch 1 in its favour. v5: - Patch 1: check dev->xdp_features instead of queue_format, and reword the subject and message around that (Joshua). - Patch 2: name INT_MAX in the subject. No code change. v4: https://lore.kernel.org/netdev/20261106114551.212675-1-amaan.cheval@gmail.com/ - Add patch 1/2 blocking XDP on DQO-QPL (Sashiko). - Say "overflow" instead of "headroom"; use USHRT_MAX directly instead of a macro (Maciej). - Say which trees need patch 1, for stable. v3: https://lore.kernel.org/netdev/20261103090651.35399-1-amaan.cheval@gmail.com/ v2: https://lore.kernel.org/netdev/20261102112613.18334-1-amaan.cheval@gmail.com/ v1: https://lore.kernel.org/netdev/20261031173449.2439047-1-amaan.cheval@gmail.com/ Amaan Cheval (2): gve: refuse XDP on queue formats without XDP support gve: fix RX page refcount overflow from INT_MAX pagecnt_bias drivers/net/ethernet/google/gve/gve.h | 2 +- .../net/ethernet/google/gve/gve_buffer_mgmt_dqo.c | 4 ++-- drivers/net/ethernet/google/gve/gve_main.c | 6 ++++++ drivers/net/ethernet/google/gve/gve_rx.c | 8 ++++---- drivers/net/ethernet/google/gve/gve_utils.c | 12 ++++-------- drivers/net/ethernet/google/gve/gve_utils.h | 2 +- 6 files changed, 18 insertions(+), 16 deletions(-) base-commit: 21f57ec673a1917547c808cfa81890485fffa03b -- 2.47.3 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net v5 1/2] gve: refuse XDP on queue formats without XDP support 2026-11-09 10:04 [PATCH net v5 0/2] gve: fix RX page refcount overflow with the pagecnt bias Amaan Cheval @ 2026-11-09 10:04 ` Amaan Cheval 2026-11-09 19:45 ` Joshua Washington 2026-11-11 10:06 ` netdev-bot+sashiko 2026-11-09 10:04 ` [PATCH net v5 2/2] gve: fix RX page refcount overflow from INT_MAX pagecnt_bias Amaan Cheval 1 sibling, 2 replies; 5+ messages in thread From: Amaan Cheval @ 2026-11-09 10:04 UTC (permalink / raw) To: netdev Cc: joshwash, hramamurthy, andrew+netdev, davem, edumazet, kuba, pabeni, bcf, jordanrhee, przemyslaw.kitszel, maciej.fijalkowski, pkaligineedi, maolson, csully, willemb, yangchun, npl, awogbemila, shailend, nktgrg, maxyuan, bpf, john.fastabend, hawk, sdf, daniel, ast, linux-kernel, stable, Amaan Cheval Commit d8a8ca14c937 ("gve: add XDP_TX and XDP_REDIRECT support for DQ RDA") enabled XDP on DQO-RDA by dropping the queue_format check from verify_xdp_configuration(), which until then refused every format but GQI-QPL. Nothing replaced it: gve_set_netdev_xdp_features() advertises no XDP features for DQO-QPL and gve_xdp_xmit() rejects it, but the core only checks that ndo_bpf exists, so a native XDP program, and an AF_XDP socket on top of it, can still be attached on a queue format the driver does not support. The DQO-QPL RX path was never written for that. Its page accounting assumes the driver keeps a reference of its own across every handoff: gve_xdp_done_dqo() passes the buffer to xdp_do_redirect() and then recycles it with gve_reuse_buffer(), so a redirect target that releases the buffer synchronously, such as an AF_XDP socket in copy mode, can drop the page's last reference when pagecnt_bias runs out. The page is then freed while it is still DMA-mapped and registered in the QPL, and the driver posts it back to the device. Refuse XDP setup in gve_verify_xdp_configuration() whenever the driver advertises no XDP features for the current queue format, which today means DQO-QPL. A zero-copy XSK pool bind is already refused by the core for the same reason, and a copy-mode bind never reaches the driver and is harmless without a program. Fixes: d8a8ca14c937 ("gve: add XDP_TX and XDP_REDIRECT support for DQ RDA") Cc: stable@vger.kernel.org Signed-off-by: Amaan Cheval <amaan.cheval@gmail.com> --- v5: - Check dev->xdp_features instead of queue_format, and reword the subject and message around that (Joshua). v4: https://lore.kernel.org/netdev/20261106114551.212675-2-amaan.cheval@gmail.com/ drivers/net/ethernet/google/gve/gve_main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c index 2437cd8ba633..fe560f5c5408 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c @@ -1723,6 +1723,12 @@ static int gve_verify_xdp_configuration(struct net_device *dev, struct gve_priv *priv = netdev_priv(dev); u16 max_xdp_mtu; + if (!(dev->xdp_features & NETDEV_XDP_ACT_BASIC)) { + NL_SET_ERR_MSG_MOD(extack, + "XDP is not supported on this queue format."); + return -EOPNOTSUPP; + } + if (dev->features & NETIF_F_GRO_HW) { NL_SET_ERR_MSG_MOD(extack, "XDP is not supported when HW-GRO is on."); -- 2.47.3 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net v5 1/2] gve: refuse XDP on queue formats without XDP support 2026-11-09 10:04 ` [PATCH net v5 1/2] gve: refuse XDP on queue formats without XDP support Amaan Cheval @ 2026-11-09 19:45 ` Joshua Washington 2026-11-11 10:06 ` netdev-bot+sashiko 1 sibling, 0 replies; 5+ messages in thread From: Joshua Washington @ 2026-11-09 19:45 UTC (permalink / raw) To: Amaan Cheval Cc: netdev, hramamurthy, andrew+netdev, davem, edumazet, kuba, pabeni, bcf, jordanrhee, przemyslaw.kitszel, maciej.fijalkowski, pkaligineedi, maolson, csully, willemb, yangchun, npl, awogbemila, shailend, nktgrg, maxyuan, bpf, john.fastabend, hawk, sdf, daniel, ast, linux-kernel, stable On Mon, Nov 9, 2026 at 2:05 AM Amaan Cheval <amaan.cheval@gmail.com> wrote: > > Commit d8a8ca14c937 ("gve: add XDP_TX and XDP_REDIRECT support for DQ > RDA") enabled XDP on DQO-RDA by dropping the queue_format check from > verify_xdp_configuration(), which until then refused every format but > GQI-QPL. Nothing replaced it: gve_set_netdev_xdp_features() advertises > no XDP features for DQO-QPL and gve_xdp_xmit() rejects it, but the core > only checks that ndo_bpf exists, so a native XDP program, and an AF_XDP > socket on top of it, can still be attached on a queue format the driver > does not support. > > The DQO-QPL RX path was never written for that. Its page accounting > assumes the driver keeps a reference of its own across every handoff: > gve_xdp_done_dqo() passes the buffer to xdp_do_redirect() and then > recycles it with gve_reuse_buffer(), so a redirect target that releases > the buffer synchronously, such as an AF_XDP socket in copy mode, can > drop the page's last reference when pagecnt_bias runs out. The page is > then freed while it is still DMA-mapped and registered in the QPL, and > the driver posts it back to the device. > > Refuse XDP setup in gve_verify_xdp_configuration() whenever the driver > advertises no XDP features for the current queue format, which today > means DQO-QPL. A zero-copy XSK pool bind is already refused by the core > for the same reason, and a copy-mode bind never reaches the driver and > is harmless without a program. > > Fixes: d8a8ca14c937 ("gve: add XDP_TX and XDP_REDIRECT support for DQ RDA") > Cc: stable@vger.kernel.org > Signed-off-by: Amaan Cheval <amaan.cheval@gmail.com> Reviewed-by: Joshua Washington <joshwash@google.com> > --- > v5: > - Check dev->xdp_features instead of queue_format, and reword the > subject and message around that (Joshua). > v4: https://lore.kernel.org/netdev/20261106114551.212675-2-amaan.cheval@gmail.com/ > > drivers/net/ethernet/google/gve/gve_main.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c > index 2437cd8ba633..fe560f5c5408 100644 > --- a/drivers/net/ethernet/google/gve/gve_main.c > +++ b/drivers/net/ethernet/google/gve/gve_main.c > @@ -1723,6 +1723,12 @@ static int gve_verify_xdp_configuration(struct net_device *dev, > struct gve_priv *priv = netdev_priv(dev); > u16 max_xdp_mtu; > > + if (!(dev->xdp_features & NETDEV_XDP_ACT_BASIC)) { > + NL_SET_ERR_MSG_MOD(extack, > + "XDP is not supported on this queue format."); > + return -EOPNOTSUPP; > + } > + > if (dev->features & NETIF_F_GRO_HW) { > NL_SET_ERR_MSG_MOD(extack, > "XDP is not supported when HW-GRO is on."); > -- > 2.47.3 > Thanks! ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net v5 1/2] gve: refuse XDP on queue formats without XDP support 2026-11-09 10:04 ` [PATCH net v5 1/2] gve: refuse XDP on queue formats without XDP support Amaan Cheval 2026-11-09 19:45 ` Joshua Washington @ 2026-11-11 10:06 ` netdev-bot+sashiko 1 sibling, 0 replies; 5+ messages in thread From: netdev-bot+sashiko @ 2026-11-11 10:06 UTC (permalink / raw) To: amaan.cheval Cc: netdev, joshwash, hramamurthy, andrew+netdev, davem, edumazet, kuba, pabeni, bcf, jordanrhee, przemyslaw.kitszel, maciej.fijalkowski, pkaligineedi, maolson, csully, willemb, yangchun, npl, awogbemila, shailend, nktgrg, maxyuan, bpf, john.fastabend, hawk, sdf, daniel, ast, linux-kernel, stable Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider. Critical: 0 · High: 0 (1) · Medium: 1 · Low: 0 If you believe none of the issues are legitimate, please reply to each issue of Medium severity or higher and explain why the AI is wrong. If any of them are legitimate and you plan to respin, please let patchwork know by including "pw-bot: cr" as a separate line at the end of your reply (one such reply per series is enough). - [Medium] The commit message misstates which queue formats the new check affects. Pre-existing issues: - [High] This problem wasn't introduced by this patch, but the patch extends it. -- gve: refuse XDP on queue formats without XDP support This patch adds a check to gve_verify_xdp_configuration() that refuses XDP setup when dev->xdp_features lacks NETDEV_XDP_ACT_BASIC. It replaces the queue format gate dropped by commit d8a8ca14c937. The aim is to keep XDP off DQO-QPL, whose RX page accounting can free a page that is still DMA-mapped and registered in the QPL. > Refuse XDP setup in gve_verify_xdp_configuration() whenever the driver > advertises no XDP features for the current queue format, which today > means DQO-QPL. [Severity: Medium] Is "which today means DQO-QPL" accurate? gve_set_netdev_xdp_features() only sets NETDEV_XDP_ACT_BASIC for GQI-QPL and DQO-RDA: drivers/net/ethernet/google/gve/gve_main.c:gve_set_netdev_xdp_features() { if (priv->queue_format == GVE_GQI_QPL_FORMAT) { xdp_features = NETDEV_XDP_ACT_BASIC; ... } else if (priv->queue_format == GVE_DQO_RDA_FORMAT) { xdp_features = NETDEV_XDP_ACT_BASIC; ... } else { xdp_features = 0; } ... } GQI-RDA also falls into the else branch. gve_adminq.c can still select GVE_GQI_RDA_FORMAT from the GQI_RDA and GQI_RAW_ADDRESSING device options, so the new check refuses GQI-RDA as well. The check that d8a8ca14c937 removed (queue_format != GVE_GQI_QPL_FORMAT) also refused GQI-RDA. Since that commit, XDP could be attached on GQI-RDA, and XDP_TX there takes this path: gve_rx() gve_xdp_done() gve_xdp_xmit_one() gve_tx_fill_xdp() gve_tx_fill_xdp() always uses tx->tx_fifo: it calls gve_tx_alloc_fifo(), memcpy()s into tx->tx_fifo.base and reads tx->tx_fifo.qpl->page_buses. A raw-addressing TX ring never allocates that FIFO. Isn't that a NULL dereference that this patch also fixes without saying so? Could the commit message mention GQI-RDA? Two things are worth stating: GQI-RDA now gets -EOPNOTSUPP, and this closes the XDP_TX crash there. That would help stable backporters. The follow-up patch "gve: fix RX page refcount overflow from INT_MAX pagecnt_bias" uses the same wording ("The previous patch keeps it that way by blocking XDP on DQO-QPL"). Its safety argument also depends on XDP being blocked on GQI-RDA. > diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c > index 2437cd8ba6331..fe560f5c5408c 100644 > --- a/drivers/net/ethernet/google/gve/gve_main.c > +++ b/drivers/net/ethernet/google/gve/gve_main.c > @@ -1723,6 +1723,12 @@ static int gve_verify_xdp_configuration(struct net_device *dev, > struct gve_priv *priv = netdev_priv(dev); > u16 max_xdp_mtu; > > + if (!(dev->xdp_features & NETDEV_XDP_ACT_BASIC)) { > + NL_SET_ERR_MSG_MOD(extack, > + "XDP is not supported on this queue format."); > + return -EOPNOTSUPP; > + } > + [Severity: High] This is a pre-existing issue that this patch did not introduce, but the patch adds another exit to the same gate. gve_xdp() calls gve_verify_xdp_configuration() before it looks at the command, so the gate also runs for teardown: drivers/net/ethernet/google/gve/gve_main.c:gve_xdp() { err = gve_verify_xdp_configuration(dev, xdp->extack); if (err) return err; switch (xdp->command) { case XDP_SETUP_PROG: return gve_set_xdp(priv, xdp->prog, xdp->extack); case XDP_SETUP_XSK_POOL: if (xdp->xsk.pool) ... else return gve_xsk_pool_disable(dev, xdp->xsk.queue_id); ... } Several of the gate's conditions can become true after a successful bind: - gve has no ndo_change_mtu, so the MTU can be raised above max_xdp_mtu while a zero-copy pool is bound. - gve_set_features() refuses HW-GRO only when priv->xdp_prog is set, so HW-GRO can be turned on while only a pool is bound. - The queue counts can be changed the same way. When the AF_XDP socket is then closed: xp_release_deferred() xp_clear_dev() __xp_clear_dev() xp_disable_drv_zc() gve_xdp() gve_verify_xdp_configuration() /* returns -EOPNOTSUPP */ On failure, xp_disable_drv_zc() only does WARN(1, "Failed to disable zero-copy!\n"). The core then goes on to xsk_clear_pool_at_qid(), xdp_put_umem() and xp_destroy(). Because gve_xsk_pool_disable() never runs, clear_bit(qid, priv->xsk_pools), xsk_pool_dma_unmap() and gve_unreg_xsk_pool() are all skipped. Won't rx->xsk_pool and tx->xsk_pool still point at the freed pool when the RX refill and XSK TX NAPI paths use them? The UMEM DMA mappings would also be leaked. dev_xdp_uninstall() follows the same pattern for programs. It does WARN_ON() on the failed removal and then calls bpf_prog_put(), which leaves priv->xdp_prog dangling. The new xdp_features check cannot change between setup and teardown by itself, since gve_setup_device() computes it only from queue_format. Even so, would it be better to run the verification only for XDP_SETUP_PROG with a non-NULL prog and for pool enable, so that teardown is never refused? -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261109100437.331423-1-amaan.cheval%40gmail.com ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net v5 2/2] gve: fix RX page refcount overflow from INT_MAX pagecnt_bias 2026-11-09 10:04 [PATCH net v5 0/2] gve: fix RX page refcount overflow with the pagecnt bias Amaan Cheval 2026-11-09 10:04 ` [PATCH net v5 1/2] gve: refuse XDP on queue formats without XDP support Amaan Cheval @ 2026-11-09 10:04 ` Amaan Cheval 1 sibling, 0 replies; 5+ messages in thread From: Amaan Cheval @ 2026-11-09 10:04 UTC (permalink / raw) To: netdev Cc: joshwash, hramamurthy, andrew+netdev, davem, edumazet, kuba, pabeni, bcf, jordanrhee, przemyslaw.kitszel, maciej.fijalkowski, pkaligineedi, maolson, csully, willemb, yangchun, npl, awogbemila, shailend, nktgrg, maxyuan, bpf, john.fastabend, hawk, sdf, daniel, ast, linux-kernel, stable, Amaan Cheval gve's GQI and DQO-QPL RX paths set every RX page's refcount to INT_MAX and hand references to the stack by decrementing page_info->pagecnt_bias, to avoid an atomic op per packet. This leaves no room for anyone else: while a fresh page's buffer sits in an skb its refcount is already INT_MAX, so a single get_page() from the stack overflows it to negative. splice() of received TCP data into a pipe takes such a reference, and the onward splice into a socket then fails: skb_splice_from_iter() sees page_count() < 1, sendpage_ok() fails and the send returns -EIO (since commit 2e910b95329c ("net: Add a function to splice pages into an skbuff for MSG_SPLICE_PAGES")). tee() of the pipe fails with -EFAULT via try_get_page(). On GQI the reuse check gve_rx_can_recycle_buffer() also sees page_count() < pagecnt_bias, WARNs and calls gve_schedule_reset(), so a task that merely pins a fresh RX page (e.g. holds spliced data in an undrained tee() pipe) can reset the NIC. Use USHRT_MAX in a u16, as igb, igc, ixgbe, i40e and hns3 do: the bias only has to make the per-packet atomic rare, so a small value keeps page_count() far below INT_MAX however many references the stack takes. Refill by adding a fixed batch and setting the bias to it, which keeps the rule `references = page_count() - bias` intact. Refilling at 0 hands the driver's last reference to the consumer once every USHRT_MAX handoffs rather than once every INT_MAX, which is only safe because every consumer on these paths holds its reference until the driver has recycled the buffer. The previous patch keeps it that way by blocking XDP on DQO-QPL, so this one depends on it. Trees before 6.17, without commit d8a8ca14c937 ("gve: add XDP_TX and XDP_REDIRECT support for DQ RDA"), still refuse XDP on every format but GQI-QPL in verify_xdp_configuration(), so there this patch stands alone. Reproduced on gVNIC in GQI-QPL mode (GCE n2-standard-8, 6.12) and in DQO-RDA mode (GCE c3-standard-8, 6.12, where DQO-RDA still uses the bias) with the help of relay.py -- a small splice(2) TCP proxy -- relaying a download while the RX ring is refilled with fresh pages: ethtool -G eth0 rx 512 && ethtool -G eth0 rx 1024 # fresh RX pages ./relay.py $HOST 8080 & # splice()s both ways for i in $(seq 200); do curl -so /dev/null \ --connect-to $HOST:80:127.0.0.1:8080 http://$HOST/file; done Most downloads failed with EIO before the fix (tee() with EFAULT) and all completed after it. relay.py is at the Link below. This bug was found and fixed with the help of an AI coding assistant (Claude Code) over an interactive session; it read the driver and splice/pipe code and ran the tests above. Link: https://github.com/amaanc/kernel-bias Fixes: 9b8dd5e5ea48 ("gve: DQO: Add RX path") Fixes: 58401b2a46e7 ("gve: Add rx buffer pagecnt bias") Fixes: 82fd151d38d9 ("gve: Reduce alloc and copy costs in the GQ rx path") Cc: stable@vger.kernel.org Reviewed-by: Harshitha Ramamurthy <hramamurthy@google.com> Tested-by: Harshitha Ramamurthy <hramamurthy@google.com> Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com> Signed-off-by: Amaan Cheval <amaan.cheval@gmail.com> --- v5: - Name INT_MAX in the subject. No code change; patch 1/2 changed. v4: https://lore.kernel.org/netdev/20261106114551.212675-3-amaan.cheval@gmail.com/ - Add patch 1/2, blocking XDP on DQO-QPL, which this fix depends on (Sashiko). Harshitha said Google would send such a patch; I'm happy to drop 1/2 in favour of theirs. - Say "overflow" instead of "headroom" in the subject and the commit message (Maciej). - Use USHRT_MAX directly instead of a GVE_PAGECNT_BIAS macro, as the other drivers do, and move its rationale next to the refill in gve_dec_pagecnt_bias() (Maciej). No functional change. - Added Reviewed-by from Maciej Fijalkowski. - Say which trees need patch 1/2, for stable. v3: https://lore.kernel.org/netdev/20261103090651.35399-1-amaan.cheval@gmail.com/ - Refill when the bias reaches 0 again, as in v1. DQO-QPL is not supposed to support XDP at all, and it will be blocked explicitly in a separate patch, so the v2 refill-at-1 change is not needed. - Added Reviewed-by and Tested-by from Harshitha Ramamurthy. v2: https://lore.kernel.org/netdev/20261102112613.18334-1-amaan.cheval@gmail.com/ - Refill when the bias reaches 1 instead of 0 so the driver keeps a reference of its own across every handoff. At bias 0 a consumer that returns its reference synchronously, such as an AF_XDP socket in copy mode on an XDP_REDIRECT from DQO-QPL, freed a page still registered in the QPL. - Commit message: explain the refill point, drop the build notes. - Re-tested on 6.12.113 (c3-standard-8, DQO-RDA, which still uses the bias on 6.12): no EIO/EFAULT from splice/tee and no NIC reset after applying the patch. DQO-QPL is untested; I have no access to that hardware. v1: https://lore.kernel.org/netdev/20261031173449.2439047-1-amaan.cheval@gmail.com/ Built allmodconfig W=1, no new warnings. drivers/net/ethernet/google/gve/gve.h | 2 +- .../net/ethernet/google/gve/gve_buffer_mgmt_dqo.c | 4 ++-- drivers/net/ethernet/google/gve/gve_rx.c | 8 ++++---- drivers/net/ethernet/google/gve/gve_utils.c | 12 ++++-------- drivers/net/ethernet/google/gve/gve_utils.h | 2 +- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h index b7ce6e8632db..18d7edbf4b3b 100644 --- a/drivers/net/ethernet/google/gve/gve.h +++ b/drivers/net/ethernet/google/gve/gve.h @@ -119,7 +119,7 @@ struct gve_rx_slot_page_info { void *page_address; u32 page_offset; /* offset to write to in page */ unsigned int buf_size; - int pagecnt_bias; /* expected pagecnt if only the driver has a ref */ + u16 pagecnt_bias; /* expected pagecnt if only the driver has a ref */ u16 pad; /* adjustment for rx padding */ u8 can_flip; /* tracks if the networking stack is using the page */ }; diff --git a/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c b/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c index 6880d1531ba5..52223baf0303 100644 --- a/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c +++ b/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c @@ -149,8 +149,8 @@ int gve_alloc_qpl_page_dqo(struct gve_rx_ring *rx, buf_state->last_single_ref_offset = 0; /* The page already has 1 ref. */ - page_ref_add(buf_state->page_info.page, INT_MAX - 1); - buf_state->page_info.pagecnt_bias = INT_MAX; + page_ref_add(buf_state->page_info.page, USHRT_MAX - 1); + buf_state->page_info.pagecnt_bias = USHRT_MAX; return 0; } diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c index 81ea800e66e9..3bed19866376 100644 --- a/drivers/net/ethernet/google/gve/gve_rx.c +++ b/drivers/net/ethernet/google/gve/gve_rx.c @@ -152,8 +152,8 @@ static void gve_setup_rx_buffer(struct gve_rx_ring *rx, page_info->buf_size = rx->packet_buffer_size; *slot_addr = cpu_to_be64(addr); /* The page already has 1 ref */ - page_ref_add(page, INT_MAX - 1); - page_info->pagecnt_bias = INT_MAX; + page_ref_add(page, USHRT_MAX - 1); + page_info->pagecnt_bias = USHRT_MAX; } static int gve_rx_alloc_buffer(struct gve_priv *priv, struct device *dev, @@ -230,8 +230,8 @@ static int gve_rx_prefill_pages(struct gve_rx_ring *rx, rx->qpl_copy_pool[j].buf_size = rx->packet_buffer_size; /* The page already has 1 ref. */ - page_ref_add(page, INT_MAX - 1); - rx->qpl_copy_pool[j].pagecnt_bias = INT_MAX; + page_ref_add(page, USHRT_MAX - 1); + rx->qpl_copy_pool[j].pagecnt_bias = USHRT_MAX; } } diff --git a/drivers/net/ethernet/google/gve/gve_utils.c b/drivers/net/ethernet/google/gve/gve_utils.c index caed38cd5f2b..930555ac8fe9 100644 --- a/drivers/net/ethernet/google/gve/gve_utils.c +++ b/drivers/net/ethernet/google/gve/gve_utils.c @@ -93,15 +93,11 @@ void gve_dec_pagecnt_bias(struct gve_rx_slot_page_info *page_info) { page_info->pagecnt_bias--; if (page_info->pagecnt_bias == 0) { - int pagecount = page_count(page_info->page); - - /* If we have run out of bias - set it back up to INT_MAX - * minus the existing refs. + /* Out of bias: take another batch. USHRT_MAX keeps this rare + * while leaving page_count() far below INT_MAX. */ - page_info->pagecnt_bias = INT_MAX - pagecount; - - /* Set pagecount back up to max. */ - page_ref_add(page_info->page, INT_MAX - pagecount); + page_info->pagecnt_bias = USHRT_MAX; + page_ref_add(page_info->page, USHRT_MAX); } } diff --git a/drivers/net/ethernet/google/gve/gve_utils.h b/drivers/net/ethernet/google/gve/gve_utils.h index bf2e9a0adb36..c686142d37ea 100644 --- a/drivers/net/ethernet/google/gve/gve_utils.h +++ b/drivers/net/ethernet/google/gve/gve_utils.h @@ -25,7 +25,7 @@ struct sk_buff *gve_rx_copy_data(struct net_device *dev, struct napi_struct *nap struct sk_buff *gve_rx_copy(struct net_device *dev, struct napi_struct *napi, struct gve_rx_slot_page_info *page_info, u16 len); -/* Decrement pagecnt_bias. Set it back to INT_MAX if it reached zero. */ +/* Decrement pagecnt_bias. Top it up by USHRT_MAX if it reached zero. */ void gve_dec_pagecnt_bias(struct gve_rx_slot_page_info *page_info); void gve_add_napi(struct gve_priv *priv, int ntfy_idx, -- 2.47.3 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-11 10:06 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-11-09 10:04 [PATCH net v5 0/2] gve: fix RX page refcount overflow with the pagecnt bias Amaan Cheval 2026-11-09 10:04 ` [PATCH net v5 1/2] gve: refuse XDP on queue formats without XDP support Amaan Cheval 2026-11-09 19:45 ` Joshua Washington 2026-11-11 10:06 ` netdev-bot+sashiko 2026-11-09 10:04 ` [PATCH net v5 2/2] gve: fix RX page refcount overflow from INT_MAX pagecnt_bias Amaan Cheval
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®