net/sched: sch_fq_pie: annotate data-races in fq_pie_dump_stats()

fq_codel_dump_stats() acquires the qdisc spinlock a bit too late.

Move this acquisition before we fill tc_fq_pie_xstats with live data.

Alternative would be to add READ_ONCE() and WRITE_ONCE() annotations,
but the spinlock is needed anyway to scan q->new_flows and q->old_flows.

Fixes: ec97ecf1eb ("net: sched: add Flow Queue PIE packet scheduler")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20260423063527.2568262-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Eric Dumazet
2026-04-23 06:35:27 +00:00
committed by Jakub Kicinski
parent d3aeb889dc
commit 59b145771c

View File

@@ -509,18 +509,19 @@ static int fq_pie_dump(struct Qdisc *sch, struct sk_buff *skb)
static int fq_pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
{
struct fq_pie_sched_data *q = qdisc_priv(sch);
struct tc_fq_pie_xstats st = {
.packets_in = q->stats.packets_in,
.overlimit = q->stats.overlimit,
.overmemory = q->overmemory,
.dropped = q->stats.dropped,
.ecn_mark = q->stats.ecn_mark,
.new_flow_count = q->new_flow_count,
.memory_usage = q->memory_usage,
};
struct tc_fq_pie_xstats st = { 0 };
struct list_head *pos;
sch_tree_lock(sch);
st.packets_in = q->stats.packets_in;
st.overlimit = q->stats.overlimit;
st.overmemory = q->overmemory;
st.dropped = q->stats.dropped;
st.ecn_mark = q->stats.ecn_mark;
st.new_flow_count = q->new_flow_count;
st.memory_usage = q->memory_usage;
list_for_each(pos, &q->new_flows)
st.new_flows_len++;