History

net: sched: gred: provide a better structured dump and expose stats

Currently all GRED's virtual queue data is dumped in a single array in a single attribute. This makes it pretty much impossible to add new fields. In order to expose more detailed stats add a new set of attributes. We can now expose the 64 bit value of bytesin and all the mark stats which were not part of the original design.

Jakub Kicinski committed 7 years ago

Commit 80e22e91 parent 9f5cd0c2 files · +78 −1Browse files

Unified · Split

2 files
  1. include/uapi/linux/pkt_sched.h +26 −0
  2. net/sched/sch_gred.c +52 −1
include/uapi/linux/pkt_sched.h+26−0
@@ -291,11 +291,37 @@ enum { · 290 unmodified lines
291 TCA_GRED_DPS,291 TCA_GRED_DPS,
292 TCA_GRED_MAX_P,292 TCA_GRED_MAX_P,
293 TCA_GRED_LIMIT,293 TCA_GRED_LIMIT,
294 TCA_GRED_VQ_LIST, /* nested TCA_GRED_VQ_ENTRY */
294 __TCA_GRED_MAX,295 __TCA_GRED_MAX,
295};296};
296 297
297#define TCA_GRED_MAX (__TCA_GRED_MAX - 1)298#define TCA_GRED_MAX (__TCA_GRED_MAX - 1)
298 299
300enum {
301 TCA_GRED_VQ_ENTRY_UNSPEC,
302 TCA_GRED_VQ_ENTRY, /* nested TCA_GRED_VQ_* */
303 __TCA_GRED_VQ_ENTRY_MAX,
304};
305#define TCA_GRED_VQ_ENTRY_MAX (__TCA_GRED_VQ_ENTRY_MAX - 1)
306
307enum {
308 TCA_GRED_VQ_UNSPEC,
309 TCA_GRED_VQ_PAD,
310 TCA_GRED_VQ_DP, /* u32 */
311 TCA_GRED_VQ_STAT_BYTES, /* u64 */
312 TCA_GRED_VQ_STAT_PACKETS, /* u32 */
313 TCA_GRED_VQ_STAT_BACKLOG, /* u32 */
314 TCA_GRED_VQ_STAT_PROB_DROP, /* u32 */
315 TCA_GRED_VQ_STAT_PROB_MARK, /* u32 */
316 TCA_GRED_VQ_STAT_FORCED_DROP, /* u32 */
317 TCA_GRED_VQ_STAT_FORCED_MARK, /* u32 */
318 TCA_GRED_VQ_STAT_PDROP, /* u32 */
319 TCA_GRED_VQ_STAT_OTHER, /* u32 */
320 __TCA_GRED_VQ_MAX
321};
322
323#define TCA_GRED_VQ_MAX (__TCA_GRED_VQ_MAX - 1)
324
299struct tc_gred_qopt {325struct tc_gred_qopt {
300 __u32 limit; /* HARD maximal queue length (bytes) */326 __u32 limit; /* HARD maximal queue length (bytes) */
301 __u32 qth_min; /* Min average length threshold (bytes) */327 __u32 qth_min; /* Min average length threshold (bytes) */
net/sched/sch_gred.c+52−1
@@ -404,6 +404,7 @@ static const struct nla_policy gred_policy[TCA_GRED_MAX + 1] = { · 403 unmodified lines
404 [TCA_GRED_DPS] = { .len = sizeof(struct tc_gred_sopt) },404 [TCA_GRED_DPS] = { .len = sizeof(struct tc_gred_sopt) },
405 [TCA_GRED_MAX_P] = { .type = NLA_U32 },405 [TCA_GRED_MAX_P] = { .type = NLA_U32 },
406 [TCA_GRED_LIMIT] = { .type = NLA_U32 },406 [TCA_GRED_LIMIT] = { .type = NLA_U32 },
407 [TCA_GRED_VQ_LIST] = { .type = NLA_REJECT },
407};408};
408 409
409static int gred_change(struct Qdisc *sch, struct nlattr *opt,410static int gred_change(struct Qdisc *sch, struct nlattr *opt,
@@ -517,7 +518,7 @@ static int gred_init(struct Qdisc *sch, struct nlattr *opt, · 107 unmodified lines
517static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)518static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
518{519{
519 struct gred_sched *table = qdisc_priv(sch);520 struct gred_sched *table = qdisc_priv(sch);
520 struct nlattr *parms, *opts = NULL;521 struct nlattr *parms, *vqs, *opts = NULL;
521 int i;522 int i;
522 u32 max_p[MAX_DPs];523 u32 max_p[MAX_DPs];
523 struct tc_gred_sopt sopt = {524 struct tc_gred_sopt sopt = {
@@ -544,6 +545,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) · 20 unmodified lines
544 if (nla_put_u32(skb, TCA_GRED_LIMIT, sch->limit))545 if (nla_put_u32(skb, TCA_GRED_LIMIT, sch->limit))
545 goto nla_put_failure;546 goto nla_put_failure;
546 547
548 /* Old style all-in-one dump of VQs */
547 parms = nla_nest_start(skb, TCA_GRED_PARMS);549 parms = nla_nest_start(skb, TCA_GRED_PARMS);
548 if (parms == NULL)550 if (parms == NULL)
549 goto nla_put_failure;551 goto nla_put_failure;
@@ -594,6 +596,55 @@ append_opt: · 44 unmodified lines
594 596
595 nla_nest_end(skb, parms);597 nla_nest_end(skb, parms);
596 598
599 /* Dump the VQs again, in more structured way */
600 vqs = nla_nest_start(skb, TCA_GRED_VQ_LIST);
601 if (!vqs)
602 goto nla_put_failure;
603
604 for (i = 0; i < MAX_DPs; i++) {
605 struct gred_sched_data *q = table->tab[i];
606 struct nlattr *vq;
607
608 if (!q)
609 continue;
610
611 vq = nla_nest_start(skb, TCA_GRED_VQ_ENTRY);
612 if (!vq)
613 goto nla_put_failure;
614
615 if (nla_put_u32(skb, TCA_GRED_VQ_DP, q->DP))
616 goto nla_put_failure;
617
618 /* Stats */
619 if (nla_put_u64_64bit(skb, TCA_GRED_VQ_STAT_BYTES, q->bytesin,
620 TCA_GRED_VQ_PAD))
621 goto nla_put_failure;
622 if (nla_put_u32(skb, TCA_GRED_VQ_STAT_PACKETS, q->packetsin))
623 goto nla_put_failure;
624 if (nla_put_u32(skb, TCA_GRED_VQ_STAT_BACKLOG,
625 gred_backlog(table, q, sch)))
626 goto nla_put_failure;
627 if (nla_put_u32(skb, TCA_GRED_VQ_STAT_PROB_DROP,
628 q->stats.prob_drop))
629 goto nla_put_failure;
630 if (nla_put_u32(skb, TCA_GRED_VQ_STAT_PROB_MARK,
631 q->stats.prob_mark))
632 goto nla_put_failure;
633 if (nla_put_u32(skb, TCA_GRED_VQ_STAT_FORCED_DROP,
634 q->stats.forced_drop))
635 goto nla_put_failure;
636 if (nla_put_u32(skb, TCA_GRED_VQ_STAT_FORCED_MARK,
637 q->stats.forced_mark))
638 goto nla_put_failure;
639 if (nla_put_u32(skb, TCA_GRED_VQ_STAT_PDROP, q->stats.pdrop))
640 goto nla_put_failure;
641 if (nla_put_u32(skb, TCA_GRED_VQ_STAT_OTHER, q->stats.other))
642 goto nla_put_failure;
643
644 nla_nest_end(skb, vq);
645 }
646 nla_nest_end(skb, vqs);
647
597 return nla_nest_end(skb, opts);648 return nla_nest_end(skb, opts);
598 649
599nla_put_failure:650nla_put_failure: