mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
net/sched: sch_htb: annotate data-races (II)
htb_dump_class_stats() will soon run locklessly. (no RTNL, not qdisc spinlock). Remove cl->xstats and replace it with two fields: - xstats_lends - xstats_borrows Then use READ_ONCE()/WRITE_ONCE() annotations on them, and change htb_dump_class_stats to use a private struct tc_htb_xstats. Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260514095935.3926276-4-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
e54c33503b
commit
55562d4662
|
|
@ -114,7 +114,8 @@ struct htb_class {
|
|||
*/
|
||||
struct gnet_stats_basic_sync bstats;
|
||||
struct gnet_stats_basic_sync bstats_bias;
|
||||
struct tc_htb_xstats xstats; /* our special stats */
|
||||
u32 xstats_lends;
|
||||
u32 xstats_borrows;
|
||||
|
||||
/* token bucket parameters */
|
||||
s64 tokens, ctokens;/* current number of tokens */
|
||||
|
|
@ -707,10 +708,10 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
|
|||
diff = min_t(s64, q->now - cl->t_c, cl->mbuffer);
|
||||
if (cl->level >= level) {
|
||||
if (cl->level == level)
|
||||
cl->xstats.lends++;
|
||||
WRITE_ONCE(cl->xstats_lends, cl->xstats_lends + 1);
|
||||
htb_accnt_tokens(cl, bytes, diff);
|
||||
} else {
|
||||
cl->xstats.borrows++;
|
||||
WRITE_ONCE(cl->xstats_borrows, cl->xstats_borrows + 1);
|
||||
cl->tokens += diff; /* we moved t_c; update tokens */
|
||||
}
|
||||
htb_accnt_ctokens(cl, bytes, diff);
|
||||
|
|
@ -1319,6 +1320,10 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
|
|||
{
|
||||
struct htb_class *cl = (struct htb_class *)arg;
|
||||
struct htb_sched *q = qdisc_priv(sch);
|
||||
struct tc_htb_xstats xstats = {
|
||||
.lends = READ_ONCE(cl->xstats_lends),
|
||||
.borrows = READ_ONCE(cl->xstats_borrows),
|
||||
};
|
||||
struct gnet_stats_queue qs = {
|
||||
.drops = cl->drops,
|
||||
.overlimits = cl->overlimits,
|
||||
|
|
@ -1328,10 +1333,10 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
|
|||
if (!cl->level && cl->leaf.q)
|
||||
qdisc_qstats_qlen_backlog(cl->leaf.q, &qlen, &qs.backlog);
|
||||
|
||||
cl->xstats.tokens = clamp_t(s64, PSCHED_NS2TICKS(cl->tokens),
|
||||
INT_MIN, INT_MAX);
|
||||
cl->xstats.ctokens = clamp_t(s64, PSCHED_NS2TICKS(cl->ctokens),
|
||||
INT_MIN, INT_MAX);
|
||||
xstats.tokens = clamp_t(s64, PSCHED_NS2TICKS(cl->tokens),
|
||||
INT_MIN, INT_MAX);
|
||||
xstats.ctokens = clamp_t(s64, PSCHED_NS2TICKS(cl->ctokens),
|
||||
INT_MIN, INT_MAX);
|
||||
|
||||
if (q->offload) {
|
||||
if (!cl->level) {
|
||||
|
|
@ -1352,7 +1357,7 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
|
|||
gnet_stats_copy_queue(d, NULL, &qs, qlen) < 0)
|
||||
return -1;
|
||||
|
||||
return gnet_stats_copy_app(d, &cl->xstats, sizeof(cl->xstats));
|
||||
return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
|
||||
}
|
||||
|
||||
static struct netdev_queue *
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user