From: Jordan Rhee Date: Thu, 14 May 2026 22:58:40 +0000 (+0000) Subject: gve: skip error logging for retryable AdminQ commands X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=55687124a86fb6a747ba099b1257f416faaeb143;p=thirdparty%2Fkernel%2Flinux.git gve: skip error logging for retryable AdminQ commands 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 Reviewed-by: Joshua Washington Signed-off-by: Jordan Rhee Signed-off-by: Harshitha Ramamurthy Link: https://patch.msgid.link/20260514225842.110706-2-hramamurthy@google.com Signed-off-by: Jakub Kicinski --- diff --git a/drivers/net/ethernet/google/gve/gve_adminq.c b/drivers/net/ethernet/google/gve/gve_adminq.c index 08587bf40ed4a..0d5a67523cbab 100644 --- a/drivers/net/ethernet/google/gve/gve_adminq.c +++ b/drivers/net/ethernet/google/gve/gve_adminq.c @@ -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;