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
291291 TCA_GRED_DPS,
292292 TCA_GRED_MAX_P,
293293 TCA_GRED_LIMIT,
294+ TCA_GRED_VQ_LIST, /* nested TCA_GRED_VQ_ENTRY */
294295 __TCA_GRED_MAX,
295296 };
296297
297298 #define TCA_GRED_MAX (__TCA_GRED_MAX - 1)
298299
300+enum {
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+
307+enum {
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+
299325 struct tc_gred_qopt {
300326 __u32 limit; /* HARD maximal queue length (bytes) */
301327 __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
404404 [TCA_GRED_DPS] = { .len = sizeof(struct tc_gred_sopt) },
405405 [TCA_GRED_MAX_P] = { .type = NLA_U32 },
406406 [TCA_GRED_LIMIT] = { .type = NLA_U32 },
407+ [TCA_GRED_VQ_LIST] = { .type = NLA_REJECT },
407408 };
408409
409410 static 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
517518 static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
518519 {
519520 struct gred_sched *table = qdisc_priv(sch);
520− struct nlattr *parms, *opts = NULL;
521+ struct nlattr *parms, *vqs, *opts = NULL;
521522 int i;
522523 u32 max_p[MAX_DPs];
523524 struct tc_gred_sopt sopt = {
@@ -544,6 +545,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) · 20 unmodified lines
544545 if (nla_put_u32(skb, TCA_GRED_LIMIT, sch->limit))
545546 goto nla_put_failure;
546547
548+ /* Old style all-in-one dump of VQs */
547549 parms = nla_nest_start(skb, TCA_GRED_PARMS);
548550 if (parms == NULL)
549551 goto nla_put_failure;
@@ -594,6 +596,55 @@ append_opt: · 44 unmodified lines
594596
595597 nla_nest_end(skb, parms);
596598
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+
597648 return nla_nest_end(skb, opts);
598649
599650 nla_put_failure: