]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[gve] Rearm interrupts unconditionally on every poll
authorMichael Brown <mcb30@ipxe.org>
Fri, 10 Oct 2025 12:07:05 +0000 (13:07 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 10 Oct 2025 12:12:19 +0000 (13:12 +0100)
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 <mcb30@ipxe.org>
src/drivers/net/gve.c

index c25f1d452f0369dbd042723eb2f9f6669d106d4d..77eb4b6746e4ba4d0fb59380ca16993f5ef37544 100644 (file)
@@ -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 */