Skip to content

Commit 748a81c

Browse files
yangflkuba-moo
authored andcommitted
net: hns3: fix data race in hns3_fetch_stats
In hns3_fetch_stats(), ring statistics, protected by u64_stats_sync, are read and accumulated in ignorance of possible u64_stats_fetch_retry() events. These statistics are already accumulated by hns3_ring_stats_update(). Fix this by reading them into a temporary buffer first. Fixes: b20d7fe ("net: hns3: add some statitics info to tx process") Signed-off-by: David Yang <mmyangfl@gmail.com> Link: https://patch.msgid.link/20260119160759.1455950-1-mmyangfl@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent a917cd0 commit 748a81c

1 file changed

Lines changed: 36 additions & 33 deletions

File tree

drivers/net/ethernet/hisilicon/hns3/hns3_enet.c

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2529,44 +2529,47 @@ static netdev_features_t hns3_features_check(struct sk_buff *skb,
25292529
static void hns3_fetch_stats(struct rtnl_link_stats64 *stats,
25302530
struct hns3_enet_ring *ring, bool is_tx)
25312531
{
2532+
struct ring_stats ring_stats;
25322533
unsigned int start;
25332534

25342535
do {
25352536
start = u64_stats_fetch_begin(&ring->syncp);
2536-
if (is_tx) {
2537-
stats->tx_bytes += ring->stats.tx_bytes;
2538-
stats->tx_packets += ring->stats.tx_pkts;
2539-
stats->tx_dropped += ring->stats.sw_err_cnt;
2540-
stats->tx_dropped += ring->stats.tx_vlan_err;
2541-
stats->tx_dropped += ring->stats.tx_l4_proto_err;
2542-
stats->tx_dropped += ring->stats.tx_l2l3l4_err;
2543-
stats->tx_dropped += ring->stats.tx_tso_err;
2544-
stats->tx_dropped += ring->stats.over_max_recursion;
2545-
stats->tx_dropped += ring->stats.hw_limitation;
2546-
stats->tx_dropped += ring->stats.copy_bits_err;
2547-
stats->tx_dropped += ring->stats.skb2sgl_err;
2548-
stats->tx_dropped += ring->stats.map_sg_err;
2549-
stats->tx_errors += ring->stats.sw_err_cnt;
2550-
stats->tx_errors += ring->stats.tx_vlan_err;
2551-
stats->tx_errors += ring->stats.tx_l4_proto_err;
2552-
stats->tx_errors += ring->stats.tx_l2l3l4_err;
2553-
stats->tx_errors += ring->stats.tx_tso_err;
2554-
stats->tx_errors += ring->stats.over_max_recursion;
2555-
stats->tx_errors += ring->stats.hw_limitation;
2556-
stats->tx_errors += ring->stats.copy_bits_err;
2557-
stats->tx_errors += ring->stats.skb2sgl_err;
2558-
stats->tx_errors += ring->stats.map_sg_err;
2559-
} else {
2560-
stats->rx_bytes += ring->stats.rx_bytes;
2561-
stats->rx_packets += ring->stats.rx_pkts;
2562-
stats->rx_dropped += ring->stats.l2_err;
2563-
stats->rx_errors += ring->stats.l2_err;
2564-
stats->rx_errors += ring->stats.l3l4_csum_err;
2565-
stats->rx_crc_errors += ring->stats.l2_err;
2566-
stats->multicast += ring->stats.rx_multicast;
2567-
stats->rx_length_errors += ring->stats.err_pkt_len;
2568-
}
2537+
ring_stats = ring->stats;
25692538
} while (u64_stats_fetch_retry(&ring->syncp, start));
2539+
2540+
if (is_tx) {
2541+
stats->tx_bytes += ring_stats.tx_bytes;
2542+
stats->tx_packets += ring_stats.tx_pkts;
2543+
stats->tx_dropped += ring_stats.sw_err_cnt;
2544+
stats->tx_dropped += ring_stats.tx_vlan_err;
2545+
stats->tx_dropped += ring_stats.tx_l4_proto_err;
2546+
stats->tx_dropped += ring_stats.tx_l2l3l4_err;
2547+
stats->tx_dropped += ring_stats.tx_tso_err;
2548+
stats->tx_dropped += ring_stats.over_max_recursion;
2549+
stats->tx_dropped += ring_stats.hw_limitation;
2550+
stats->tx_dropped += ring_stats.copy_bits_err;
2551+
stats->tx_dropped += ring_stats.skb2sgl_err;
2552+
stats->tx_dropped += ring_stats.map_sg_err;
2553+
stats->tx_errors += ring_stats.sw_err_cnt;
2554+
stats->tx_errors += ring_stats.tx_vlan_err;
2555+
stats->tx_errors += ring_stats.tx_l4_proto_err;
2556+
stats->tx_errors += ring_stats.tx_l2l3l4_err;
2557+
stats->tx_errors += ring_stats.tx_tso_err;
2558+
stats->tx_errors += ring_stats.over_max_recursion;
2559+
stats->tx_errors += ring_stats.hw_limitation;
2560+
stats->tx_errors += ring_stats.copy_bits_err;
2561+
stats->tx_errors += ring_stats.skb2sgl_err;
2562+
stats->tx_errors += ring_stats.map_sg_err;
2563+
} else {
2564+
stats->rx_bytes += ring_stats.rx_bytes;
2565+
stats->rx_packets += ring_stats.rx_pkts;
2566+
stats->rx_dropped += ring_stats.l2_err;
2567+
stats->rx_errors += ring_stats.l2_err;
2568+
stats->rx_errors += ring_stats.l3l4_csum_err;
2569+
stats->rx_crc_errors += ring_stats.l2_err;
2570+
stats->multicast += ring_stats.rx_multicast;
2571+
stats->rx_length_errors += ring_stats.err_pkt_len;
2572+
}
25702573
}
25712574

25722575
static void hns3_nic_get_stats64(struct net_device *netdev,

0 commit comments

Comments
 (0)