Skip to content

Commit f56940d

Browse files
a-darwishdavem330
authored andcommitted
net: sched: Use _bstats_update/set() instead of raw writes
The Qdisc::running sequence counter, used to protect Qdisc::bstats reads from parallel writes, is in the process of being removed. Qdisc::bstats read/writes will synchronize using an internal u64_stats sync point instead. Modify all bstats writes to use _bstats_update(). This ensures that the internal u64_stats sync point is always acquired and released as appropriate. 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>
1 parent 67c9e62 commit f56940d

File tree

5 files changed

+26
-21
lines changed

5 files changed

+26
-21
lines changed

net/core/gen_stats.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ EXPORT_SYMBOL(gnet_stats_basic_packed_init);
126126
static void gnet_stats_add_basic_cpu(struct gnet_stats_basic_packed *bstats,
127127
struct gnet_stats_basic_cpu __percpu *cpu)
128128
{
129+
u64 t_bytes = 0, t_packets = 0;
129130
int i;
130131

131132
for_each_possible_cpu(i) {
@@ -139,9 +140,10 @@ static void gnet_stats_add_basic_cpu(struct gnet_stats_basic_packed *bstats,
139140
packets = bcpu->bstats.packets;
140141
} while (u64_stats_fetch_retry_irq(&bcpu->syncp, start));
141142

142-
bstats->bytes += bytes;
143-
bstats->packets += packets;
143+
t_bytes += bytes;
144+
t_packets += packets;
144145
}
146+
_bstats_update(bstats, t_bytes, t_packets);
145147
}
146148

147149
void gnet_stats_add_basic(const seqcount_t *running,
@@ -164,8 +166,7 @@ void gnet_stats_add_basic(const seqcount_t *running,
164166
packets = b->packets;
165167
} while (running && read_seqcount_retry(running, seq));
166168

167-
bstats->bytes += bytes;
168-
bstats->packets += packets;
169+
_bstats_update(bstats, bytes, packets);
169170
}
170171
EXPORT_SYMBOL(gnet_stats_add_basic);
171172

net/sched/sch_cbq.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,8 +565,7 @@ cbq_update(struct cbq_sched_data *q)
565565
long avgidle = cl->avgidle;
566566
long idle;
567567

568-
cl->bstats.packets++;
569-
cl->bstats.bytes += len;
568+
_bstats_update(&cl->bstats, len, 1);
570569

571570
/*
572571
* (now - last) is total time between packet right edges.

net/sched/sch_gred.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ static int gred_offload_dump_stats(struct Qdisc *sch)
353353
{
354354
struct gred_sched *table = qdisc_priv(sch);
355355
struct tc_gred_qopt_offload *hw_stats;
356+
u64 bytes = 0, packets = 0;
356357
unsigned int i;
357358
int ret;
358359

@@ -381,15 +382,15 @@ static int gred_offload_dump_stats(struct Qdisc *sch)
381382
table->tab[i]->bytesin += hw_stats->stats.bstats[i].bytes;
382383
table->tab[i]->backlog += hw_stats->stats.qstats[i].backlog;
383384

384-
_bstats_update(&sch->bstats,
385-
hw_stats->stats.bstats[i].bytes,
386-
hw_stats->stats.bstats[i].packets);
385+
bytes += hw_stats->stats.bstats[i].bytes;
386+
packets += hw_stats->stats.bstats[i].packets;
387387
sch->qstats.qlen += hw_stats->stats.qstats[i].qlen;
388388
sch->qstats.backlog += hw_stats->stats.qstats[i].backlog;
389389
sch->qstats.drops += hw_stats->stats.qstats[i].drops;
390390
sch->qstats.requeues += hw_stats->stats.qstats[i].requeues;
391391
sch->qstats.overlimits += hw_stats->stats.qstats[i].overlimits;
392392
}
393+
_bstats_update(&sch->bstats, bytes, packets);
393394

394395
kfree(hw_stats);
395396
return ret;

net/sched/sch_htb.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,6 +1308,7 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
13081308
static void htb_offload_aggregate_stats(struct htb_sched *q,
13091309
struct htb_class *cl)
13101310
{
1311+
u64 bytes = 0, packets = 0;
13111312
struct htb_class *c;
13121313
unsigned int i;
13131314

@@ -1323,14 +1324,15 @@ static void htb_offload_aggregate_stats(struct htb_sched *q,
13231324
if (p != cl)
13241325
continue;
13251326

1326-
cl->bstats.bytes += c->bstats_bias.bytes;
1327-
cl->bstats.packets += c->bstats_bias.packets;
1327+
bytes += c->bstats_bias.bytes;
1328+
packets += c->bstats_bias.packets;
13281329
if (c->level == 0) {
1329-
cl->bstats.bytes += c->leaf.q->bstats.bytes;
1330-
cl->bstats.packets += c->leaf.q->bstats.packets;
1330+
bytes += c->leaf.q->bstats.bytes;
1331+
packets += c->leaf.q->bstats.packets;
13311332
}
13321333
}
13331334
}
1335+
_bstats_update(&cl->bstats, bytes, packets);
13341336
}
13351337

13361338
static int
@@ -1358,8 +1360,9 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
13581360
cl->bstats = cl->leaf.q->bstats;
13591361
else
13601362
gnet_stats_basic_packed_init(&cl->bstats);
1361-
cl->bstats.bytes += cl->bstats_bias.bytes;
1362-
cl->bstats.packets += cl->bstats_bias.packets;
1363+
_bstats_update(&cl->bstats,
1364+
cl->bstats_bias.bytes,
1365+
cl->bstats_bias.packets);
13631366
} else {
13641367
htb_offload_aggregate_stats(q, cl);
13651368
}
@@ -1578,8 +1581,9 @@ static int htb_destroy_class_offload(struct Qdisc *sch, struct htb_class *cl,
15781581
WARN_ON(old != q);
15791582

15801583
if (cl->parent) {
1581-
cl->parent->bstats_bias.bytes += q->bstats.bytes;
1582-
cl->parent->bstats_bias.packets += q->bstats.packets;
1584+
_bstats_update(&cl->parent->bstats_bias,
1585+
q->bstats.bytes,
1586+
q->bstats.packets);
15831587
}
15841588

15851589
offload_opt = (struct tc_htb_qopt_offload) {
@@ -1925,8 +1929,9 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
19251929
htb_graft_helper(dev_queue, old_q);
19261930
goto err_kill_estimator;
19271931
}
1928-
parent->bstats_bias.bytes += old_q->bstats.bytes;
1929-
parent->bstats_bias.packets += old_q->bstats.packets;
1932+
_bstats_update(&parent->bstats_bias,
1933+
old_q->bstats.bytes,
1934+
old_q->bstats.packets);
19301935
qdisc_put(old_q);
19311936
}
19321937
new_q = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,

net/sched/sch_qfq.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,8 +1235,7 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch,
12351235
return err;
12361236
}
12371237

1238-
cl->bstats.bytes += len;
1239-
cl->bstats.packets += gso_segs;
1238+
_bstats_update(&cl->bstats, len, gso_segs);
12401239
sch->qstats.backlog += len;
12411240
++sch->q.qlen;
12421241

0 commit comments

Comments
 (0)