Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gve: defer interrupt enabling until NAPI registration

Currently, interrupts are automatically enabled immediately upon
request. This allows interrupt to fire before the associated NAPI
context is fully initialized and cause failures like below:

[ 0.946369] Call Trace:
[ 0.946369] <IRQ>
[ 0.946369] __napi_poll+0x2a/0x1e0
[ 0.946369] net_rx_action+0x2f9/0x3f0
[ 0.946369] handle_softirqs+0xd6/0x2c0
[ 0.946369] ? handle_edge_irq+0xc1/0x1b0
[ 0.946369] __irq_exit_rcu+0xc3/0xe0
[ 0.946369] common_interrupt+0x81/0xa0
[ 0.946369] </IRQ>
[ 0.946369] <TASK>
[ 0.946369] asm_common_interrupt+0x22/0x40
[ 0.946369] RIP: 0010:pv_native_safe_halt+0xb/0x10

Use the `IRQF_NO_AUTOEN` flag when requesting interrupts to prevent auto
enablement and explicitly enable the interrupt in NAPI initialization
path (and disable it during NAPI teardown).

This ensures that interrupt lifecycle is strictly coupled with
readiness of NAPI context.

Cc: stable@vger.kernel.org
Fixes: 1dfc2e46117e ("gve: Refactor napi add and remove functions")
Signed-off-by: Ankit Garg <nktgrg@google.com>
Reviewed-by: Jordan Rhee <jordanrhee@google.com>
Reviewed-by: Joshua Washington <joshwash@google.com>
Signed-off-by: Harshitha Ramamurthy <hramamurthy@google.com>
Link: https://patch.msgid.link/20251219102945.2193617-1-hramamurthy@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Ankit Garg and committed by
Paolo Abeni
3d970eda a48e2322

+3 -1
+1 -1
drivers/net/ethernet/google/gve/gve_main.c
··· 558 558 block->priv = priv; 559 559 err = request_irq(priv->msix_vectors[msix_idx].vector, 560 560 gve_is_gqi(priv) ? gve_intr : gve_intr_dqo, 561 - 0, block->name, block); 561 + IRQF_NO_AUTOEN, block->name, block); 562 562 if (err) { 563 563 dev_err(&priv->pdev->dev, 564 564 "Failed to receive msix vector %d\n", i);
+2
drivers/net/ethernet/google/gve/gve_utils.c
··· 112 112 113 113 netif_napi_add_locked(priv->dev, &block->napi, gve_poll); 114 114 netif_napi_set_irq_locked(&block->napi, block->irq); 115 + enable_irq(block->irq); 115 116 } 116 117 117 118 void gve_remove_napi(struct gve_priv *priv, int ntfy_idx) 118 119 { 119 120 struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx]; 120 121 122 + disable_irq(block->irq); 121 123 netif_napi_del_locked(&block->napi); 122 124 }