Skip to content

Commit 8327158

Browse files
Maxim Mikityanskiykuba-moo
authored andcommitted
sch_htb: Stats for offloaded HTB
This commit adds support for statistics of offloaded HTB. Bytes and packets counters for leaf and inner nodes are supported, the values are taken from per-queue qdiscs, and the numbers that the user sees should have the same behavior as the software (non-offloaded) HTB. Signed-off-by: Maxim Mikityanskiy <maximmi@mellanox.com> Reviewed-by: Tariq Toukan <tariqt@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent d03b195 commit 8327158

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

net/sched/sch_htb.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ struct htb_class {
114114
* Written often fields
115115
*/
116116
struct gnet_stats_basic_packed bstats;
117+
struct gnet_stats_basic_packed bstats_bias;
117118
struct tc_htb_xstats xstats; /* our special stats */
118119

119120
/* token bucket parameters */
@@ -1220,6 +1221,7 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
12201221
struct sk_buff *skb, struct tcmsg *tcm)
12211222
{
12221223
struct htb_class *cl = (struct htb_class *)arg;
1224+
struct htb_sched *q = qdisc_priv(sch);
12231225
struct nlattr *nest;
12241226
struct tc_htb_opt opt;
12251227

@@ -1246,6 +1248,8 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
12461248
opt.level = cl->level;
12471249
if (nla_put(skb, TCA_HTB_PARMS, sizeof(opt), &opt))
12481250
goto nla_put_failure;
1251+
if (q->offload && nla_put_flag(skb, TCA_HTB_OFFLOAD))
1252+
goto nla_put_failure;
12491253
if ((cl->rate.rate_bytes_ps >= (1ULL << 32)) &&
12501254
nla_put_u64_64bit(skb, TCA_HTB_RATE64, cl->rate.rate_bytes_ps,
12511255
TCA_HTB_PAD))
@@ -1262,10 +1266,39 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
12621266
return -1;
12631267
}
12641268

1269+
static void htb_offload_aggregate_stats(struct htb_sched *q,
1270+
struct htb_class *cl)
1271+
{
1272+
struct htb_class *c;
1273+
unsigned int i;
1274+
1275+
memset(&cl->bstats, 0, sizeof(cl->bstats));
1276+
1277+
for (i = 0; i < q->clhash.hashsize; i++) {
1278+
hlist_for_each_entry(c, &q->clhash.hash[i], common.hnode) {
1279+
struct htb_class *p = c;
1280+
1281+
while (p && p->level < cl->level)
1282+
p = p->parent;
1283+
1284+
if (p != cl)
1285+
continue;
1286+
1287+
cl->bstats.bytes += c->bstats_bias.bytes;
1288+
cl->bstats.packets += c->bstats_bias.packets;
1289+
if (c->level == 0) {
1290+
cl->bstats.bytes += c->leaf.q->bstats.bytes;
1291+
cl->bstats.packets += c->leaf.q->bstats.packets;
1292+
}
1293+
}
1294+
}
1295+
}
1296+
12651297
static int
12661298
htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
12671299
{
12681300
struct htb_class *cl = (struct htb_class *)arg;
1301+
struct htb_sched *q = qdisc_priv(sch);
12691302
struct gnet_stats_queue qs = {
12701303
.drops = cl->drops,
12711304
.overlimits = cl->overlimits,
@@ -1280,6 +1313,19 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
12801313
cl->xstats.ctokens = clamp_t(s64, PSCHED_NS2TICKS(cl->ctokens),
12811314
INT_MIN, INT_MAX);
12821315

1316+
if (q->offload) {
1317+
if (!cl->level) {
1318+
if (cl->leaf.q)
1319+
cl->bstats = cl->leaf.q->bstats;
1320+
else
1321+
memset(&cl->bstats, 0, sizeof(cl->bstats));
1322+
cl->bstats.bytes += cl->bstats_bias.bytes;
1323+
cl->bstats.packets += cl->bstats_bias.packets;
1324+
} else {
1325+
htb_offload_aggregate_stats(q, cl);
1326+
}
1327+
}
1328+
12831329
if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
12841330
d, NULL, &cl->bstats) < 0 ||
12851331
gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
@@ -1464,6 +1510,11 @@ static int htb_destroy_class_offload(struct Qdisc *sch, struct htb_class *cl,
14641510
WARN_ON(old != q);
14651511
}
14661512

1513+
if (cl->parent) {
1514+
cl->parent->bstats_bias.bytes += q->bstats.bytes;
1515+
cl->parent->bstats_bias.packets += q->bstats.packets;
1516+
}
1517+
14671518
offload_opt = (struct tc_htb_qopt_offload) {
14681519
.command = !last_child ? TC_HTB_LEAF_DEL :
14691520
destroying ? TC_HTB_LEAF_DEL_LAST_FORCE :
@@ -1803,6 +1854,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
18031854
htb_graft_helper(dev_queue, old_q);
18041855
goto err_kill_estimator;
18051856
}
1857+
parent->bstats_bias.bytes += old_q->bstats.bytes;
1858+
parent->bstats_bias.packets += old_q->bstats.packets;
18061859
qdisc_put(old_q);
18071860
}
18081861
new_q = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,

0 commit comments

Comments
 (0)