diff options
| author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
|---|---|---|
| committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
| commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
| tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/sched/sch_htb.c | |
| parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
| parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) | |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'net/sched/sch_htb.c')
| -rw-r--r-- | net/sched/sch_htb.c | 147 |
1 files changed, 78 insertions, 69 deletions
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 4be8d04b262d..29b942ce9e82 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
| @@ -99,9 +99,10 @@ struct htb_class { | |||
| 99 | struct rb_root feed[TC_HTB_NUMPRIO]; /* feed trees */ | 99 | struct rb_root feed[TC_HTB_NUMPRIO]; /* feed trees */ |
| 100 | struct rb_node *ptr[TC_HTB_NUMPRIO]; /* current class ptr */ | 100 | struct rb_node *ptr[TC_HTB_NUMPRIO]; /* current class ptr */ |
| 101 | /* When class changes from state 1->2 and disconnects from | 101 | /* When class changes from state 1->2 and disconnects from |
| 102 | parent's feed then we lost ptr value and start from the | 102 | * parent's feed then we lost ptr value and start from the |
| 103 | first child again. Here we store classid of the | 103 | * first child again. Here we store classid of the |
| 104 | last valid ptr (used when ptr is NULL). */ | 104 | * last valid ptr (used when ptr is NULL). |
| 105 | */ | ||
| 105 | u32 last_ptr_id[TC_HTB_NUMPRIO]; | 106 | u32 last_ptr_id[TC_HTB_NUMPRIO]; |
| 106 | } inner; | 107 | } inner; |
| 107 | } un; | 108 | } un; |
| @@ -182,10 +183,10 @@ static inline struct htb_class *htb_find(u32 handle, struct Qdisc *sch) | |||
| 182 | * filters in qdisc and in inner nodes (if higher filter points to the inner | 183 | * filters in qdisc and in inner nodes (if higher filter points to the inner |
| 183 | * node). If we end up with classid MAJOR:0 we enqueue the skb into special | 184 | * node). If we end up with classid MAJOR:0 we enqueue the skb into special |
| 184 | * internal fifo (direct). These packets then go directly thru. If we still | 185 | * internal fifo (direct). These packets then go directly thru. If we still |
| 185 | * have no valid leaf we try to use MAJOR:default leaf. It still unsuccessfull | 186 | * have no valid leaf we try to use MAJOR:default leaf. It still unsuccessful |
| 186 | * then finish and return direct queue. | 187 | * then finish and return direct queue. |
| 187 | */ | 188 | */ |
| 188 | #define HTB_DIRECT (struct htb_class*)-1 | 189 | #define HTB_DIRECT ((struct htb_class *)-1L) |
| 189 | 190 | ||
| 190 | static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, | 191 | static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, |
| 191 | int *qerr) | 192 | int *qerr) |
| @@ -197,11 +198,13 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, | |||
| 197 | int result; | 198 | int result; |
| 198 | 199 | ||
| 199 | /* allow to select class by setting skb->priority to valid classid; | 200 | /* allow to select class by setting skb->priority to valid classid; |
| 200 | note that nfmark can be used too by attaching filter fw with no | 201 | * note that nfmark can be used too by attaching filter fw with no |
| 201 | rules in it */ | 202 | * rules in it |
| 203 | */ | ||
| 202 | if (skb->priority == sch->handle) | 204 | if (skb->priority == sch->handle) |
| 203 | return HTB_DIRECT; /* X:0 (direct flow) selected */ | 205 | return HTB_DIRECT; /* X:0 (direct flow) selected */ |
| 204 | if ((cl = htb_find(skb->priority, sch)) != NULL && cl->level == 0) | 206 | cl = htb_find(skb->priority, sch); |
| 207 | if (cl && cl->level == 0) | ||
| 205 | return cl; | 208 | return cl; |
| 206 | 209 | ||
| 207 | *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; | 210 | *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; |
| @@ -216,10 +219,12 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, | |||
| 216 | return NULL; | 219 | return NULL; |
| 217 | } | 220 | } |
| 218 | #endif | 221 | #endif |
| 219 | if ((cl = (void *)res.class) == NULL) { | 222 | cl = (void *)res.class; |
| 223 | if (!cl) { | ||
| 220 | if (res.classid == sch->handle) | 224 | if (res.classid == sch->handle) |
| 221 | return HTB_DIRECT; /* X:0 (direct flow) */ | 225 | return HTB_DIRECT; /* X:0 (direct flow) */ |
| 222 | if ((cl = htb_find(res.classid, sch)) == NULL) | 226 | cl = htb_find(res.classid, sch); |
| 227 | if (!cl) | ||
| 223 | break; /* filter selected invalid classid */ | 228 | break; /* filter selected invalid classid */ |
| 224 | } | 229 | } |
| 225 | if (!cl->level) | 230 | if (!cl->level) |
| @@ -378,7 +383,8 @@ static void htb_activate_prios(struct htb_sched *q, struct htb_class *cl) | |||
| 378 | 383 | ||
| 379 | if (p->un.inner.feed[prio].rb_node) | 384 | if (p->un.inner.feed[prio].rb_node) |
| 380 | /* parent already has its feed in use so that | 385 | /* parent already has its feed in use so that |
| 381 | reset bit in mask as parent is already ok */ | 386 | * reset bit in mask as parent is already ok |
| 387 | */ | ||
| 382 | mask &= ~(1 << prio); | 388 | mask &= ~(1 << prio); |
| 383 | 389 | ||
| 384 | htb_add_to_id_tree(p->un.inner.feed + prio, cl, prio); | 390 | htb_add_to_id_tree(p->un.inner.feed + prio, cl, prio); |
| @@ -413,8 +419,9 @@ static void htb_deactivate_prios(struct htb_sched *q, struct htb_class *cl) | |||
| 413 | 419 | ||
| 414 | if (p->un.inner.ptr[prio] == cl->node + prio) { | 420 | if (p->un.inner.ptr[prio] == cl->node + prio) { |
| 415 | /* we are removing child which is pointed to from | 421 | /* we are removing child which is pointed to from |
| 416 | parent feed - forget the pointer but remember | 422 | * parent feed - forget the pointer but remember |
| 417 | classid */ | 423 | * classid |
| 424 | */ | ||
| 418 | p->un.inner.last_ptr_id[prio] = cl->common.classid; | 425 | p->un.inner.last_ptr_id[prio] = cl->common.classid; |
| 419 | p->un.inner.ptr[prio] = NULL; | 426 | p->un.inner.ptr[prio] = NULL; |
| 420 | } | 427 | } |
| @@ -569,15 +576,11 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 569 | } | 576 | } |
| 570 | return ret; | 577 | return ret; |
| 571 | } else { | 578 | } else { |
| 572 | cl->bstats.packets += | 579 | bstats_update(&cl->bstats, skb); |
| 573 | skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1; | ||
| 574 | cl->bstats.bytes += qdisc_pkt_len(skb); | ||
| 575 | htb_activate(q, cl); | 580 | htb_activate(q, cl); |
| 576 | } | 581 | } |
| 577 | 582 | ||
| 578 | sch->q.qlen++; | 583 | sch->q.qlen++; |
| 579 | sch->bstats.packets += skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1; | ||
| 580 | sch->bstats.bytes += qdisc_pkt_len(skb); | ||
| 581 | return NET_XMIT_SUCCESS; | 584 | return NET_XMIT_SUCCESS; |
| 582 | } | 585 | } |
| 583 | 586 | ||
| @@ -648,12 +651,10 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl, | |||
| 648 | htb_add_to_wait_tree(q, cl, diff); | 651 | htb_add_to_wait_tree(q, cl, diff); |
| 649 | } | 652 | } |
| 650 | 653 | ||
| 651 | /* update byte stats except for leaves which are already updated */ | 654 | /* update basic stats except for leaves which are already updated */ |
| 652 | if (cl->level) { | 655 | if (cl->level) |
| 653 | cl->bstats.bytes += bytes; | 656 | bstats_update(&cl->bstats, skb); |
| 654 | cl->bstats.packets += skb_is_gso(skb)? | 657 | |
| 655 | skb_shinfo(skb)->gso_segs:1; | ||
| 656 | } | ||
| 657 | cl = cl->parent; | 658 | cl = cl->parent; |
| 658 | } | 659 | } |
| 659 | } | 660 | } |
| @@ -669,8 +670,9 @@ static psched_time_t htb_do_events(struct htb_sched *q, int level, | |||
| 669 | unsigned long start) | 670 | unsigned long start) |
| 670 | { | 671 | { |
| 671 | /* don't run for longer than 2 jiffies; 2 is used instead of | 672 | /* don't run for longer than 2 jiffies; 2 is used instead of |
| 672 | 1 to simplify things when jiffy is going to be incremented | 673 | * 1 to simplify things when jiffy is going to be incremented |
| 673 | too soon */ | 674 | * too soon |
| 675 | */ | ||
| 674 | unsigned long stop_at = start + 2; | 676 | unsigned long stop_at = start + 2; |
| 675 | while (time_before(jiffies, stop_at)) { | 677 | while (time_before(jiffies, stop_at)) { |
| 676 | struct htb_class *cl; | 678 | struct htb_class *cl; |
| @@ -693,7 +695,7 @@ static psched_time_t htb_do_events(struct htb_sched *q, int level, | |||
| 693 | 695 | ||
| 694 | /* too much load - let's continue after a break for scheduling */ | 696 | /* too much load - let's continue after a break for scheduling */ |
| 695 | if (!(q->warned & HTB_WARN_TOOMANYEVENTS)) { | 697 | if (!(q->warned & HTB_WARN_TOOMANYEVENTS)) { |
| 696 | printk(KERN_WARNING "htb: too many events!\n"); | 698 | pr_warning("htb: too many events!\n"); |
| 697 | q->warned |= HTB_WARN_TOOMANYEVENTS; | 699 | q->warned |= HTB_WARN_TOOMANYEVENTS; |
| 698 | } | 700 | } |
| 699 | 701 | ||
| @@ -701,7 +703,8 @@ static psched_time_t htb_do_events(struct htb_sched *q, int level, | |||
| 701 | } | 703 | } |
| 702 | 704 | ||
| 703 | /* Returns class->node+prio from id-tree where classe's id is >= id. NULL | 705 | /* Returns class->node+prio from id-tree where classe's id is >= id. NULL |
| 704 | is no such one exists. */ | 706 | * is no such one exists. |
| 707 | */ | ||
| 705 | static struct rb_node *htb_id_find_next_upper(int prio, struct rb_node *n, | 708 | static struct rb_node *htb_id_find_next_upper(int prio, struct rb_node *n, |
| 706 | u32 id) | 709 | u32 id) |
| 707 | { | 710 | { |
| @@ -745,12 +748,14 @@ static struct htb_class *htb_lookup_leaf(struct rb_root *tree, int prio, | |||
| 745 | for (i = 0; i < 65535; i++) { | 748 | for (i = 0; i < 65535; i++) { |
| 746 | if (!*sp->pptr && *sp->pid) { | 749 | if (!*sp->pptr && *sp->pid) { |
| 747 | /* ptr was invalidated but id is valid - try to recover | 750 | /* ptr was invalidated but id is valid - try to recover |
| 748 | the original or next ptr */ | 751 | * the original or next ptr |
| 752 | */ | ||
| 749 | *sp->pptr = | 753 | *sp->pptr = |
| 750 | htb_id_find_next_upper(prio, sp->root, *sp->pid); | 754 | htb_id_find_next_upper(prio, sp->root, *sp->pid); |
| 751 | } | 755 | } |
| 752 | *sp->pid = 0; /* ptr is valid now so that remove this hint as it | 756 | *sp->pid = 0; /* ptr is valid now so that remove this hint as it |
| 753 | can become out of date quickly */ | 757 | * can become out of date quickly |
| 758 | */ | ||
| 754 | if (!*sp->pptr) { /* we are at right end; rewind & go up */ | 759 | if (!*sp->pptr) { /* we are at right end; rewind & go up */ |
| 755 | *sp->pptr = sp->root; | 760 | *sp->pptr = sp->root; |
| 756 | while ((*sp->pptr)->rb_left) | 761 | while ((*sp->pptr)->rb_left) |
| @@ -778,7 +783,8 @@ static struct htb_class *htb_lookup_leaf(struct rb_root *tree, int prio, | |||
| 778 | } | 783 | } |
| 779 | 784 | ||
| 780 | /* dequeues packet at given priority and level; call only if | 785 | /* dequeues packet at given priority and level; call only if |
| 781 | you are sure that there is active class at prio/level */ | 786 | * you are sure that there is active class at prio/level |
| 787 | */ | ||
| 782 | static struct sk_buff *htb_dequeue_tree(struct htb_sched *q, int prio, | 788 | static struct sk_buff *htb_dequeue_tree(struct htb_sched *q, int prio, |
| 783 | int level) | 789 | int level) |
| 784 | { | 790 | { |
| @@ -795,9 +801,10 @@ next: | |||
| 795 | return NULL; | 801 | return NULL; |
| 796 | 802 | ||
| 797 | /* class can be empty - it is unlikely but can be true if leaf | 803 | /* class can be empty - it is unlikely but can be true if leaf |
| 798 | qdisc drops packets in enqueue routine or if someone used | 804 | * qdisc drops packets in enqueue routine or if someone used |
| 799 | graft operation on the leaf since last dequeue; | 805 | * graft operation on the leaf since last dequeue; |
| 800 | simply deactivate and skip such class */ | 806 | * simply deactivate and skip such class |
| 807 | */ | ||
| 801 | if (unlikely(cl->un.leaf.q->q.qlen == 0)) { | 808 | if (unlikely(cl->un.leaf.q->q.qlen == 0)) { |
| 802 | struct htb_class *next; | 809 | struct htb_class *next; |
| 803 | htb_deactivate(q, cl); | 810 | htb_deactivate(q, cl); |
| @@ -837,7 +844,8 @@ next: | |||
| 837 | ptr[0]) + prio); | 844 | ptr[0]) + prio); |
| 838 | } | 845 | } |
| 839 | /* this used to be after charge_class but this constelation | 846 | /* this used to be after charge_class but this constelation |
| 840 | gives us slightly better performance */ | 847 | * gives us slightly better performance |
| 848 | */ | ||
| 841 | if (!cl->un.leaf.q->q.qlen) | 849 | if (!cl->un.leaf.q->q.qlen) |
| 842 | htb_deactivate(q, cl); | 850 | htb_deactivate(q, cl); |
| 843 | htb_charge_class(q, cl, level, skb); | 851 | htb_charge_class(q, cl, level, skb); |
| @@ -847,7 +855,7 @@ next: | |||
| 847 | 855 | ||
| 848 | static struct sk_buff *htb_dequeue(struct Qdisc *sch) | 856 | static struct sk_buff *htb_dequeue(struct Qdisc *sch) |
| 849 | { | 857 | { |
| 850 | struct sk_buff *skb = NULL; | 858 | struct sk_buff *skb; |
| 851 | struct htb_sched *q = qdisc_priv(sch); | 859 | struct htb_sched *q = qdisc_priv(sch); |
| 852 | int level; | 860 | int level; |
| 853 | psched_time_t next_event; | 861 | psched_time_t next_event; |
| @@ -856,7 +864,9 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) | |||
| 856 | /* try to dequeue direct packets as high prio (!) to minimize cpu work */ | 864 | /* try to dequeue direct packets as high prio (!) to minimize cpu work */ |
| 857 | skb = __skb_dequeue(&q->direct_queue); | 865 | skb = __skb_dequeue(&q->direct_queue); |
| 858 | if (skb != NULL) { | 866 | if (skb != NULL) { |
| 859 | sch->flags &= ~TCQ_F_THROTTLED; | 867 | ok: |
| 868 | qdisc_bstats_update(sch, skb); | ||
| 869 | qdisc_unthrottled(sch); | ||
| 860 | sch->q.qlen--; | 870 | sch->q.qlen--; |
| 861 | return skb; | 871 | return skb; |
| 862 | } | 872 | } |
| @@ -887,13 +897,11 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) | |||
| 887 | m = ~q->row_mask[level]; | 897 | m = ~q->row_mask[level]; |
| 888 | while (m != (int)(-1)) { | 898 | while (m != (int)(-1)) { |
| 889 | int prio = ffz(m); | 899 | int prio = ffz(m); |
| 900 | |||
| 890 | m |= 1 << prio; | 901 | m |= 1 << prio; |
| 891 | skb = htb_dequeue_tree(q, prio, level); | 902 | skb = htb_dequeue_tree(q, prio, level); |
| 892 | if (likely(skb != NULL)) { | 903 | if (likely(skb != NULL)) |
| 893 | sch->q.qlen--; | 904 | goto ok; |
| 894 | sch->flags &= ~TCQ_F_THROTTLED; | ||
| 895 | goto fin; | ||
| 896 | } | ||
| 897 | } | 905 | } |
| 898 | } | 906 | } |
| 899 | sch->qstats.overlimits++; | 907 | sch->qstats.overlimits++; |
| @@ -994,13 +1002,12 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) | |||
| 994 | return err; | 1002 | return err; |
| 995 | 1003 | ||
| 996 | if (tb[TCA_HTB_INIT] == NULL) { | 1004 | if (tb[TCA_HTB_INIT] == NULL) { |
| 997 | printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n"); | 1005 | pr_err("HTB: hey probably you have bad tc tool ?\n"); |
| 998 | return -EINVAL; | 1006 | return -EINVAL; |
| 999 | } | 1007 | } |
| 1000 | gopt = nla_data(tb[TCA_HTB_INIT]); | 1008 | gopt = nla_data(tb[TCA_HTB_INIT]); |
| 1001 | if (gopt->version != HTB_VER >> 16) { | 1009 | if (gopt->version != HTB_VER >> 16) { |
| 1002 | printk(KERN_ERR | 1010 | pr_err("HTB: need tc/htb version %d (minor is %d), you have %d\n", |
| 1003 | "HTB: need tc/htb version %d (minor is %d), you have %d\n", | ||
| 1004 | HTB_VER >> 16, HTB_VER & 0xffff, gopt->version); | 1011 | HTB_VER >> 16, HTB_VER & 0xffff, gopt->version); |
| 1005 | return -EINVAL; | 1012 | return -EINVAL; |
| 1006 | } | 1013 | } |
| @@ -1121,8 +1128,7 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, | |||
| 1121 | if (cl->level) | 1128 | if (cl->level) |
| 1122 | return -EINVAL; | 1129 | return -EINVAL; |
| 1123 | if (new == NULL && | 1130 | if (new == NULL && |
| 1124 | (new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, | 1131 | (new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, |
| 1125 | &pfifo_qdisc_ops, | ||
| 1126 | cl->common.classid)) == NULL) | 1132 | cl->common.classid)) == NULL) |
| 1127 | return -ENOBUFS; | 1133 | return -ENOBUFS; |
| 1128 | 1134 | ||
| @@ -1214,9 +1220,10 @@ static void htb_destroy(struct Qdisc *sch) | |||
| 1214 | cancel_work_sync(&q->work); | 1220 | cancel_work_sync(&q->work); |
| 1215 | qdisc_watchdog_cancel(&q->watchdog); | 1221 | qdisc_watchdog_cancel(&q->watchdog); |
| 1216 | /* This line used to be after htb_destroy_class call below | 1222 | /* This line used to be after htb_destroy_class call below |
| 1217 | and surprisingly it worked in 2.4. But it must precede it | 1223 | * and surprisingly it worked in 2.4. But it must precede it |
| 1218 | because filter need its target class alive to be able to call | 1224 | * because filter need its target class alive to be able to call |
| 1219 | unbind_filter on it (without Oops). */ | 1225 | * unbind_filter on it (without Oops). |
| 1226 | */ | ||
| 1220 | tcf_destroy_chain(&q->filter_list); | 1227 | tcf_destroy_chain(&q->filter_list); |
| 1221 | 1228 | ||
| 1222 | for (i = 0; i < q->clhash.hashsize; i++) { | 1229 | for (i = 0; i < q->clhash.hashsize; i++) { |
| @@ -1247,8 +1254,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) | |||
| 1247 | return -EBUSY; | 1254 | return -EBUSY; |
| 1248 | 1255 | ||
| 1249 | if (!cl->level && htb_parent_last_child(cl)) { | 1256 | if (!cl->level && htb_parent_last_child(cl)) { |
| 1250 | new_q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, | 1257 | new_q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, |
| 1251 | &pfifo_qdisc_ops, | ||
| 1252 | cl->parent->common.classid); | 1258 | cl->parent->common.classid); |
| 1253 | last_child = 1; | 1259 | last_child = 1; |
| 1254 | } | 1260 | } |
| @@ -1302,14 +1308,14 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
| 1302 | struct htb_class *cl = (struct htb_class *)*arg, *parent; | 1308 | struct htb_class *cl = (struct htb_class *)*arg, *parent; |
| 1303 | struct nlattr *opt = tca[TCA_OPTIONS]; | 1309 | struct nlattr *opt = tca[TCA_OPTIONS]; |
| 1304 | struct qdisc_rate_table *rtab = NULL, *ctab = NULL; | 1310 | struct qdisc_rate_table *rtab = NULL, *ctab = NULL; |
| 1305 | struct nlattr *tb[TCA_HTB_RTAB + 1]; | 1311 | struct nlattr *tb[__TCA_HTB_MAX]; |
| 1306 | struct tc_htb_opt *hopt; | 1312 | struct tc_htb_opt *hopt; |
| 1307 | 1313 | ||
| 1308 | /* extract all subattrs from opt attr */ | 1314 | /* extract all subattrs from opt attr */ |
| 1309 | if (!opt) | 1315 | if (!opt) |
| 1310 | goto failure; | 1316 | goto failure; |
| 1311 | 1317 | ||
| 1312 | err = nla_parse_nested(tb, TCA_HTB_RTAB, opt, htb_policy); | 1318 | err = nla_parse_nested(tb, TCA_HTB_MAX, opt, htb_policy); |
| 1313 | if (err < 0) | 1319 | if (err < 0) |
| 1314 | goto failure; | 1320 | goto failure; |
| 1315 | 1321 | ||
| @@ -1351,11 +1357,12 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
| 1351 | 1357 | ||
| 1352 | /* check maximal depth */ | 1358 | /* check maximal depth */ |
| 1353 | if (parent && parent->parent && parent->parent->level < 2) { | 1359 | if (parent && parent->parent && parent->parent->level < 2) { |
| 1354 | printk(KERN_ERR "htb: tree is too deep\n"); | 1360 | pr_err("htb: tree is too deep\n"); |
| 1355 | goto failure; | 1361 | goto failure; |
| 1356 | } | 1362 | } |
| 1357 | err = -ENOBUFS; | 1363 | err = -ENOBUFS; |
| 1358 | if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL) | 1364 | cl = kzalloc(sizeof(*cl), GFP_KERNEL); |
| 1365 | if (!cl) | ||
| 1359 | goto failure; | 1366 | goto failure; |
| 1360 | 1367 | ||
| 1361 | err = gen_new_estimator(&cl->bstats, &cl->rate_est, | 1368 | err = gen_new_estimator(&cl->bstats, &cl->rate_est, |
| @@ -1375,9 +1382,10 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
| 1375 | RB_CLEAR_NODE(&cl->node[prio]); | 1382 | RB_CLEAR_NODE(&cl->node[prio]); |
| 1376 | 1383 | ||
| 1377 | /* create leaf qdisc early because it uses kmalloc(GFP_KERNEL) | 1384 | /* create leaf qdisc early because it uses kmalloc(GFP_KERNEL) |
| 1378 | so that can't be used inside of sch_tree_lock | 1385 | * so that can't be used inside of sch_tree_lock |
| 1379 | -- thanks to Karlis Peisenieks */ | 1386 | * -- thanks to Karlis Peisenieks |
| 1380 | new_q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, | 1387 | */ |
| 1388 | new_q = qdisc_create_dflt(sch->dev_queue, | ||
| 1381 | &pfifo_qdisc_ops, classid); | 1389 | &pfifo_qdisc_ops, classid); |
| 1382 | sch_tree_lock(sch); | 1390 | sch_tree_lock(sch); |
| 1383 | if (parent && !parent->level) { | 1391 | if (parent && !parent->level) { |
| @@ -1428,17 +1436,18 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
| 1428 | } | 1436 | } |
| 1429 | 1437 | ||
| 1430 | /* it used to be a nasty bug here, we have to check that node | 1438 | /* it used to be a nasty bug here, we have to check that node |
| 1431 | is really leaf before changing cl->un.leaf ! */ | 1439 | * is really leaf before changing cl->un.leaf ! |
| 1440 | */ | ||
| 1432 | if (!cl->level) { | 1441 | if (!cl->level) { |
| 1433 | cl->quantum = rtab->rate.rate / q->rate2quantum; | 1442 | cl->quantum = rtab->rate.rate / q->rate2quantum; |
| 1434 | if (!hopt->quantum && cl->quantum < 1000) { | 1443 | if (!hopt->quantum && cl->quantum < 1000) { |
| 1435 | printk(KERN_WARNING | 1444 | pr_warning( |
| 1436 | "HTB: quantum of class %X is small. Consider r2q change.\n", | 1445 | "HTB: quantum of class %X is small. Consider r2q change.\n", |
| 1437 | cl->common.classid); | 1446 | cl->common.classid); |
| 1438 | cl->quantum = 1000; | 1447 | cl->quantum = 1000; |
| 1439 | } | 1448 | } |
| 1440 | if (!hopt->quantum && cl->quantum > 200000) { | 1449 | if (!hopt->quantum && cl->quantum > 200000) { |
| 1441 | printk(KERN_WARNING | 1450 | pr_warning( |
| 1442 | "HTB: quantum of class %X is big. Consider r2q change.\n", | 1451 | "HTB: quantum of class %X is big. Consider r2q change.\n", |
| 1443 | cl->common.classid); | 1452 | cl->common.classid); |
| 1444 | cl->quantum = 200000; | 1453 | cl->quantum = 200000; |
| @@ -1487,13 +1496,13 @@ static unsigned long htb_bind_filter(struct Qdisc *sch, unsigned long parent, | |||
| 1487 | struct htb_class *cl = htb_find(classid, sch); | 1496 | struct htb_class *cl = htb_find(classid, sch); |
| 1488 | 1497 | ||
| 1489 | /*if (cl && !cl->level) return 0; | 1498 | /*if (cl && !cl->level) return 0; |
| 1490 | The line above used to be there to prevent attaching filters to | 1499 | * The line above used to be there to prevent attaching filters to |
| 1491 | leaves. But at least tc_index filter uses this just to get class | 1500 | * leaves. But at least tc_index filter uses this just to get class |
| 1492 | for other reasons so that we have to allow for it. | 1501 | * for other reasons so that we have to allow for it. |
| 1493 | ---- | 1502 | * ---- |
| 1494 | 19.6.2002 As Werner explained it is ok - bind filter is just | 1503 | * 19.6.2002 As Werner explained it is ok - bind filter is just |
| 1495 | another way to "lock" the class - unlike "get" this lock can | 1504 | * another way to "lock" the class - unlike "get" this lock can |
| 1496 | be broken by class during destroy IIUC. | 1505 | * be broken by class during destroy IIUC. |
| 1497 | */ | 1506 | */ |
| 1498 | if (cl) | 1507 | if (cl) |
| 1499 | cl->filter_cnt++; | 1508 | cl->filter_cnt++; |
