]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
gve: skip error logging for retryable AdminQ commands
authorJordan Rhee <jordanrhee@google.com>
Thu, 14 May 2026 22:58:40 +0000 (22:58 +0000)
committerJakub Kicinski <kuba@kernel.org>
Wed, 20 May 2026 01:17:27 +0000 (18:17 -0700)
AdminQ commands may return -EAGAIN under certain transient conditions.
These commands are intended to be retried by the driver, so logging
a formal error to the system log is misleading and creates
unnecessary noise.

Modify the logging logic to skip the error message when the result
is -EAGAIN, and move logging to dev_err_ratelimited() to avoid
spamming the log.

Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Joshua Washington <joshwash@google.com>
Signed-off-by: Jordan Rhee <jordanrhee@google.com>
Signed-off-by: Harshitha Ramamurthy <hramamurthy@google.com>
Link: https://patch.msgid.link/20260514225842.110706-2-hramamurthy@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/google/gve/gve_adminq.c

index 08587bf40ed4a556c3d5bd0121bd2997bfecc13d..0d5a67523cbab029c23de6940e64353d0362598a 100644 (file)
@@ -416,16 +416,10 @@ static bool gve_adminq_wait_for_cmd(struct gve_priv *priv, u32 prod_cnt)
 
 static int gve_adminq_parse_err(struct gve_priv *priv, u32 status)
 {
-       if (status != GVE_ADMINQ_COMMAND_PASSED &&
-           status != GVE_ADMINQ_COMMAND_UNSET) {
-               dev_err(&priv->pdev->dev, "AQ command failed with status %d\n", status);
-               priv->adminq_cmd_fail++;
-       }
        switch (status) {
        case GVE_ADMINQ_COMMAND_PASSED:
                return 0;
        case GVE_ADMINQ_COMMAND_UNSET:
-               dev_err(&priv->pdev->dev, "parse_aq_err: err and status both unset, this should not be possible.\n");
                return -EINVAL;
        case GVE_ADMINQ_COMMAND_ERROR_ABORTED:
        case GVE_ADMINQ_COMMAND_ERROR_CANCELLED:
@@ -455,6 +449,27 @@ static int gve_adminq_parse_err(struct gve_priv *priv, u32 status)
        }
 }
 
+static bool gve_adminq_is_retryable(enum gve_adminq_opcodes opcode)
+{
+       switch (opcode) {
+       case GVE_ADMINQ_REPORT_NIC_TIMESTAMP:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static enum gve_adminq_opcodes gve_extract_opcode(union gve_adminq_command *cmd)
+{
+       u32 opcode;
+
+       opcode = be32_to_cpu(READ_ONCE(cmd->opcode));
+       if (opcode == GVE_ADMINQ_EXTENDED_COMMAND)
+               opcode = be32_to_cpu(cmd->extended_command.inner_opcode);
+
+       return opcode;
+}
+
 /* Flushes all AQ commands currently queued and waits for them to complete.
  * If there are failures, it will return the first error.
  */
@@ -477,14 +492,24 @@ static int gve_adminq_kick_and_wait(struct gve_priv *priv)
 
        for (i = tail; i < head; i++) {
                union gve_adminq_command *cmd;
-               u32 status, err;
+               u32 status;
+               int err;
 
                cmd = &priv->adminq[i & priv->adminq_mask];
                status = be32_to_cpu(READ_ONCE(cmd->status));
                err = gve_adminq_parse_err(priv, status);
-               if (err)
+               if (err) {
+                       enum gve_adminq_opcodes opcode = gve_extract_opcode(cmd);
+
+                       priv->adminq_cmd_fail++;
+                       if (!gve_adminq_is_retryable(opcode) || err != -EAGAIN)
+                               dev_err_ratelimited(&priv->pdev->dev,
+                                                   "AQ command %d failed with status %d\n",
+                                                   opcode, status);
+
                        // Return the first error if we failed.
                        return err;
+               }
        }
 
        return 0;