From: Michael Brown Date: Fri, 10 Oct 2025 12:07:05 +0000 (+0100) Subject: [gve] Rearm interrupts unconditionally on every poll X-Git-Tag: rolling/bin~136 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f44f624027c9e62cf2ed4486cd9e3429e6ebb52;p=thirdparty%2Fipxe.git [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 --- 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 */