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.
Unified · Split
| @@ -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 | ||
| 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 | |||
| 299 | struct tc_gred_qopt { | 325 | struct 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) */ |
| @@ -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 | ||
| 409 | static int gred_change(struct Qdisc *sch, struct nlattr *opt, | 410 | 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 | |||
| 517 | static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) | 518 | static 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 | ||
| 599 | nla_put_failure: | 650 | nla_put_failure: |