Commit c7db85d5 authored by Max Yuan's avatar Max Yuan Committed by Jakub Kicinski
Browse files

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: 433e274b ("gve: Add stats for gve.")
Signed-off-by: default avatarMax Yuan <maxyuan@google.com>
Reviewed-by: default avatarJordan Rhee <jordanrhee@google.com>
Reviewed-by: default avatarJoshua Washington <joshwash@google.com>
Reviewed-by: default avatarMatt Olson <maolson@google.com>
Signed-off-by: default avatarHarshitha Ramamurthy <hramamurthy@google.com>
Reviewed-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20260202193925.3106272-3-hramamurthy@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 7b9ebcce
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -152,10 +152,11 @@ gve_get_ethtool_stats(struct net_device *netdev,
	u64 tmp_rx_pkts, tmp_rx_hsplit_pkt, tmp_rx_bytes, tmp_rx_hsplit_bytes,
		tmp_rx_skb_alloc_fail, tmp_rx_buf_alloc_fail,
		tmp_rx_desc_err_dropped_pkt, tmp_rx_hsplit_unsplit_pkt,
		tmp_tx_pkts, tmp_tx_bytes;
		tmp_tx_pkts, tmp_tx_bytes,
		tmp_xdp_tx_errors, tmp_xdp_redirect_errors;
	u64 rx_buf_alloc_fail, rx_desc_err_dropped_pkt, rx_hsplit_unsplit_pkt,
		rx_pkts, rx_hsplit_pkt, rx_skb_alloc_fail, rx_bytes, tx_pkts, tx_bytes,
		tx_dropped;
		tx_dropped, xdp_tx_errors, xdp_redirect_errors;
	int rx_base_stats_idx, max_rx_stats_idx, max_tx_stats_idx;
	int stats_idx, stats_region_len, nic_stats_len;
	struct stats *report_stats;
@@ -199,6 +200,7 @@ gve_get_ethtool_stats(struct net_device *netdev,
	for (rx_pkts = 0, rx_bytes = 0, rx_hsplit_pkt = 0,
	     rx_skb_alloc_fail = 0, rx_buf_alloc_fail = 0,
	     rx_desc_err_dropped_pkt = 0, rx_hsplit_unsplit_pkt = 0,
	     xdp_tx_errors = 0, xdp_redirect_errors = 0,
	     ring = 0;
	     ring < priv->rx_cfg.num_queues; ring++) {
		if (priv->rx) {
@@ -216,6 +218,9 @@ gve_get_ethtool_stats(struct net_device *netdev,
					rx->rx_desc_err_dropped_pkt;
				tmp_rx_hsplit_unsplit_pkt =
					rx->rx_hsplit_unsplit_pkt;
				tmp_xdp_tx_errors = rx->xdp_tx_errors;
				tmp_xdp_redirect_errors =
					rx->xdp_redirect_errors;
			} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
						       start));
			rx_pkts += tmp_rx_pkts;
@@ -225,6 +230,8 @@ gve_get_ethtool_stats(struct net_device *netdev,
			rx_buf_alloc_fail += tmp_rx_buf_alloc_fail;
			rx_desc_err_dropped_pkt += tmp_rx_desc_err_dropped_pkt;
			rx_hsplit_unsplit_pkt += tmp_rx_hsplit_unsplit_pkt;
			xdp_tx_errors += tmp_xdp_tx_errors;
			xdp_redirect_errors += tmp_xdp_redirect_errors;
		}
	}
	for (tx_pkts = 0, tx_bytes = 0, tx_dropped = 0, ring = 0;
@@ -250,8 +257,8 @@ gve_get_ethtool_stats(struct net_device *netdev,
	data[i++] = rx_bytes;
	data[i++] = tx_bytes;
	/* total rx dropped packets */
	data[i++] = rx_skb_alloc_fail + rx_buf_alloc_fail +
		    rx_desc_err_dropped_pkt;
	data[i++] = rx_skb_alloc_fail + rx_desc_err_dropped_pkt +
		    xdp_tx_errors + xdp_redirect_errors;
	data[i++] = tx_dropped;
	data[i++] = priv->tx_timeo_cnt;
	data[i++] = rx_skb_alloc_fail;
@@ -330,6 +337,9 @@ gve_get_ethtool_stats(struct net_device *netdev,
				tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail;
				tmp_rx_desc_err_dropped_pkt =
					rx->rx_desc_err_dropped_pkt;
				tmp_xdp_tx_errors = rx->xdp_tx_errors;
				tmp_xdp_redirect_errors =
					rx->xdp_redirect_errors;
			} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
						       start));
			data[i++] = tmp_rx_bytes;
@@ -340,8 +350,9 @@ gve_get_ethtool_stats(struct net_device *netdev,
			data[i++] = rx->rx_frag_alloc_cnt;
			/* rx dropped packets */
			data[i++] = tmp_rx_skb_alloc_fail +
				tmp_rx_buf_alloc_fail +
				tmp_rx_desc_err_dropped_pkt;
				    tmp_rx_desc_err_dropped_pkt +
				    tmp_xdp_tx_errors +
				    tmp_xdp_redirect_errors;
			data[i++] = rx->rx_copybreak_pkt;
			data[i++] = rx->rx_copied_pkt;
			/* stats from NIC */