From 4f44f624027c9e62cf2ed4486cd9e3429e6ebb52 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 10 Oct 2025 13:07:05 +0100 Subject: [PATCH] [gve] Rearm interrupts unconditionally on every poll Experimentation suggests that rearming the interrupt once per observed completion is not sufficient: we still see occasional delays during which the hardware fails to write out completions. As described in commit d2e1e59 ("[gve] Use dummy interrupt to trigger completion writeback in DQO mode"), there is no documentation around the precise semantics of the interrupt rearming mechanism, and so experimentation is the only available guide. Switch to rearming both TX and RX interrupts unconditionally on every poll, since this produces better experimental results. Signed-off-by: Michael Brown --- src/drivers/net/gve.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/drivers/net/gve.c b/src/drivers/net/gve.c index c25f1d452..77eb4b674 100644 --- a/src/drivers/net/gve.c +++ b/src/drivers/net/gve.c @@ -1508,9 +1508,6 @@ static void gve_poll_tx ( struct net_device *netdev ) { rmb(); tx->done++; - /* Re-arm interrupt */ - writel ( GVE_DQO_IRQ_REARM, gve->irqs.db[GVE_TX_IRQ] ); - /* Ignore non-packet completions */ if ( ( ! ( dqo->flags & GVE_DQO_TXF_PKT ) ) || ( dqo->tag.count < 0 ) ) { @@ -1601,9 +1598,6 @@ static void gve_poll_rx ( struct net_device *netdev ) { break; rmb(); - /* Re-arm interrupt */ - writel ( GVE_DQO_IRQ_REARM, gve->irqs.db[GVE_RX_IRQ] ); - /* Parse completion */ len = ( le16_to_cpu ( dqo->len ) & ( GVE_BUF_SIZE - 1 ) ); @@ -1762,6 +1756,7 @@ static void gve_refill_rx ( struct net_device *netdev ) { * @v netdev Network device */ static void gve_poll ( struct net_device *netdev ) { + struct gve_nic *gve = netdev->priv; /* Do nothing if queues are not yet set up */ if ( ! netdev_link_ok ( netdev ) ) @@ -1775,6 +1770,12 @@ static void gve_poll ( struct net_device *netdev ) { /* Refill receive queue */ gve_refill_rx ( netdev ); + + /* Rearm queue interrupts if applicable */ + if ( gve->mode & GVE_MODE_DQO ) { + writel ( GVE_DQO_IRQ_REARM, gve->irqs.db[GVE_TX_IRQ] ); + writel ( GVE_DQO_IRQ_REARM, gve->irqs.db[GVE_RX_IRQ] ); + } } /** GVE network device operations */