aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_htb.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_htb.c')
-rw-r--r--net/sched/sch_htb.c171
1 files changed, 70 insertions, 101 deletions
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index d14f02056ae6..5070643ce534 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -84,12 +84,12 @@ struct htb_class {
84 unsigned int children; 84 unsigned int children;
85 struct htb_class *parent; /* parent class */ 85 struct htb_class *parent; /* parent class */
86 86
87 int prio; /* these two are used only by leaves... */
88 int quantum; /* but stored for parent-to-leaf return */
89
87 union { 90 union {
88 struct htb_class_leaf { 91 struct htb_class_leaf {
89 struct Qdisc *q; 92 struct Qdisc *q;
90 int prio;
91 int aprio;
92 int quantum;
93 int deficit[TC_HTB_MAXDEPTH]; 93 int deficit[TC_HTB_MAXDEPTH];
94 struct list_head drop_list; 94 struct list_head drop_list;
95 } leaf; 95 } leaf;
@@ -123,19 +123,8 @@ struct htb_class {
123 psched_tdiff_t mbuffer; /* max wait time */ 123 psched_tdiff_t mbuffer; /* max wait time */
124 long tokens, ctokens; /* current number of tokens */ 124 long tokens, ctokens; /* current number of tokens */
125 psched_time_t t_c; /* checkpoint time */ 125 psched_time_t t_c; /* checkpoint time */
126
127 int prio; /* For parent to leaf return possible here */
128 int quantum; /* we do backup. Finally full replacement */
129 /* of un.leaf originals should be done. */
130}; 126};
131 127
132static inline long L2T(struct htb_class *cl, struct qdisc_rate_table *rate,
133 int size)
134{
135 long result = qdisc_l2t(rate, size);
136 return result;
137}
138
139struct htb_sched { 128struct htb_sched {
140 struct Qdisc_class_hash clhash; 129 struct Qdisc_class_hash clhash;
141 struct list_head drops[TC_HTB_NUMPRIO];/* active leaves (for drops) */ 130 struct list_head drops[TC_HTB_NUMPRIO];/* active leaves (for drops) */
@@ -152,9 +141,6 @@ struct htb_sched {
152 /* time of nearest event per level (row) */ 141 /* time of nearest event per level (row) */
153 psched_time_t near_ev_cache[TC_HTB_MAXDEPTH]; 142 psched_time_t near_ev_cache[TC_HTB_MAXDEPTH];
154 143
155 /* whether we hit non-work conserving class during this dequeue; we use */
156 int nwc_hit; /* this to disable mindelay complaint in dequeue */
157
158 int defcls; /* class where unclassified flows go to */ 144 int defcls; /* class where unclassified flows go to */
159 145
160 /* filters for qdisc itself */ 146 /* filters for qdisc itself */
@@ -527,10 +513,10 @@ static inline void htb_activate(struct htb_sched *q, struct htb_class *cl)
527 WARN_ON(cl->level || !cl->un.leaf.q || !cl->un.leaf.q->q.qlen); 513 WARN_ON(cl->level || !cl->un.leaf.q || !cl->un.leaf.q->q.qlen);
528 514
529 if (!cl->prio_activity) { 515 if (!cl->prio_activity) {
530 cl->prio_activity = 1 << (cl->un.leaf.aprio = cl->un.leaf.prio); 516 cl->prio_activity = 1 << cl->prio;
531 htb_activate_prios(q, cl); 517 htb_activate_prios(q, cl);
532 list_add_tail(&cl->un.leaf.drop_list, 518 list_add_tail(&cl->un.leaf.drop_list,
533 q->drops + cl->un.leaf.aprio); 519 q->drops + cl->prio);
534 } 520 }
535} 521}
536 522
@@ -551,7 +537,7 @@ static inline void htb_deactivate(struct htb_sched *q, struct htb_class *cl)
551 537
552static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) 538static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
553{ 539{
554 int ret; 540 int uninitialized_var(ret);
555 struct htb_sched *q = qdisc_priv(sch); 541 struct htb_sched *q = qdisc_priv(sch);
556 struct htb_class *cl = htb_classify(skb, sch, &ret); 542 struct htb_class *cl = htb_classify(skb, sch, &ret);
557 543
@@ -591,45 +577,30 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
591 return NET_XMIT_SUCCESS; 577 return NET_XMIT_SUCCESS;
592} 578}
593 579
594/* TODO: requeuing packet charges it to policers again !! */ 580static inline void htb_accnt_tokens(struct htb_class *cl, int bytes, long diff)
595static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
596{ 581{
597 int ret; 582 long toks = diff + cl->tokens;
598 struct htb_sched *q = qdisc_priv(sch);
599 struct htb_class *cl = htb_classify(skb, sch, &ret);
600 struct sk_buff *tskb;
601 583
602 if (cl == HTB_DIRECT) { 584 if (toks > cl->buffer)
603 /* enqueue to helper queue */ 585 toks = cl->buffer;
604 if (q->direct_queue.qlen < q->direct_qlen) { 586 toks -= (long) qdisc_l2t(cl->rate, bytes);
605 __skb_queue_head(&q->direct_queue, skb); 587 if (toks <= -cl->mbuffer)
606 } else { 588 toks = 1 - cl->mbuffer;
607 __skb_queue_head(&q->direct_queue, skb);
608 tskb = __skb_dequeue_tail(&q->direct_queue);
609 kfree_skb(tskb);
610 sch->qstats.drops++;
611 return NET_XMIT_CN;
612 }
613#ifdef CONFIG_NET_CLS_ACT
614 } else if (!cl) {
615 if (ret & __NET_XMIT_BYPASS)
616 sch->qstats.drops++;
617 kfree_skb(skb);
618 return ret;
619#endif
620 } else if ((ret = cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q)) !=
621 NET_XMIT_SUCCESS) {
622 if (net_xmit_drop_count(ret)) {
623 sch->qstats.drops++;
624 cl->qstats.drops++;
625 }
626 return ret;
627 } else
628 htb_activate(q, cl);
629 589
630 sch->q.qlen++; 590 cl->tokens = toks;
631 sch->qstats.requeues++; 591}
632 return NET_XMIT_SUCCESS; 592
593static inline void htb_accnt_ctokens(struct htb_class *cl, int bytes, long diff)
594{
595 long toks = diff + cl->ctokens;
596
597 if (toks > cl->cbuffer)
598 toks = cl->cbuffer;
599 toks -= (long) qdisc_l2t(cl->ceil, bytes);
600 if (toks <= -cl->mbuffer)
601 toks = 1 - cl->mbuffer;
602
603 cl->ctokens = toks;
633} 604}
634 605
635/** 606/**
@@ -647,26 +618,20 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
647 int level, struct sk_buff *skb) 618 int level, struct sk_buff *skb)
648{ 619{
649 int bytes = qdisc_pkt_len(skb); 620 int bytes = qdisc_pkt_len(skb);
650 long toks, diff;
651 enum htb_cmode old_mode; 621 enum htb_cmode old_mode;
652 622 long diff;
653#define HTB_ACCNT(T,B,R) toks = diff + cl->T; \
654 if (toks > cl->B) toks = cl->B; \
655 toks -= L2T(cl, cl->R, bytes); \
656 if (toks <= -cl->mbuffer) toks = 1-cl->mbuffer; \
657 cl->T = toks
658 623
659 while (cl) { 624 while (cl) {
660 diff = psched_tdiff_bounded(q->now, cl->t_c, cl->mbuffer); 625 diff = psched_tdiff_bounded(q->now, cl->t_c, cl->mbuffer);
661 if (cl->level >= level) { 626 if (cl->level >= level) {
662 if (cl->level == level) 627 if (cl->level == level)
663 cl->xstats.lends++; 628 cl->xstats.lends++;
664 HTB_ACCNT(tokens, buffer, rate); 629 htb_accnt_tokens(cl, bytes, diff);
665 } else { 630 } else {
666 cl->xstats.borrows++; 631 cl->xstats.borrows++;
667 cl->tokens += diff; /* we moved t_c; update tokens */ 632 cl->tokens += diff; /* we moved t_c; update tokens */
668 } 633 }
669 HTB_ACCNT(ctokens, cbuffer, ceil); 634 htb_accnt_ctokens(cl, bytes, diff);
670 cl->t_c = q->now; 635 cl->t_c = q->now;
671 636
672 old_mode = cl->cmode; 637 old_mode = cl->cmode;
@@ -733,14 +698,14 @@ static struct rb_node *htb_id_find_next_upper(int prio, struct rb_node *n,
733 while (n) { 698 while (n) {
734 struct htb_class *cl = 699 struct htb_class *cl =
735 rb_entry(n, struct htb_class, node[prio]); 700 rb_entry(n, struct htb_class, node[prio]);
736 if (id == cl->common.classid)
737 return n;
738 701
739 if (id > cl->common.classid) { 702 if (id > cl->common.classid) {
740 n = n->rb_right; 703 n = n->rb_right;
741 } else { 704 } else if (id < cl->common.classid) {
742 r = n; 705 r = n;
743 n = n->rb_left; 706 n = n->rb_left;
707 } else {
708 return n;
744 } 709 }
745 } 710 }
746 return r; 711 return r;
@@ -761,7 +726,7 @@ static struct htb_class *htb_lookup_leaf(struct rb_root *tree, int prio,
761 u32 *pid; 726 u32 *pid;
762 } stk[TC_HTB_MAXDEPTH], *sp = stk; 727 } stk[TC_HTB_MAXDEPTH], *sp = stk;
763 728
764 WARN_ON(!tree->rb_node); 729 BUG_ON(!tree->rb_node);
765 sp->root = tree->rb_node; 730 sp->root = tree->rb_node;
766 sp->pptr = pptr; 731 sp->pptr = pptr;
767 sp->pid = pid; 732 sp->pid = pid;
@@ -781,9 +746,10 @@ static struct htb_class *htb_lookup_leaf(struct rb_root *tree, int prio,
781 *sp->pptr = (*sp->pptr)->rb_left; 746 *sp->pptr = (*sp->pptr)->rb_left;
782 if (sp > stk) { 747 if (sp > stk) {
783 sp--; 748 sp--;
784 WARN_ON(!*sp->pptr); 749 if (!*sp->pptr) {
785 if (!*sp->pptr) 750 WARN_ON(1);
786 return NULL; 751 return NULL;
752 }
787 htb_next_rb_node(sp->pptr); 753 htb_next_rb_node(sp->pptr);
788 } 754 }
789 } else { 755 } else {
@@ -814,8 +780,7 @@ static struct sk_buff *htb_dequeue_tree(struct htb_sched *q, int prio,
814 780
815 do { 781 do {
816next: 782next:
817 WARN_ON(!cl); 783 if (unlikely(!cl))
818 if (!cl)
819 return NULL; 784 return NULL;
820 785
821 /* class can be empty - it is unlikely but can be true if leaf 786 /* class can be empty - it is unlikely but can be true if leaf
@@ -849,7 +814,7 @@ next:
849 cl->common.classid); 814 cl->common.classid);
850 cl->warned = 1; 815 cl->warned = 1;
851 } 816 }
852 q->nwc_hit++; 817
853 htb_next_rb_node((level ? cl->parent->un.inner.ptr : q-> 818 htb_next_rb_node((level ? cl->parent->un.inner.ptr : q->
854 ptr[0]) + prio); 819 ptr[0]) + prio);
855 cl = htb_lookup_leaf(q->row[level] + prio, prio, 820 cl = htb_lookup_leaf(q->row[level] + prio, prio,
@@ -861,7 +826,7 @@ next:
861 if (likely(skb != NULL)) { 826 if (likely(skb != NULL)) {
862 cl->un.leaf.deficit[level] -= qdisc_pkt_len(skb); 827 cl->un.leaf.deficit[level] -= qdisc_pkt_len(skb);
863 if (cl->un.leaf.deficit[level] < 0) { 828 if (cl->un.leaf.deficit[level] < 0) {
864 cl->un.leaf.deficit[level] += cl->un.leaf.quantum; 829 cl->un.leaf.deficit[level] += cl->quantum;
865 htb_next_rb_node((level ? cl->parent->un.inner.ptr : q-> 830 htb_next_rb_node((level ? cl->parent->un.inner.ptr : q->
866 ptr[0]) + prio); 831 ptr[0]) + prio);
867 } 832 }
@@ -894,7 +859,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
894 q->now = psched_get_time(); 859 q->now = psched_get_time();
895 860
896 next_event = q->now + 5 * PSCHED_TICKS_PER_SEC; 861 next_event = q->now + 5 * PSCHED_TICKS_PER_SEC;
897 q->nwc_hit = 0; 862
898 for (level = 0; level < TC_HTB_MAXDEPTH; level++) { 863 for (level = 0; level < TC_HTB_MAXDEPTH; level++) {
899 /* common case optimization - skip event handler quickly */ 864 /* common case optimization - skip event handler quickly */
900 int m; 865 int m;
@@ -1095,8 +1060,8 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
1095 opt.buffer = cl->buffer; 1060 opt.buffer = cl->buffer;
1096 opt.ceil = cl->ceil->rate; 1061 opt.ceil = cl->ceil->rate;
1097 opt.cbuffer = cl->cbuffer; 1062 opt.cbuffer = cl->cbuffer;
1098 opt.quantum = cl->un.leaf.quantum; 1063 opt.quantum = cl->quantum;
1099 opt.prio = cl->un.leaf.prio; 1064 opt.prio = cl->prio;
1100 opt.level = cl->level; 1065 opt.level = cl->level;
1101 NLA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt); 1066 NLA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
1102 1067
@@ -1141,7 +1106,9 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1141 == NULL) 1106 == NULL)
1142 return -ENOBUFS; 1107 return -ENOBUFS;
1143 sch_tree_lock(sch); 1108 sch_tree_lock(sch);
1144 if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) { 1109 *old = cl->un.leaf.q;
1110 cl->un.leaf.q = new;
1111 if (*old != NULL) {
1145 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); 1112 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
1146 qdisc_reset(*old); 1113 qdisc_reset(*old);
1147 } 1114 }
@@ -1198,8 +1165,6 @@ static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl,
1198 memset(&parent->un.inner, 0, sizeof(parent->un.inner)); 1165 memset(&parent->un.inner, 0, sizeof(parent->un.inner));
1199 INIT_LIST_HEAD(&parent->un.leaf.drop_list); 1166 INIT_LIST_HEAD(&parent->un.leaf.drop_list);
1200 parent->un.leaf.q = new_q ? new_q : &noop_qdisc; 1167 parent->un.leaf.q = new_q ? new_q : &noop_qdisc;
1201 parent->un.leaf.quantum = parent->quantum;
1202 parent->un.leaf.prio = parent->prio;
1203 parent->tokens = parent->buffer; 1168 parent->tokens = parent->buffer;
1204 parent->ctokens = parent->cbuffer; 1169 parent->ctokens = parent->cbuffer;
1205 parent->t_c = psched_get_time(); 1170 parent->t_c = psched_get_time();
@@ -1371,9 +1336,14 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1371 if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL) 1336 if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
1372 goto failure; 1337 goto failure;
1373 1338
1374 gen_new_estimator(&cl->bstats, &cl->rate_est, 1339 err = gen_new_estimator(&cl->bstats, &cl->rate_est,
1375 qdisc_root_sleeping_lock(sch), 1340 qdisc_root_sleeping_lock(sch),
1376 tca[TCA_RATE] ? : &est.nla); 1341 tca[TCA_RATE] ? : &est.nla);
1342 if (err) {
1343 kfree(cl);
1344 goto failure;
1345 }
1346
1377 cl->refcnt = 1; 1347 cl->refcnt = 1;
1378 cl->children = 0; 1348 cl->children = 0;
1379 INIT_LIST_HEAD(&cl->un.leaf.drop_list); 1349 INIT_LIST_HEAD(&cl->un.leaf.drop_list);
@@ -1425,37 +1395,36 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1425 if (parent) 1395 if (parent)
1426 parent->children++; 1396 parent->children++;
1427 } else { 1397 } else {
1428 if (tca[TCA_RATE]) 1398 if (tca[TCA_RATE]) {
1429 gen_replace_estimator(&cl->bstats, &cl->rate_est, 1399 err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
1430 qdisc_root_sleeping_lock(sch), 1400 qdisc_root_sleeping_lock(sch),
1431 tca[TCA_RATE]); 1401 tca[TCA_RATE]);
1402 if (err)
1403 return err;
1404 }
1432 sch_tree_lock(sch); 1405 sch_tree_lock(sch);
1433 } 1406 }
1434 1407
1435 /* it used to be a nasty bug here, we have to check that node 1408 /* it used to be a nasty bug here, we have to check that node
1436 is really leaf before changing cl->un.leaf ! */ 1409 is really leaf before changing cl->un.leaf ! */
1437 if (!cl->level) { 1410 if (!cl->level) {
1438 cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum; 1411 cl->quantum = rtab->rate.rate / q->rate2quantum;
1439 if (!hopt->quantum && cl->un.leaf.quantum < 1000) { 1412 if (!hopt->quantum && cl->quantum < 1000) {
1440 printk(KERN_WARNING 1413 printk(KERN_WARNING
1441 "HTB: quantum of class %X is small. Consider r2q change.\n", 1414 "HTB: quantum of class %X is small. Consider r2q change.\n",
1442 cl->common.classid); 1415 cl->common.classid);
1443 cl->un.leaf.quantum = 1000; 1416 cl->quantum = 1000;
1444 } 1417 }
1445 if (!hopt->quantum && cl->un.leaf.quantum > 200000) { 1418 if (!hopt->quantum && cl->quantum > 200000) {
1446 printk(KERN_WARNING 1419 printk(KERN_WARNING
1447 "HTB: quantum of class %X is big. Consider r2q change.\n", 1420 "HTB: quantum of class %X is big. Consider r2q change.\n",
1448 cl->common.classid); 1421 cl->common.classid);
1449 cl->un.leaf.quantum = 200000; 1422 cl->quantum = 200000;
1450 } 1423 }
1451 if (hopt->quantum) 1424 if (hopt->quantum)
1452 cl->un.leaf.quantum = hopt->quantum; 1425 cl->quantum = hopt->quantum;
1453 if ((cl->un.leaf.prio = hopt->prio) >= TC_HTB_NUMPRIO) 1426 if ((cl->prio = hopt->prio) >= TC_HTB_NUMPRIO)
1454 cl->un.leaf.prio = TC_HTB_NUMPRIO - 1; 1427 cl->prio = TC_HTB_NUMPRIO - 1;
1455
1456 /* backup for htb_parent_to_leaf */
1457 cl->quantum = cl->un.leaf.quantum;
1458 cl->prio = cl->un.leaf.prio;
1459 } 1428 }
1460 1429
1461 cl->buffer = hopt->buffer; 1430 cl->buffer = hopt->buffer;
@@ -1565,7 +1534,7 @@ static struct Qdisc_ops htb_qdisc_ops __read_mostly = {
1565 .priv_size = sizeof(struct htb_sched), 1534 .priv_size = sizeof(struct htb_sched),
1566 .enqueue = htb_enqueue, 1535 .enqueue = htb_enqueue,
1567 .dequeue = htb_dequeue, 1536 .dequeue = htb_dequeue,
1568 .requeue = htb_requeue, 1537 .peek = qdisc_peek_dequeued,
1569 .drop = htb_drop, 1538 .drop = htb_drop,
1570 .init = htb_init, 1539 .init = htb_init,
1571 .reset = htb_reset, 1540 .reset = htb_reset,