mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
net: sched: Remove Qdisc::running sequence counter
The Qdisc::running sequence counter has two uses: 1. Reliably reading qdisc's tc statistics while the qdisc is running (a seqcount read/retry loop at gnet_stats_add_basic()). 2. As a flag, indicating whether the qdisc in question is running (without any retry loops). For the first usage, the Qdisc::running sequence counter write section, qdisc_run_begin() => qdisc_run_end(), covers a much wider area than what is actually needed: the raw qdisc's bstats update. A u64_stats sync point was thus introduced (in previous commits) inside the bstats structure itself. A local u64_stats write section is then started and stopped for the bstats updates. Use that u64_stats sync point mechanism for the bstats read/retry loop at gnet_stats_add_basic(). For the second qdisc->running usage, a __QDISC_STATE_RUNNING bit flag, accessed with atomic bitops, is sufficient. Using a bit flag instead of a sequence counter at qdisc_run_begin/end() and qdisc_is_running() leads to the SMP barriers implicitly added through raw_read_seqcount() and write_seqcount_begin/end() getting removed. All call sites have been surveyed though, and no required ordering was identified. Now that the qdisc->running sequence counter is no longer used, remove it. Note, using u64_stats implies no sequence counter protection for 64-bit architectures. This can lead to the qdisc tc statistics "packets" vs. "bytes" values getting out of sync on rare occasions. The individual values will still be valid. Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
50dc9a8572
commit
29cbcd8582
21 changed files with 102 additions and 134 deletions
|
@ -943,8 +943,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
|
|||
cpu_qstats = q->cpu_qstats;
|
||||
}
|
||||
|
||||
if (gnet_stats_copy_basic(qdisc_root_sleeping_running(q),
|
||||
&d, cpu_bstats, &q->bstats) < 0 ||
|
||||
if (gnet_stats_copy_basic(&d, cpu_bstats, &q->bstats, true) < 0 ||
|
||||
gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 ||
|
||||
gnet_stats_copy_queue(&d, cpu_qstats, &q->qstats, qlen) < 0)
|
||||
goto nla_put_failure;
|
||||
|
@ -1265,26 +1264,17 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
|
|||
rcu_assign_pointer(sch->stab, stab);
|
||||
}
|
||||
if (tca[TCA_RATE]) {
|
||||
seqcount_t *running;
|
||||
|
||||
err = -EOPNOTSUPP;
|
||||
if (sch->flags & TCQ_F_MQROOT) {
|
||||
NL_SET_ERR_MSG(extack, "Cannot attach rate estimator to a multi-queue root qdisc");
|
||||
goto err_out4;
|
||||
}
|
||||
|
||||
if (sch->parent != TC_H_ROOT &&
|
||||
!(sch->flags & TCQ_F_INGRESS) &&
|
||||
(!p || !(p->flags & TCQ_F_MQROOT)))
|
||||
running = qdisc_root_sleeping_running(sch);
|
||||
else
|
||||
running = &sch->running;
|
||||
|
||||
err = gen_new_estimator(&sch->bstats,
|
||||
sch->cpu_bstats,
|
||||
&sch->rate_est,
|
||||
NULL,
|
||||
running,
|
||||
true,
|
||||
tca[TCA_RATE]);
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG(extack, "Failed to generate new estimator");
|
||||
|
@ -1360,7 +1350,7 @@ static int qdisc_change(struct Qdisc *sch, struct nlattr **tca,
|
|||
sch->cpu_bstats,
|
||||
&sch->rate_est,
|
||||
NULL,
|
||||
qdisc_root_sleeping_running(sch),
|
||||
true,
|
||||
tca[TCA_RATE]);
|
||||
}
|
||||
out:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue