Netdev List
 help / color / mirror / Atom feed
* [PATCH net] net/sched: act_api: take tcfa_lock for hardware stats updates
@ 2026-10-09  5:16 Alexandre Cassen
  2026-10-09  5:20 ` netdev-bot+sinfo
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Alexandre Cassen @ 2026-10-09  5:16 UTC (permalink / raw)
  To: Jamal Hadi Salim, Jiri Pirko
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Vlad Buslov, Sebastian Andrzej Siewior,
	Clark Williams, Steven Rostedt, netdev

Actions without per CPU stats update their counters under tcfa_lock in
the software path but tcf_action_update_stats() adds hardware stats to
the same counters without it. An offloaded action that also runs in
software can then lose counter updates. On 32-bit the race can also
leave the u64_stats seqcount odd and make its readers spin forever.

Callers disable preemption around this update for the per CPU stats.
PREEMPT_RT forbids taking a spinlock_t with preemption disabled. Pin
the CPU in the per CPU path instead.

Tested for regressions on ConnectX-7 with firmware 28.48.1000.

Fixes: 5e174d5e73df ("net: sched: modify stats helper functions to support regular stats")
Signed-off-by: Alexandre Cassen <acassen@corp.free.fr>
---
 include/net/pkt_cls.h | 2 --
 net/sched/act_api.c   | 6 ++++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 5f5cb36439fe..9382405b2bab 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -316,10 +316,8 @@ tcf_exts_hw_stats_update(const struct tcf_exts *exts,
 				continue;
 		}
 
-		preempt_disable();
 		tcf_action_stats_update(a, stats->bytes, stats->pkts, stats->drops,
 					stats->lastused, true);
-		preempt_enable();
 
 		a->used_hw_stats = stats->used_hw_stats;
 		a->used_hw_stats_valid = stats->used_hw_stats_valid;
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 6e48b4bc2d75..f634c23d6a65 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -307,13 +307,11 @@ int tcf_action_update_hw_stats(struct tc_action *action)
 
 	err = tcf_action_offload_cmd(&fl_act, NULL, NULL, NULL);
 	if (!err) {
-		preempt_disable();
 		tcf_action_stats_update(action, fl_act.stats.bytes,
 					fl_act.stats.pkts,
 					fl_act.stats.drops,
 					fl_act.stats.lastused,
 					true);
-		preempt_enable();
 		action->used_hw_stats = fl_act.stats.used_hw_stats;
 		action->used_hw_stats_valid = true;
 	} else {
@@ -1597,6 +1595,7 @@ void tcf_action_update_stats(struct tc_action *a, u64 bytes, u64 packets,
 			     u64 drops, bool hw)
 {
 	if (a->cpu_bstats) {
+		preempt_disable();
 		_bstats_update(this_cpu_ptr(a->cpu_bstats), bytes, packets);
 
 		this_cpu_add(a->cpu_qstats->drops, drops);
@@ -1604,13 +1603,16 @@ void tcf_action_update_stats(struct tc_action *a, u64 bytes, u64 packets,
 		if (hw)
 			_bstats_update(this_cpu_ptr(a->cpu_bstats_hw),
 				       bytes, packets);
+		preempt_enable();
 		return;
 	}
 
+	spin_lock_bh(&a->tcfa_lock);
 	_bstats_update(&a->tcfa_bstats, bytes, packets);
 	atomic_add(drops, &a->tcfa_drops);
 	if (hw)
 		_bstats_update(&a->tcfa_bstats_hw, bytes, packets);
+	spin_unlock_bh(&a->tcfa_lock);
 }
 EXPORT_SYMBOL(tcf_action_update_stats);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-10  5:52 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-09  5:16 [PATCH net] net/sched: act_api: take tcfa_lock for hardware stats updates Alexandre Cassen
2026-10-09  5:20 ` netdev-bot+sinfo
2026-10-09  6:23 ` Eric Dumazet
2026-10-09  9:23 ` Jamal Hadi Salim
2026-10-10  5:52 ` netdev-bot+sashiko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox