Commit 20ab3416 authored by Petr Tesarik's avatar Petr Tesarik Committed by Ma Wupeng
Browse files

net: stmmac: fix ethtool per-queue statistics

stable inclusion
from stable-v6.6.14
commit ed00d917056b30b206743f1953fc7963cb906670
bugzilla: https://gitee.com/openeuler/kernel/issues/I99TJK

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=ed00d917056b30b206743f1953fc7963cb906670



--------------------------------

commit 61921bdaa132b580b6db6858e6d7dcdb870df5fe upstream.

Fix per-queue statistics for devices with more than one queue.

The output data pointer is currently reset in each loop iteration,
effectively summing all queue statistics in the first four u64 values.

The summary values are not even labeled correctly. For example, if eth0 has
2 queues, ethtool -S eth0 shows:

     q0_tx_pkt_n: 374 (actually tx_pkt_n over all queues)
     q0_tx_irq_n: 23  (actually tx_normal_irq_n over all queues)
     q1_tx_pkt_n: 462 (actually rx_pkt_n over all queues)
     q1_tx_irq_n: 446 (actually rx_normal_irq_n over all queues)
     q0_rx_pkt_n: 0
     q0_rx_irq_n: 0
     q1_rx_pkt_n: 0
     q1_rx_irq_n: 0

Fixes: 133466c3 ("net: stmmac: use per-queue 64 bit statistics where necessary")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarPetr Tesarik <petr@tesarici.cz>
Reviewed-by: default avatarJisheng Zhang <jszhang@kernel.org>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarZhangPeng <zhangpeng362@huawei.com>
parent ffcded06
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -543,15 +543,12 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)
	u32 rx_cnt = priv->plat->rx_queues_to_use;
	unsigned int start;
	int q, stat;
	u64 *pos;
	char *p;

	pos = data;
	for (q = 0; q < tx_cnt; q++) {
		struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q];
		struct stmmac_txq_stats snapshot;

		data = pos;
		do {
			start = u64_stats_fetch_begin(&txq_stats->syncp);
			snapshot = *txq_stats;
@@ -559,17 +556,15 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)

		p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n);
		for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
			*data++ += (*(u64 *)p);
			*data++ = (*(u64 *)p);
			p += sizeof(u64);
		}
	}

	pos = data;
	for (q = 0; q < rx_cnt; q++) {
		struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q];
		struct stmmac_rxq_stats snapshot;

		data = pos;
		do {
			start = u64_stats_fetch_begin(&rxq_stats->syncp);
			snapshot = *rxq_stats;
@@ -577,7 +572,7 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)

		p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n);
		for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
			*data++ += (*(u64 *)p);
			*data++ = (*(u64 *)p);
			p += sizeof(u64);
		}
	}