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 */ | ||
