]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
idpf: Fix data race in idpf_net_dim
authorDavid Yang <mmyangfl@gmail.com>
Mon, 19 Jan 2026 16:27:16 +0000 (00:27 +0800)
committerJakub Kicinski <kuba@kernel.org>
Wed, 21 Jan 2026 02:29:37 +0000 (18:29 -0800)
In idpf_net_dim(), some statistics protected by u64_stats_sync, are read
and accumulated in ignorance of possible u64_stats_fetch_retry() events.
The correct way to copy statistics is already illustrated by
idpf_add_queue_stats(). Fix this by reading them into temporary variables
first.

Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
Fixes: 3a8845af66ed ("idpf: add RX splitq napi poll support")
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260119162720.1463859-1-mmyangfl@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/intel/idpf/idpf_txrx.c

index 7f3933ca9edcd1778ba2b0a63e18cb0eabda0307..f58f616d87fc4e6312ddff6d2874fb079606f027 100644 (file)
@@ -3941,7 +3941,7 @@ static void idpf_update_dim_sample(struct idpf_q_vector *q_vector,
 static void idpf_net_dim(struct idpf_q_vector *q_vector)
 {
        struct dim_sample dim_sample = { };
-       u64 packets, bytes;
+       u64 packets, bytes, pkts, bts;
        u32 i;
 
        if (!IDPF_ITR_IS_DYNAMIC(q_vector->tx_intr_mode))
@@ -3953,9 +3953,12 @@ static void idpf_net_dim(struct idpf_q_vector *q_vector)
 
                do {
                        start = u64_stats_fetch_begin(&txq->stats_sync);
-                       packets += u64_stats_read(&txq->q_stats.packets);
-                       bytes += u64_stats_read(&txq->q_stats.bytes);
+                       pkts = u64_stats_read(&txq->q_stats.packets);
+                       bts = u64_stats_read(&txq->q_stats.bytes);
                } while (u64_stats_fetch_retry(&txq->stats_sync, start));
+
+               packets += pkts;
+               bytes += bts;
        }
 
        idpf_update_dim_sample(q_vector, &dim_sample, &q_vector->tx_dim,
@@ -3972,9 +3975,12 @@ check_rx_itr:
 
                do {
                        start = u64_stats_fetch_begin(&rxq->stats_sync);
-                       packets += u64_stats_read(&rxq->q_stats.packets);
-                       bytes += u64_stats_read(&rxq->q_stats.bytes);
+                       pkts = u64_stats_read(&rxq->q_stats.packets);
+                       bts = u64_stats_read(&rxq->q_stats.bytes);
                } while (u64_stats_fetch_retry(&rxq->stats_sync, start));
+
+               packets += pkts;
+               bytes += bts;
        }
 
        idpf_update_dim_sample(q_vector, &dim_sample, &q_vector->rx_dim,