Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gve: Correct ethtool rx_dropped calculation

The gve driver's "rx_dropped" statistic, exposed via `ethtool -S`,
incorrectly includes `rx_buf_alloc_fail` counts. These failures
represent an inability to allocate receive buffers, not true packet
drops where a received packet is discarded. This misrepresentation can
lead to inaccurate diagnostics.

This patch rectifies the ethtool "rx_dropped" calculation. It removes
`rx_buf_alloc_fail` from the total and adds `xdp_tx_errors` and
`xdp_redirect_errors`, which represent legitimate packet drops within
the XDP path.

Cc: stable@vger.kernel.org
Fixes: 433e274b8f7b ("gve: Add stats for gve.")
Signed-off-by: Max Yuan <maxyuan@google.com>
Reviewed-by: Jordan Rhee <jordanrhee@google.com>
Reviewed-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Matt Olson <maolson@google.com>
Signed-off-by: Harshitha Ramamurthy <hramamurthy@google.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20260202193925.3106272-3-hramamurthy@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Max Yuan and committed by
Jakub Kicinski
c7db85d5 7b9ebcce

+17 -6
+17 -6
drivers/net/ethernet/google/gve/gve_ethtool.c
··· 152 152 u64 tmp_rx_pkts, tmp_rx_hsplit_pkt, tmp_rx_bytes, tmp_rx_hsplit_bytes, 153 153 tmp_rx_skb_alloc_fail, tmp_rx_buf_alloc_fail, 154 154 tmp_rx_desc_err_dropped_pkt, tmp_rx_hsplit_unsplit_pkt, 155 - tmp_tx_pkts, tmp_tx_bytes; 155 + tmp_tx_pkts, tmp_tx_bytes, 156 + tmp_xdp_tx_errors, tmp_xdp_redirect_errors; 156 157 u64 rx_buf_alloc_fail, rx_desc_err_dropped_pkt, rx_hsplit_unsplit_pkt, 157 158 rx_pkts, rx_hsplit_pkt, rx_skb_alloc_fail, rx_bytes, tx_pkts, tx_bytes, 158 - tx_dropped; 159 + tx_dropped, xdp_tx_errors, xdp_redirect_errors; 159 160 int rx_base_stats_idx, max_rx_stats_idx, max_tx_stats_idx; 160 161 int stats_idx, stats_region_len, nic_stats_len; 161 162 struct stats *report_stats; ··· 200 199 for (rx_pkts = 0, rx_bytes = 0, rx_hsplit_pkt = 0, 201 200 rx_skb_alloc_fail = 0, rx_buf_alloc_fail = 0, 202 201 rx_desc_err_dropped_pkt = 0, rx_hsplit_unsplit_pkt = 0, 202 + xdp_tx_errors = 0, xdp_redirect_errors = 0, 203 203 ring = 0; 204 204 ring < priv->rx_cfg.num_queues; ring++) { 205 205 if (priv->rx) { ··· 218 216 rx->rx_desc_err_dropped_pkt; 219 217 tmp_rx_hsplit_unsplit_pkt = 220 218 rx->rx_hsplit_unsplit_pkt; 219 + tmp_xdp_tx_errors = rx->xdp_tx_errors; 220 + tmp_xdp_redirect_errors = 221 + rx->xdp_redirect_errors; 221 222 } while (u64_stats_fetch_retry(&priv->rx[ring].statss, 222 223 start)); 223 224 rx_pkts += tmp_rx_pkts; ··· 230 225 rx_buf_alloc_fail += tmp_rx_buf_alloc_fail; 231 226 rx_desc_err_dropped_pkt += tmp_rx_desc_err_dropped_pkt; 232 227 rx_hsplit_unsplit_pkt += tmp_rx_hsplit_unsplit_pkt; 228 + xdp_tx_errors += tmp_xdp_tx_errors; 229 + xdp_redirect_errors += tmp_xdp_redirect_errors; 233 230 } 234 231 } 235 232 for (tx_pkts = 0, tx_bytes = 0, tx_dropped = 0, ring = 0; ··· 257 250 data[i++] = rx_bytes; 258 251 data[i++] = tx_bytes; 259 252 /* total rx dropped packets */ 260 - data[i++] = rx_skb_alloc_fail + rx_buf_alloc_fail + 261 - rx_desc_err_dropped_pkt; 253 + data[i++] = rx_skb_alloc_fail + rx_desc_err_dropped_pkt + 254 + xdp_tx_errors + xdp_redirect_errors; 262 255 data[i++] = tx_dropped; 263 256 data[i++] = priv->tx_timeo_cnt; 264 257 data[i++] = rx_skb_alloc_fail; ··· 337 330 tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail; 338 331 tmp_rx_desc_err_dropped_pkt = 339 332 rx->rx_desc_err_dropped_pkt; 333 + tmp_xdp_tx_errors = rx->xdp_tx_errors; 334 + tmp_xdp_redirect_errors = 335 + rx->xdp_redirect_errors; 340 336 } while (u64_stats_fetch_retry(&priv->rx[ring].statss, 341 337 start)); 342 338 data[i++] = tmp_rx_bytes; ··· 350 340 data[i++] = rx->rx_frag_alloc_cnt; 351 341 /* rx dropped packets */ 352 342 data[i++] = tmp_rx_skb_alloc_fail + 353 - tmp_rx_buf_alloc_fail + 354 - tmp_rx_desc_err_dropped_pkt; 343 + tmp_rx_desc_err_dropped_pkt + 344 + tmp_xdp_tx_errors + 345 + tmp_xdp_redirect_errors; 355 346 data[i++] = rx->rx_copybreak_pkt; 356 347 data[i++] = rx->rx_copied_pkt; 357 348 /* stats from NIC */