Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 07 Aug 2026 13:10:44 +0000
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Cc:        Sujithra Periasamy <sujithra@google.com>
Subject:   git: 36d57489ca07 - main - gve: Implement AQ batching for queue creation and destruction
Message-ID:  <6a75d954.3e55a.58c1ac30@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=36d57489ca07642dec31390e90c25b2a0ca9313e

commit 36d57489ca07642dec31390e90c25b2a0ca9313e
Author:     Sujithra Periasamy <sujithra@google.com>
AuthorDate: 2026-08-07 13:07:20 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-08-07 13:10:24 +0000

    gve: Implement AQ batching for queue creation and destruction
    
    Currently, the FreeBSD driver configures and destroys queues
    sequentially by issuing individual Admin Queue (AQ) commands.
    
    During queue teardown (e.g., interface reset), disabling queues
    one by one leaves the device in a partially configured state.
    Because the device does not yet know that the driver is in the
    process of fully unconfiguring all queues, this intermediate
    state can trigger transient error logs (such as when queue 0 is
    disabled while other queues are still active).
    
    Modify the driver to use Admin Queue batching for both the
    creation and destruction of TX and RX queues. Commands are now
    queued and kicked together, ensuring the queue configuration changes
    are applied atomically and preventing transient errors from being logged.
    
    Signed-off-by: Sujithra Periasamy <sujithra@google.com>
    
    Reviewed by:    markj
    MFC after:      1 week
    Sponsored by:   Google
    Differential Revision:  https://reviews.freebsd.org/D58696
---
 sys/dev/gve/gve_adminq.c | 47 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/sys/dev/gve/gve_adminq.c b/sys/dev/gve/gve_adminq.c
index 9b59570a2af4..43952308098b 100644
--- a/sys/dev/gve/gve_adminq.c
+++ b/sys/dev/gve/gve_adminq.c
@@ -214,6 +214,9 @@ gve_process_device_options(struct gve_priv *priv,
 	return (0);
 }
 
+static int gve_adminq_issue_cmd(struct gve_priv *priv,
+    struct gve_adminq_command *cmd);
+static int gve_adminq_kick_and_wait(struct gve_priv *priv);
 static int gve_adminq_execute_cmd(struct gve_priv *priv,
     struct gve_adminq_command *cmd);
 
@@ -225,7 +228,7 @@ gve_adminq_destroy_tx_queue(struct gve_priv *priv, uint32_t id)
 	cmd.opcode = htobe32(GVE_ADMINQ_DESTROY_TX_QUEUE);
 	cmd.destroy_tx_queue.queue_id = htobe32(id);
 
-	return (gve_adminq_execute_cmd(priv, &cmd));
+	return (gve_adminq_issue_cmd(priv, &cmd));
 }
 
 static int
@@ -236,7 +239,7 @@ gve_adminq_destroy_rx_queue(struct gve_priv *priv, uint32_t id)
 	cmd.opcode = htobe32(GVE_ADMINQ_DESTROY_RX_QUEUE);
 	cmd.destroy_rx_queue.queue_id = htobe32(id);
 
-	return (gve_adminq_execute_cmd(priv, &cmd));
+	return (gve_adminq_issue_cmd(priv, &cmd));
 }
 
 int
@@ -248,13 +251,18 @@ gve_adminq_destroy_rx_queues(struct gve_priv *priv, uint32_t num_queues)
 	for (i = 0; i < num_queues; i++) {
 		err = gve_adminq_destroy_rx_queue(priv, i);
 		if (err != 0) {
-			device_printf(priv->dev, "Failed to destroy rxq %d, err: %d\n",
+			device_printf(priv->dev, "Failed to issue destroy rxq %d, err: %d\n",
 			    i, err);
+			return (err);
 		}
 	}
 
-	if (err != 0)
+	err = gve_adminq_kick_and_wait(priv);
+	if (err != 0) {
+		device_printf(priv->dev, "Failed to batch destroy rx queues, err: %d\n",
+		    err);
 		return (err);
+	}
 
 	device_printf(priv->dev, "Destroyed %d rx queues\n", num_queues);
 	return (0);
@@ -269,13 +277,18 @@ gve_adminq_destroy_tx_queues(struct gve_priv *priv, uint32_t num_queues)
 	for (i = 0; i < num_queues; i++) {
 		err = gve_adminq_destroy_tx_queue(priv, i);
 		if (err != 0) {
-			device_printf(priv->dev, "Failed to destroy txq %d, err: %d\n",
+			device_printf(priv->dev, "Failed to issue destroy txq %d, err: %d\n",
 			    i, err);
+			return (err);
 		}
 	}
 
-	if (err != 0)
+	err = gve_adminq_kick_and_wait(priv);
+	if (err != 0) {
+		device_printf(priv->dev, "Failed to batch destroy tx queues, err: %d\n",
+		    err);
 		return (err);
+	}
 
 	device_printf(priv->dev, "Destroyed %d tx queues\n", num_queues);
 	return (0);
@@ -325,7 +338,7 @@ gve_adminq_create_rx_queue(struct gve_priv *priv, uint32_t queue_index)
 		    htobe16(priv->rx_buf_size_dqo);
 	}
 
-	return (gve_adminq_execute_cmd(priv, &cmd));
+	return (gve_adminq_issue_cmd(priv, &cmd));
 }
 
 int
@@ -337,12 +350,19 @@ gve_adminq_create_rx_queues(struct gve_priv *priv, uint32_t num_queues)
 	for (i = 0; i < num_queues; i++) {
 		err = gve_adminq_create_rx_queue(priv, i);
 		if (err != 0) {
-			device_printf(priv->dev, "Failed to create rxq %d, err: %d\n",
+			device_printf(priv->dev, "Failed to issue create rxq %d, err: %d\n",
 			    i, err);
 			goto abort;
 		}
 	}
 
+	err = gve_adminq_kick_and_wait(priv);
+	if (err != 0) {
+		device_printf(priv->dev, "Failed to batch create rx queues, err: %d\n",
+		    err);
+		goto abort;
+	}
+
 	if (bootverbose)
 		device_printf(priv->dev, "Created %d rx queues\n", num_queues);
 	return (0);
@@ -381,7 +401,7 @@ gve_adminq_create_tx_queue(struct gve_priv *priv, uint32_t queue_index)
 		cmd.create_tx_queue.tx_comp_ring_size =
 		    htobe16(priv->tx_desc_cnt);
 	}
-	return (gve_adminq_execute_cmd(priv, &cmd));
+	return (gve_adminq_issue_cmd(priv, &cmd));
 }
 
 int
@@ -393,12 +413,19 @@ gve_adminq_create_tx_queues(struct gve_priv *priv, uint32_t num_queues)
 	for (i = 0; i < num_queues; i++) {
 		err = gve_adminq_create_tx_queue(priv, i);
 		if (err != 0) {
-			device_printf(priv->dev, "Failed to create txq %d, err: %d\n",
+			device_printf(priv->dev, "Failed to issue create txq %d, err: %d\n",
 			    i, err);
 			goto abort;
 		}
 	}
 
+	err = gve_adminq_kick_and_wait(priv);
+	if (err != 0) {
+		device_printf(priv->dev, "Failed to batch create tx queues, err: %d\n",
+		    err);
+		goto abort;
+	}
+
 	if (bootverbose)
 		device_printf(priv->dev, "Created %d tx queues\n", num_queues);
 	return (0);


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a75d954.3e55a.58c1ac30>