diff options
author | Thomas Graf <tgraf@suug.ch> | 2005-11-05 15:14:11 -0500 |
---|---|---|
committer | Thomas Graf <tgr@axs.localdomain> | 2005-11-05 16:02:26 -0500 |
commit | 05f1cc01b4d24bc5432ae7044f8209d464f2b8ec (patch) | |
tree | 428f69d6e2b94712d6b566d7d3e65b8f1ad1df76 | |
parent | d6fd4e9667bf5e00b92e62f02d75bd6c97a7007a (diff) |
[PKT_SCHED]: GRED: Cleanup dumping
Avoids the allocation of a buffer by appending the VQs directly
to the skb and simplifies the code by using the appropriate
message construction macros.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
-rw-r--r-- | net/sched/sch_gred.c | 92 |
1 files changed, 34 insertions, 58 deletions
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index db594b46a52f..b3f5ad73fd82 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c | |||
@@ -559,50 +559,44 @@ static int gred_init(struct Qdisc *sch, struct rtattr *opt) | |||
559 | 559 | ||
560 | static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) | 560 | static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) |
561 | { | 561 | { |
562 | unsigned long qave; | ||
563 | struct rtattr *rta; | ||
564 | struct tc_gred_qopt *opt = NULL ; | ||
565 | struct tc_gred_qopt *dst; | ||
566 | struct gred_sched *table = qdisc_priv(sch); | 562 | struct gred_sched *table = qdisc_priv(sch); |
567 | struct gred_sched_data *q; | 563 | struct rtattr *parms, *opts = NULL; |
568 | int i; | 564 | int i; |
569 | unsigned char *b = skb->tail; | ||
570 | |||
571 | rta = (struct rtattr*)b; | ||
572 | RTA_PUT(skb, TCA_OPTIONS, 0, NULL); | ||
573 | 565 | ||
574 | opt=kmalloc(sizeof(struct tc_gred_qopt)*MAX_DPs, GFP_KERNEL); | 566 | opts = RTA_NEST(skb, TCA_OPTIONS); |
575 | 567 | parms = RTA_NEST(skb, TCA_GRED_PARMS); | |
576 | if (opt == NULL) { | ||
577 | DPRINTK("gred_dump:failed to malloc for %Zd\n", | ||
578 | sizeof(struct tc_gred_qopt)*MAX_DPs); | ||
579 | goto rtattr_failure; | ||
580 | } | ||
581 | 568 | ||
582 | memset(opt, 0, (sizeof(struct tc_gred_qopt))*table->DPs); | 569 | for (i = 0; i < MAX_DPs; i++) { |
583 | 570 | struct gred_sched_data *q = table->tab[i]; | |
584 | if (!table->initd) { | 571 | struct tc_gred_qopt opt; |
585 | DPRINTK("NO GRED Queues setup!\n"); | ||
586 | } | ||
587 | 572 | ||
588 | for (i=0;i<MAX_DPs;i++) { | 573 | memset(&opt, 0, sizeof(opt)); |
589 | dst= &opt[i]; | ||
590 | q= table->tab[i]; | ||
591 | 574 | ||
592 | if (!q) { | 575 | if (!q) { |
593 | /* hack -- fix at some point with proper message | 576 | /* hack -- fix at some point with proper message |
594 | This is how we indicate to tc that there is no VQ | 577 | This is how we indicate to tc that there is no VQ |
595 | at this DP */ | 578 | at this DP */ |
596 | 579 | ||
597 | dst->DP=MAX_DPs+i; | 580 | opt.DP = MAX_DPs + i; |
598 | continue; | 581 | goto append_opt; |
599 | } | 582 | } |
600 | 583 | ||
601 | dst->limit=q->limit; | 584 | opt.limit = q->limit; |
602 | dst->qth_min=q->qth_min>>q->Wlog; | 585 | opt.DP = q->DP; |
603 | dst->qth_max=q->qth_max>>q->Wlog; | 586 | opt.backlog = q->backlog; |
604 | dst->DP=q->DP; | 587 | opt.prio = q->prio; |
605 | dst->backlog=q->backlog; | 588 | opt.qth_min = q->qth_min >> q->Wlog; |
589 | opt.qth_max = q->qth_max >> q->Wlog; | ||
590 | opt.Wlog = q->Wlog; | ||
591 | opt.Plog = q->Plog; | ||
592 | opt.Scell_log = q->Scell_log; | ||
593 | opt.other = q->other; | ||
594 | opt.early = q->early; | ||
595 | opt.forced = q->forced; | ||
596 | opt.pdrop = q->pdrop; | ||
597 | opt.packets = q->packetsin; | ||
598 | opt.bytesin = q->bytesin; | ||
599 | |||
606 | if (q->qave) { | 600 | if (q->qave) { |
607 | if (gred_wred_mode(table)) { | 601 | if (gred_wred_mode(table)) { |
608 | q->qidlestart=table->tab[table->def]->qidlestart; | 602 | q->qidlestart=table->tab[table->def]->qidlestart; |
@@ -610,46 +604,28 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
610 | } | 604 | } |
611 | if (!PSCHED_IS_PASTPERFECT(q->qidlestart)) { | 605 | if (!PSCHED_IS_PASTPERFECT(q->qidlestart)) { |
612 | long idle; | 606 | long idle; |
607 | unsigned long qave; | ||
613 | psched_time_t now; | 608 | psched_time_t now; |
614 | PSCHED_GET_TIME(now); | 609 | PSCHED_GET_TIME(now); |
615 | idle = PSCHED_TDIFF_SAFE(now, q->qidlestart, q->Scell_max); | 610 | idle = PSCHED_TDIFF_SAFE(now, q->qidlestart, q->Scell_max); |
616 | qave = q->qave >> q->Stab[(idle>>q->Scell_log)&0xFF]; | 611 | qave = q->qave >> q->Stab[(idle>>q->Scell_log)&0xFF]; |
617 | dst->qave = qave >> q->Wlog; | 612 | opt.qave = qave >> q->Wlog; |
618 | 613 | ||
619 | } else { | 614 | } else { |
620 | dst->qave = q->qave >> q->Wlog; | 615 | opt.qave = q->qave >> q->Wlog; |
621 | } | 616 | } |
622 | } else { | ||
623 | dst->qave = 0; | ||
624 | } | 617 | } |
625 | 618 | ||
626 | 619 | append_opt: | |
627 | dst->Wlog = q->Wlog; | 620 | RTA_APPEND(skb, sizeof(opt), &opt); |
628 | dst->Plog = q->Plog; | ||
629 | dst->Scell_log = q->Scell_log; | ||
630 | dst->other = q->other; | ||
631 | dst->forced = q->forced; | ||
632 | dst->early = q->early; | ||
633 | dst->pdrop = q->pdrop; | ||
634 | dst->prio = q->prio; | ||
635 | dst->packets=q->packetsin; | ||
636 | dst->bytesin=q->bytesin; | ||
637 | } | 621 | } |
638 | 622 | ||
639 | RTA_PUT(skb, TCA_GRED_PARMS, sizeof(struct tc_gred_qopt)*MAX_DPs, opt); | 623 | RTA_NEST_END(skb, parms); |
640 | rta->rta_len = skb->tail - b; | ||
641 | 624 | ||
642 | kfree(opt); | 625 | return RTA_NEST_END(skb, opts); |
643 | return skb->len; | ||
644 | 626 | ||
645 | rtattr_failure: | 627 | rtattr_failure: |
646 | if (opt) | 628 | return RTA_NEST_CANCEL(skb, opts); |
647 | kfree(opt); | ||
648 | DPRINTK("gred_dump: FAILURE!!!!\n"); | ||
649 | |||
650 | /* also free the opt struct here */ | ||
651 | skb_trim(skb, b - skb->data); | ||
652 | return -1; | ||
653 | } | 629 | } |
654 | 630 | ||
655 | static void gred_destroy(struct Qdisc *sch) | 631 | static void gred_destroy(struct Qdisc *sch) |