aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/Kconfig56
-rw-r--r--net/sched/act_api.c81
-rw-r--r--net/sched/act_gact.c5
-rw-r--r--net/sched/act_ipt.c5
-rw-r--r--net/sched/act_mirred.c5
-rw-r--r--net/sched/act_pedit.c7
-rw-r--r--net/sched/act_police.c34
-rw-r--r--net/sched/act_simple.c5
-rw-r--r--net/sched/cls_api.c36
-rw-r--r--net/sched/cls_basic.c7
-rw-r--r--net/sched/cls_fw.c7
-rw-r--r--net/sched/cls_route.c11
-rw-r--r--net/sched/cls_rsvp.c1
-rw-r--r--net/sched/cls_rsvp.h12
-rw-r--r--net/sched/cls_rsvp6.c1
-rw-r--r--net/sched/cls_tcindex.c9
-rw-r--r--net/sched/cls_u32.c13
-rw-r--r--net/sched/em_u32.c2
-rw-r--r--net/sched/ematch.c17
-rw-r--r--net/sched/sch_api.c227
-rw-r--r--net/sched/sch_atm.c28
-rw-r--r--net/sched/sch_cbq.c207
-rw-r--r--net/sched/sch_dsmark.c22
-rw-r--r--net/sched/sch_generic.c35
-rw-r--r--net/sched/sch_hfsc.c109
-rw-r--r--net/sched/sch_htb.c130
-rw-r--r--net/sched/sch_ingress.c27
-rw-r--r--net/sched/sch_netem.c108
-rw-r--r--net/sched/sch_prio.c14
-rw-r--r--net/sched/sch_sfq.c9
-rw-r--r--net/sched/sch_tbf.c47
-rw-r--r--net/sched/sch_teql.c2
32 files changed, 511 insertions, 768 deletions
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index f4544dd86476..475df8449be9 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -46,62 +46,6 @@ config NET_SCH_FIFO
46 46
47if NET_SCHED 47if NET_SCHED
48 48
49choice
50 prompt "Packet scheduler clock source"
51 default NET_SCH_CLK_GETTIMEOFDAY
52 ---help---
53 Packet schedulers need a monotonic clock that increments at a static
54 rate. The kernel provides several suitable interfaces, each with
55 different properties:
56
57 - high resolution (us or better)
58 - fast to read (minimal locking, no i/o access)
59 - synchronized on all processors
60 - handles cpu clock frequency changes
61
62 but nothing provides all of the above.
63
64config NET_SCH_CLK_JIFFIES
65 bool "Timer interrupt"
66 ---help---
67 Say Y here if you want to use the timer interrupt (jiffies) as clock
68 source. This clock source is fast, synchronized on all processors and
69 handles cpu clock frequency changes, but its resolution is too low
70 for accurate shaping except at very low speed.
71
72config NET_SCH_CLK_GETTIMEOFDAY
73 bool "gettimeofday"
74 ---help---
75 Say Y here if you want to use gettimeofday as clock source. This clock
76 source has high resolution, is synchronized on all processors and
77 handles cpu clock frequency changes, but it is slow.
78
79 Choose this if you need a high resolution clock source but can't use
80 the CPU's cycle counter.
81
82# don't allow on SMP x86 because they can have unsynchronized TSCs.
83# gettimeofday is a good alternative
84config NET_SCH_CLK_CPU
85 bool "CPU cycle counter"
86 depends on ((X86_TSC || X86_64) && !SMP) || ALPHA || SPARC64 || PPC64 || IA64
87 ---help---
88 Say Y here if you want to use the CPU's cycle counter as clock source.
89 This is a cheap and high resolution clock source, but on some
90 architectures it is not synchronized on all processors and doesn't
91 handle cpu clock frequency changes.
92
93 The useable cycle counters are:
94
95 x86/x86_64 - Timestamp Counter
96 alpha - Cycle Counter
97 sparc64 - %ticks register
98 ppc64 - Time base
99 ia64 - Interval Time Counter
100
101 Choose this if your CPU's cycle counter is working properly.
102
103endchoice
104
105comment "Queueing/Scheduling" 49comment "Queueing/Scheduling"
106 50
107config NET_SCH_CBQ 51config NET_SCH_CBQ
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index cb21617a5670..711dd26c95c3 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -25,12 +25,12 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/netdevice.h> 26#include <linux/netdevice.h>
27#include <linux/skbuff.h> 27#include <linux/skbuff.h>
28#include <linux/rtnetlink.h>
29#include <linux/init.h> 28#include <linux/init.h>
30#include <linux/kmod.h> 29#include <linux/kmod.h>
31#include <net/sock.h> 30#include <net/sock.h>
32#include <net/sch_generic.h> 31#include <net/sch_generic.h>
33#include <net/act_api.h> 32#include <net/act_api.h>
33#include <net/netlink.h>
34 34
35void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo) 35void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
36{ 36{
@@ -93,15 +93,15 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
93 continue; 93 continue;
94 a->priv = p; 94 a->priv = p;
95 a->order = n_i; 95 a->order = n_i;
96 r = (struct rtattr*) skb->tail; 96 r = (struct rtattr *)skb_tail_pointer(skb);
97 RTA_PUT(skb, a->order, 0, NULL); 97 RTA_PUT(skb, a->order, 0, NULL);
98 err = tcf_action_dump_1(skb, a, 0, 0); 98 err = tcf_action_dump_1(skb, a, 0, 0);
99 if (err < 0) { 99 if (err < 0) {
100 index--; 100 index--;
101 skb_trim(skb, (u8*)r - skb->data); 101 nlmsg_trim(skb, r);
102 goto done; 102 goto done;
103 } 103 }
104 r->rta_len = skb->tail - (u8*)r; 104 r->rta_len = skb_tail_pointer(skb) - (u8 *)r;
105 n_i++; 105 n_i++;
106 if (n_i >= TCA_ACT_MAX_PRIO) 106 if (n_i >= TCA_ACT_MAX_PRIO)
107 goto done; 107 goto done;
@@ -114,7 +114,7 @@ done:
114 return n_i; 114 return n_i;
115 115
116rtattr_failure: 116rtattr_failure:
117 skb_trim(skb, (u8*)r - skb->data); 117 nlmsg_trim(skb, r);
118 goto done; 118 goto done;
119} 119}
120 120
@@ -125,7 +125,7 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
125 struct rtattr *r ; 125 struct rtattr *r ;
126 int i= 0, n_i = 0; 126 int i= 0, n_i = 0;
127 127
128 r = (struct rtattr*) skb->tail; 128 r = (struct rtattr *)skb_tail_pointer(skb);
129 RTA_PUT(skb, a->order, 0, NULL); 129 RTA_PUT(skb, a->order, 0, NULL);
130 RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); 130 RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
131 for (i = 0; i < (hinfo->hmask + 1); i++) { 131 for (i = 0; i < (hinfo->hmask + 1); i++) {
@@ -140,11 +140,11 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
140 } 140 }
141 } 141 }
142 RTA_PUT(skb, TCA_FCNT, 4, &n_i); 142 RTA_PUT(skb, TCA_FCNT, 4, &n_i);
143 r->rta_len = skb->tail - (u8*)r; 143 r->rta_len = skb_tail_pointer(skb) - (u8 *)r;
144 144
145 return n_i; 145 return n_i;
146rtattr_failure: 146rtattr_failure:
147 skb_trim(skb, (u8*)r - skb->data); 147 nlmsg_trim(skb, r);
148 return -EINVAL; 148 return -EINVAL;
149} 149}
150 150
@@ -423,7 +423,7 @@ int
423tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) 423tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
424{ 424{
425 int err = -EINVAL; 425 int err = -EINVAL;
426 unsigned char *b = skb->tail; 426 unsigned char *b = skb_tail_pointer(skb);
427 struct rtattr *r; 427 struct rtattr *r;
428 428
429 if (a->ops == NULL || a->ops->dump == NULL) 429 if (a->ops == NULL || a->ops->dump == NULL)
@@ -432,15 +432,15 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
432 RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); 432 RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
433 if (tcf_action_copy_stats(skb, a, 0)) 433 if (tcf_action_copy_stats(skb, a, 0))
434 goto rtattr_failure; 434 goto rtattr_failure;
435 r = (struct rtattr*) skb->tail; 435 r = (struct rtattr *)skb_tail_pointer(skb);
436 RTA_PUT(skb, TCA_OPTIONS, 0, NULL); 436 RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
437 if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) { 437 if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) {
438 r->rta_len = skb->tail - (u8*)r; 438 r->rta_len = skb_tail_pointer(skb) - (u8 *)r;
439 return err; 439 return err;
440 } 440 }
441 441
442rtattr_failure: 442rtattr_failure:
443 skb_trim(skb, b - skb->data); 443 nlmsg_trim(skb, b);
444 return -1; 444 return -1;
445} 445}
446 446
@@ -449,17 +449,17 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
449{ 449{
450 struct tc_action *a; 450 struct tc_action *a;
451 int err = -EINVAL; 451 int err = -EINVAL;
452 unsigned char *b = skb->tail; 452 unsigned char *b = skb_tail_pointer(skb);
453 struct rtattr *r ; 453 struct rtattr *r ;
454 454
455 while ((a = act) != NULL) { 455 while ((a = act) != NULL) {
456 r = (struct rtattr*) skb->tail; 456 r = (struct rtattr *)skb_tail_pointer(skb);
457 act = a->next; 457 act = a->next;
458 RTA_PUT(skb, a->order, 0, NULL); 458 RTA_PUT(skb, a->order, 0, NULL);
459 err = tcf_action_dump_1(skb, a, bind, ref); 459 err = tcf_action_dump_1(skb, a, bind, ref);
460 if (err < 0) 460 if (err < 0)
461 goto errout; 461 goto errout;
462 r->rta_len = skb->tail - (u8*)r; 462 r->rta_len = skb_tail_pointer(skb) - (u8 *)r;
463 } 463 }
464 464
465 return 0; 465 return 0;
@@ -467,7 +467,7 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
467rtattr_failure: 467rtattr_failure:
468 err = -EINVAL; 468 err = -EINVAL;
469errout: 469errout:
470 skb_trim(skb, b - skb->data); 470 nlmsg_trim(skb, b);
471 return err; 471 return err;
472} 472}
473 473
@@ -635,7 +635,7 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
635{ 635{
636 struct tcamsg *t; 636 struct tcamsg *t;
637 struct nlmsghdr *nlh; 637 struct nlmsghdr *nlh;
638 unsigned char *b = skb->tail; 638 unsigned char *b = skb_tail_pointer(skb);
639 struct rtattr *x; 639 struct rtattr *x;
640 640
641 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); 641 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
@@ -645,20 +645,20 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
645 t->tca__pad1 = 0; 645 t->tca__pad1 = 0;
646 t->tca__pad2 = 0; 646 t->tca__pad2 = 0;
647 647
648 x = (struct rtattr*) skb->tail; 648 x = (struct rtattr *)skb_tail_pointer(skb);
649 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); 649 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
650 650
651 if (tcf_action_dump(skb, a, bind, ref) < 0) 651 if (tcf_action_dump(skb, a, bind, ref) < 0)
652 goto rtattr_failure; 652 goto rtattr_failure;
653 653
654 x->rta_len = skb->tail - (u8*)x; 654 x->rta_len = skb_tail_pointer(skb) - (u8 *)x;
655 655
656 nlh->nlmsg_len = skb->tail - b; 656 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
657 return skb->len; 657 return skb->len;
658 658
659rtattr_failure: 659rtattr_failure:
660nlmsg_failure: 660nlmsg_failure:
661 skb_trim(skb, b - skb->data); 661 nlmsg_trim(skb, b);
662 return -1; 662 return -1;
663} 663}
664 664
@@ -767,7 +767,7 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid)
767 return -ENOBUFS; 767 return -ENOBUFS;
768 } 768 }
769 769
770 b = (unsigned char *)skb->tail; 770 b = skb_tail_pointer(skb);
771 771
772 if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0) 772 if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
773 goto err_out; 773 goto err_out;
@@ -783,16 +783,16 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid)
783 t->tca__pad1 = 0; 783 t->tca__pad1 = 0;
784 t->tca__pad2 = 0; 784 t->tca__pad2 = 0;
785 785
786 x = (struct rtattr *) skb->tail; 786 x = (struct rtattr *)skb_tail_pointer(skb);
787 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); 787 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
788 788
789 err = a->ops->walk(skb, &dcb, RTM_DELACTION, a); 789 err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
790 if (err < 0) 790 if (err < 0)
791 goto rtattr_failure; 791 goto rtattr_failure;
792 792
793 x->rta_len = skb->tail - (u8 *) x; 793 x->rta_len = skb_tail_pointer(skb) - (u8 *)x;
794 794
795 nlh->nlmsg_len = skb->tail - b; 795 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
796 nlh->nlmsg_flags |= NLM_F_ROOT; 796 nlh->nlmsg_flags |= NLM_F_ROOT;
797 module_put(a->ops->owner); 797 module_put(a->ops->owner);
798 kfree(a); 798 kfree(a);
@@ -884,7 +884,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
884 if (!skb) 884 if (!skb)
885 return -ENOBUFS; 885 return -ENOBUFS;
886 886
887 b = (unsigned char *)skb->tail; 887 b = skb_tail_pointer(skb);
888 888
889 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); 889 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
890 t = NLMSG_DATA(nlh); 890 t = NLMSG_DATA(nlh);
@@ -892,15 +892,15 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
892 t->tca__pad1 = 0; 892 t->tca__pad1 = 0;
893 t->tca__pad2 = 0; 893 t->tca__pad2 = 0;
894 894
895 x = (struct rtattr*) skb->tail; 895 x = (struct rtattr *)skb_tail_pointer(skb);
896 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); 896 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
897 897
898 if (tcf_action_dump(skb, a, 0, 0) < 0) 898 if (tcf_action_dump(skb, a, 0, 0) < 0)
899 goto rtattr_failure; 899 goto rtattr_failure;
900 900
901 x->rta_len = skb->tail - (u8*)x; 901 x->rta_len = skb_tail_pointer(skb) - (u8 *)x;
902 902
903 nlh->nlmsg_len = skb->tail - b; 903 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
904 NETLINK_CB(skb).dst_group = RTNLGRP_TC; 904 NETLINK_CB(skb).dst_group = RTNLGRP_TC;
905 905
906 err = rtnetlink_send(skb, pid, RTNLGRP_TC, flags&NLM_F_ECHO); 906 err = rtnetlink_send(skb, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
@@ -1015,7 +1015,7 @@ static int
1015tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) 1015tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1016{ 1016{
1017 struct nlmsghdr *nlh; 1017 struct nlmsghdr *nlh;
1018 unsigned char *b = skb->tail; 1018 unsigned char *b = skb_tail_pointer(skb);
1019 struct rtattr *x; 1019 struct rtattr *x;
1020 struct tc_action_ops *a_o; 1020 struct tc_action_ops *a_o;
1021 struct tc_action a; 1021 struct tc_action a;
@@ -1048,7 +1048,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1048 t->tca__pad1 = 0; 1048 t->tca__pad1 = 0;
1049 t->tca__pad2 = 0; 1049 t->tca__pad2 = 0;
1050 1050
1051 x = (struct rtattr *) skb->tail; 1051 x = (struct rtattr *)skb_tail_pointer(skb);
1052 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); 1052 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
1053 1053
1054 ret = a_o->walk(skb, cb, RTM_GETACTION, &a); 1054 ret = a_o->walk(skb, cb, RTM_GETACTION, &a);
@@ -1056,12 +1056,12 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1056 goto rtattr_failure; 1056 goto rtattr_failure;
1057 1057
1058 if (ret > 0) { 1058 if (ret > 0) {
1059 x->rta_len = skb->tail - (u8 *) x; 1059 x->rta_len = skb_tail_pointer(skb) - (u8 *)x;
1060 ret = skb->len; 1060 ret = skb->len;
1061 } else 1061 } else
1062 skb_trim(skb, (u8*)x - skb->data); 1062 nlmsg_trim(skb, x);
1063 1063
1064 nlh->nlmsg_len = skb->tail - b; 1064 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1065 if (NETLINK_CB(cb->skb).pid && ret) 1065 if (NETLINK_CB(cb->skb).pid && ret)
1066 nlh->nlmsg_flags |= NLM_F_MULTI; 1066 nlh->nlmsg_flags |= NLM_F_MULTI;
1067 module_put(a_o->owner); 1067 module_put(a_o->owner);
@@ -1070,20 +1070,15 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1070rtattr_failure: 1070rtattr_failure:
1071nlmsg_failure: 1071nlmsg_failure:
1072 module_put(a_o->owner); 1072 module_put(a_o->owner);
1073 skb_trim(skb, b - skb->data); 1073 nlmsg_trim(skb, b);
1074 return skb->len; 1074 return skb->len;
1075} 1075}
1076 1076
1077static int __init tc_action_init(void) 1077static int __init tc_action_init(void)
1078{ 1078{
1079 struct rtnetlink_link *link_p = rtnetlink_links[PF_UNSPEC]; 1079 rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL);
1080 1080 rtnl_register(PF_UNSPEC, RTM_DELACTION, tc_ctl_action, NULL);
1081 if (link_p) { 1081 rtnl_register(PF_UNSPEC, RTM_GETACTION, tc_ctl_action, tc_dump_action);
1082 link_p[RTM_NEWACTION-RTM_BASE].doit = tc_ctl_action;
1083 link_p[RTM_DELACTION-RTM_BASE].doit = tc_ctl_action;
1084 link_p[RTM_GETACTION-RTM_BASE].doit = tc_ctl_action;
1085 link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action;
1086 }
1087 1082
1088 return 0; 1083 return 0;
1089} 1084}
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index 87d0faf32867..7517f3791541 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -28,6 +28,7 @@
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
31#include <net/netlink.h>
31#include <net/sock.h> 32#include <net/sock.h>
32#include <net/pkt_sched.h> 33#include <net/pkt_sched.h>
33#include <linux/tc_act/tc_gact.h> 34#include <linux/tc_act/tc_gact.h>
@@ -155,7 +156,7 @@ static int tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result
155 156
156static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) 157static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
157{ 158{
158 unsigned char *b = skb->tail; 159 unsigned char *b = skb_tail_pointer(skb);
159 struct tc_gact opt; 160 struct tc_gact opt;
160 struct tcf_gact *gact = a->priv; 161 struct tcf_gact *gact = a->priv;
161 struct tcf_t t; 162 struct tcf_t t;
@@ -181,7 +182,7 @@ static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int
181 return skb->len; 182 return skb->len;
182 183
183rtattr_failure: 184rtattr_failure:
184 skb_trim(skb, b - skb->data); 185 nlmsg_trim(skb, b);
185 return -1; 186 return -1;
186} 187}
187 188
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 47f0b1324239..00b05f422d45 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -30,6 +30,7 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/proc_fs.h> 31#include <linux/proc_fs.h>
32#include <linux/kmod.h> 32#include <linux/kmod.h>
33#include <net/netlink.h>
33#include <net/sock.h> 34#include <net/sock.h>
34#include <net/pkt_sched.h> 35#include <net/pkt_sched.h>
35#include <linux/tc_act/tc_ipt.h> 36#include <linux/tc_act/tc_ipt.h>
@@ -245,7 +246,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
245 246
246static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) 247static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
247{ 248{
248 unsigned char *b = skb->tail; 249 unsigned char *b = skb_tail_pointer(skb);
249 struct tcf_ipt *ipt = a->priv; 250 struct tcf_ipt *ipt = a->priv;
250 struct ipt_entry_target *t; 251 struct ipt_entry_target *t;
251 struct tcf_t tm; 252 struct tcf_t tm;
@@ -277,7 +278,7 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int
277 return skb->len; 278 return skb->len;
278 279
279rtattr_failure: 280rtattr_failure:
280 skb_trim(skb, b - skb->data); 281 nlmsg_trim(skb, b);
281 kfree(t); 282 kfree(t);
282 return -1; 283 return -1;
283} 284}
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 3e93683e9ab3..de21c92faaa2 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -30,6 +30,7 @@
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <net/netlink.h>
33#include <net/sock.h> 34#include <net/sock.h>
34#include <net/pkt_sched.h> 35#include <net/pkt_sched.h>
35#include <linux/tc_act/tc_mirred.h> 36#include <linux/tc_act/tc_mirred.h>
@@ -206,7 +207,7 @@ bad_mirred:
206 207
207static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) 208static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
208{ 209{
209 unsigned char *b = skb->tail; 210 unsigned char *b = skb_tail_pointer(skb);
210 struct tcf_mirred *m = a->priv; 211 struct tcf_mirred *m = a->priv;
211 struct tc_mirred opt; 212 struct tc_mirred opt;
212 struct tcf_t t; 213 struct tcf_t t;
@@ -225,7 +226,7 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, i
225 return skb->len; 226 return skb->len;
226 227
227rtattr_failure: 228rtattr_failure:
228 skb_trim(skb, b - skb->data); 229 nlmsg_trim(skb, b);
229 return -1; 230 return -1;
230} 231}
231 232
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 3d6a2fcc9ce4..45b3cda86a21 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -27,6 +27,7 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/proc_fs.h> 29#include <linux/proc_fs.h>
30#include <net/netlink.h>
30#include <net/sock.h> 31#include <net/sock.h>
31#include <net/pkt_sched.h> 32#include <net/pkt_sched.h>
32#include <linux/tc_act/tc_pedit.h> 33#include <linux/tc_act/tc_pedit.h>
@@ -136,7 +137,7 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
136 } 137 }
137 } 138 }
138 139
139 pptr = skb->nh.raw; 140 pptr = skb_network_header(skb);
140 141
141 spin_lock(&p->tcf_lock); 142 spin_lock(&p->tcf_lock);
142 143
@@ -195,7 +196,7 @@ done:
195static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a, 196static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
196 int bind, int ref) 197 int bind, int ref)
197{ 198{
198 unsigned char *b = skb->tail; 199 unsigned char *b = skb_tail_pointer(skb);
199 struct tcf_pedit *p = a->priv; 200 struct tcf_pedit *p = a->priv;
200 struct tc_pedit *opt; 201 struct tc_pedit *opt;
201 struct tcf_t t; 202 struct tcf_t t;
@@ -226,7 +227,7 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
226 return skb->len; 227 return skb->len;
227 228
228rtattr_failure: 229rtattr_failure:
229 skb_trim(skb, b - skb->data); 230 nlmsg_trim(skb, b);
230 kfree(opt); 231 kfree(opt);
231 return -1; 232 return -1;
232} 233}
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 10a5a5c36f76..616f465f407e 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -30,6 +30,7 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <net/sock.h> 31#include <net/sock.h>
32#include <net/act_api.h> 32#include <net/act_api.h>
33#include <net/netlink.h>
33 34
34#define L2T(p,L) ((p)->tcfp_R_tab->data[(L)>>(p)->tcfp_R_tab->rate.cell_log]) 35#define L2T(p,L) ((p)->tcfp_R_tab->data[(L)>>(p)->tcfp_R_tab->rate.cell_log])
35#define L2T_P(p,L) ((p)->tcfp_P_tab->data[(L)>>(p)->tcfp_P_tab->rate.cell_log]) 36#define L2T_P(p,L) ((p)->tcfp_P_tab->data[(L)>>(p)->tcfp_P_tab->rate.cell_log])
@@ -80,7 +81,7 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c
80 continue; 81 continue;
81 a->priv = p; 82 a->priv = p;
82 a->order = index; 83 a->order = index;
83 r = (struct rtattr*) skb->tail; 84 r = (struct rtattr *)skb_tail_pointer(skb);
84 RTA_PUT(skb, a->order, 0, NULL); 85 RTA_PUT(skb, a->order, 0, NULL);
85 if (type == RTM_DELACTION) 86 if (type == RTM_DELACTION)
86 err = tcf_action_dump_1(skb, a, 0, 1); 87 err = tcf_action_dump_1(skb, a, 0, 1);
@@ -88,10 +89,10 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c
88 err = tcf_action_dump_1(skb, a, 0, 0); 89 err = tcf_action_dump_1(skb, a, 0, 0);
89 if (err < 0) { 90 if (err < 0) {
90 index--; 91 index--;
91 skb_trim(skb, (u8*)r - skb->data); 92 nlmsg_trim(skb, r);
92 goto done; 93 goto done;
93 } 94 }
94 r->rta_len = skb->tail - (u8*)r; 95 r->rta_len = skb_tail_pointer(skb) - (u8 *)r;
95 n_i++; 96 n_i++;
96 } 97 }
97 } 98 }
@@ -102,7 +103,7 @@ done:
102 return n_i; 103 return n_i;
103 104
104rtattr_failure: 105rtattr_failure:
105 skb_trim(skb, (u8*)r - skb->data); 106 nlmsg_trim(skb, r);
106 goto done; 107 goto done;
107} 108}
108#endif 109#endif
@@ -240,7 +241,7 @@ override:
240 if (ret != ACT_P_CREATED) 241 if (ret != ACT_P_CREATED)
241 return ret; 242 return ret;
242 243
243 PSCHED_GET_TIME(police->tcfp_t_c); 244 police->tcfp_t_c = psched_get_time();
244 police->tcf_index = parm->index ? parm->index : 245 police->tcf_index = parm->index ? parm->index :
245 tcf_hash_new_index(&police_idx_gen, &police_hash_info); 246 tcf_hash_new_index(&police_idx_gen, &police_hash_info);
246 h = tcf_hash(police->tcf_index, POL_TAB_MASK); 247 h = tcf_hash(police->tcf_index, POL_TAB_MASK);
@@ -295,10 +296,9 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a,
295 return police->tcfp_result; 296 return police->tcfp_result;
296 } 297 }
297 298
298 PSCHED_GET_TIME(now); 299 now = psched_get_time();
299 300 toks = psched_tdiff_bounded(now, police->tcfp_t_c,
300 toks = PSCHED_TDIFF_SAFE(now, police->tcfp_t_c, 301 police->tcfp_burst);
301 police->tcfp_burst);
302 if (police->tcfp_P_tab) { 302 if (police->tcfp_P_tab) {
303 ptoks = toks + police->tcfp_ptoks; 303 ptoks = toks + police->tcfp_ptoks;
304 if (ptoks > (long)L2T_P(police, police->tcfp_mtu)) 304 if (ptoks > (long)L2T_P(police, police->tcfp_mtu))
@@ -326,7 +326,7 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a,
326static int 326static int
327tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) 327tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
328{ 328{
329 unsigned char *b = skb->tail; 329 unsigned char *b = skb_tail_pointer(skb);
330 struct tcf_police *police = a->priv; 330 struct tcf_police *police = a->priv;
331 struct tc_police opt; 331 struct tc_police opt;
332 332
@@ -355,7 +355,7 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
355 return skb->len; 355 return skb->len;
356 356
357rtattr_failure: 357rtattr_failure:
358 skb_trim(skb, b - skb->data); 358 nlmsg_trim(skb, b);
359 return -1; 359 return -1;
360} 360}
361 361
@@ -494,7 +494,7 @@ struct tcf_police *tcf_police_locate(struct rtattr *rta, struct rtattr *est)
494 } 494 }
495 if (police->tcfp_P_tab) 495 if (police->tcfp_P_tab)
496 police->tcfp_ptoks = L2T_P(police, police->tcfp_mtu); 496 police->tcfp_ptoks = L2T_P(police, police->tcfp_mtu);
497 PSCHED_GET_TIME(police->tcfp_t_c); 497 police->tcfp_t_c = psched_get_time();
498 police->tcf_index = parm->index ? parm->index : 498 police->tcf_index = parm->index ? parm->index :
499 tcf_police_new_index(); 499 tcf_police_new_index();
500 police->tcf_action = parm->action; 500 police->tcf_action = parm->action;
@@ -542,9 +542,9 @@ int tcf_police(struct sk_buff *skb, struct tcf_police *police)
542 return police->tcfp_result; 542 return police->tcfp_result;
543 } 543 }
544 544
545 PSCHED_GET_TIME(now); 545 now = psched_get_time();
546 toks = PSCHED_TDIFF_SAFE(now, police->tcfp_t_c, 546 toks = psched_tdiff_bounded(now, police->tcfp_t_c,
547 police->tcfp_burst); 547 police->tcfp_burst);
548 if (police->tcfp_P_tab) { 548 if (police->tcfp_P_tab) {
549 ptoks = toks + police->tcfp_ptoks; 549 ptoks = toks + police->tcfp_ptoks;
550 if (ptoks > (long)L2T_P(police, police->tcfp_mtu)) 550 if (ptoks > (long)L2T_P(police, police->tcfp_mtu))
@@ -572,7 +572,7 @@ EXPORT_SYMBOL(tcf_police);
572 572
573int tcf_police_dump(struct sk_buff *skb, struct tcf_police *police) 573int tcf_police_dump(struct sk_buff *skb, struct tcf_police *police)
574{ 574{
575 unsigned char *b = skb->tail; 575 unsigned char *b = skb_tail_pointer(skb);
576 struct tc_police opt; 576 struct tc_police opt;
577 577
578 opt.index = police->tcf_index; 578 opt.index = police->tcf_index;
@@ -598,7 +598,7 @@ int tcf_police_dump(struct sk_buff *skb, struct tcf_police *police)
598 return skb->len; 598 return skb->len;
599 599
600rtattr_failure: 600rtattr_failure:
601 skb_trim(skb, b - skb->data); 601 nlmsg_trim(skb, b);
602 return -1; 602 return -1;
603} 603}
604 604
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index c7971182af07..36e1edad5990 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -16,6 +16,7 @@
16#include <linux/netdevice.h> 16#include <linux/netdevice.h>
17#include <linux/skbuff.h> 17#include <linux/skbuff.h>
18#include <linux/rtnetlink.h> 18#include <linux/rtnetlink.h>
19#include <net/netlink.h>
19#include <net/pkt_sched.h> 20#include <net/pkt_sched.h>
20 21
21#define TCA_ACT_SIMP 22 22#define TCA_ACT_SIMP 22
@@ -155,7 +156,7 @@ static inline int tcf_simp_cleanup(struct tc_action *a, int bind)
155static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a, 156static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
156 int bind, int ref) 157 int bind, int ref)
157{ 158{
158 unsigned char *b = skb->tail; 159 unsigned char *b = skb_tail_pointer(skb);
159 struct tcf_defact *d = a->priv; 160 struct tcf_defact *d = a->priv;
160 struct tc_defact opt; 161 struct tc_defact opt;
161 struct tcf_t t; 162 struct tcf_t t;
@@ -173,7 +174,7 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
173 return skb->len; 174 return skb->len;
174 175
175rtattr_failure: 176rtattr_failure:
176 skb_trim(skb, b - skb->data); 177 nlmsg_trim(skb, b);
177 return -1; 178 return -1;
178} 179}
179 180
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 5c6ffdb77d2d..ebf94edf0478 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -29,9 +29,10 @@
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/netdevice.h> 30#include <linux/netdevice.h>
31#include <linux/skbuff.h> 31#include <linux/skbuff.h>
32#include <linux/rtnetlink.h>
33#include <linux/init.h> 32#include <linux/init.h>
34#include <linux/kmod.h> 33#include <linux/kmod.h>
34#include <linux/netlink.h>
35#include <net/netlink.h>
35#include <net/sock.h> 36#include <net/sock.h>
36#include <net/pkt_sched.h> 37#include <net/pkt_sched.h>
37#include <net/pkt_cls.h> 38#include <net/pkt_cls.h>
@@ -323,7 +324,7 @@ tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh,
323{ 324{
324 struct tcmsg *tcm; 325 struct tcmsg *tcm;
325 struct nlmsghdr *nlh; 326 struct nlmsghdr *nlh;
326 unsigned char *b = skb->tail; 327 unsigned char *b = skb_tail_pointer(skb);
327 328
328 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); 329 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
329 tcm = NLMSG_DATA(nlh); 330 tcm = NLMSG_DATA(nlh);
@@ -340,12 +341,12 @@ tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh,
340 if (tp->ops->dump && tp->ops->dump(tp, fh, skb, tcm) < 0) 341 if (tp->ops->dump && tp->ops->dump(tp, fh, skb, tcm) < 0)
341 goto rtattr_failure; 342 goto rtattr_failure;
342 } 343 }
343 nlh->nlmsg_len = skb->tail - b; 344 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
344 return skb->len; 345 return skb->len;
345 346
346nlmsg_failure: 347nlmsg_failure:
347rtattr_failure: 348rtattr_failure:
348 skb_trim(skb, b - skb->data); 349 nlmsg_trim(skb, b);
349 return -1; 350 return -1;
350} 351}
351 352
@@ -399,7 +400,6 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
399 if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL) 400 if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL)
400 return skb->len; 401 return skb->len;
401 402
402 read_lock(&qdisc_tree_lock);
403 if (!tcm->tcm_parent) 403 if (!tcm->tcm_parent)
404 q = dev->qdisc_sleeping; 404 q = dev->qdisc_sleeping;
405 else 405 else
@@ -456,7 +456,6 @@ errout:
456 if (cl) 456 if (cl)
457 cops->put(q, cl); 457 cops->put(q, cl);
458out: 458out:
459 read_unlock(&qdisc_tree_lock);
460 dev_put(dev); 459 dev_put(dev);
461 return skb->len; 460 return skb->len;
462} 461}
@@ -563,30 +562,30 @@ tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
563 * to work with both old and new modes of entering 562 * to work with both old and new modes of entering
564 * tc data even if iproute2 was newer - jhs 563 * tc data even if iproute2 was newer - jhs
565 */ 564 */
566 struct rtattr * p_rta = (struct rtattr*) skb->tail; 565 struct rtattr *p_rta = (struct rtattr *)skb_tail_pointer(skb);
567 566
568 if (exts->action->type != TCA_OLD_COMPAT) { 567 if (exts->action->type != TCA_OLD_COMPAT) {
569 RTA_PUT(skb, map->action, 0, NULL); 568 RTA_PUT(skb, map->action, 0, NULL);
570 if (tcf_action_dump(skb, exts->action, 0, 0) < 0) 569 if (tcf_action_dump(skb, exts->action, 0, 0) < 0)
571 goto rtattr_failure; 570 goto rtattr_failure;
572 p_rta->rta_len = skb->tail - (u8*)p_rta; 571 p_rta->rta_len = skb_tail_pointer(skb) - (u8 *)p_rta;
573 } else if (map->police) { 572 } else if (map->police) {
574 RTA_PUT(skb, map->police, 0, NULL); 573 RTA_PUT(skb, map->police, 0, NULL);
575 if (tcf_action_dump_old(skb, exts->action, 0, 0) < 0) 574 if (tcf_action_dump_old(skb, exts->action, 0, 0) < 0)
576 goto rtattr_failure; 575 goto rtattr_failure;
577 p_rta->rta_len = skb->tail - (u8*)p_rta; 576 p_rta->rta_len = skb_tail_pointer(skb) - (u8 *)p_rta;
578 } 577 }
579 } 578 }
580#elif defined CONFIG_NET_CLS_POLICE 579#elif defined CONFIG_NET_CLS_POLICE
581 if (map->police && exts->police) { 580 if (map->police && exts->police) {
582 struct rtattr * p_rta = (struct rtattr*) skb->tail; 581 struct rtattr *p_rta = (struct rtattr *)skb_tail_pointer(skb);
583 582
584 RTA_PUT(skb, map->police, 0, NULL); 583 RTA_PUT(skb, map->police, 0, NULL);
585 584
586 if (tcf_police_dump(skb, exts->police) < 0) 585 if (tcf_police_dump(skb, exts->police) < 0)
587 goto rtattr_failure; 586 goto rtattr_failure;
588 587
589 p_rta->rta_len = skb->tail - (u8*)p_rta; 588 p_rta->rta_len = skb_tail_pointer(skb) - (u8 *)p_rta;
590 } 589 }
591#endif 590#endif
592 return 0; 591 return 0;
@@ -614,18 +613,11 @@ rtattr_failure: __attribute__ ((unused))
614 613
615static int __init tc_filter_init(void) 614static int __init tc_filter_init(void)
616{ 615{
617 struct rtnetlink_link *link_p = rtnetlink_links[PF_UNSPEC]; 616 rtnl_register(PF_UNSPEC, RTM_NEWTFILTER, tc_ctl_tfilter, NULL);
617 rtnl_register(PF_UNSPEC, RTM_DELTFILTER, tc_ctl_tfilter, NULL);
618 rtnl_register(PF_UNSPEC, RTM_GETTFILTER, tc_ctl_tfilter,
619 tc_dump_tfilter);
618 620
619 /* Setup rtnetlink links. It is made here to avoid
620 exporting large number of public symbols.
621 */
622
623 if (link_p) {
624 link_p[RTM_NEWTFILTER-RTM_BASE].doit = tc_ctl_tfilter;
625 link_p[RTM_DELTFILTER-RTM_BASE].doit = tc_ctl_tfilter;
626 link_p[RTM_GETTFILTER-RTM_BASE].doit = tc_ctl_tfilter;
627 link_p[RTM_GETTFILTER-RTM_BASE].dumpit = tc_dump_tfilter;
628 }
629 return 0; 621 return 0;
630} 622}
631 623
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 4a91f082a81d..c885412d79d5 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -17,6 +17,7 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/rtnetlink.h> 18#include <linux/rtnetlink.h>
19#include <linux/skbuff.h> 19#include <linux/skbuff.h>
20#include <net/netlink.h>
20#include <net/act_api.h> 21#include <net/act_api.h>
21#include <net/pkt_cls.h> 22#include <net/pkt_cls.h>
22 23
@@ -245,7 +246,7 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh,
245 struct sk_buff *skb, struct tcmsg *t) 246 struct sk_buff *skb, struct tcmsg *t)
246{ 247{
247 struct basic_filter *f = (struct basic_filter *) fh; 248 struct basic_filter *f = (struct basic_filter *) fh;
248 unsigned char *b = skb->tail; 249 unsigned char *b = skb_tail_pointer(skb);
249 struct rtattr *rta; 250 struct rtattr *rta;
250 251
251 if (f == NULL) 252 if (f == NULL)
@@ -263,11 +264,11 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh,
263 tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0) 264 tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0)
264 goto rtattr_failure; 265 goto rtattr_failure;
265 266
266 rta->rta_len = (skb->tail - b); 267 rta->rta_len = skb_tail_pointer(skb) - b;
267 return skb->len; 268 return skb->len;
268 269
269rtattr_failure: 270rtattr_failure:
270 skb_trim(skb, b - skb->data); 271 nlmsg_trim(skb, b);
271 return -1; 272 return -1;
272} 273}
273 274
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 5dbb9d451f73..bbec4a0d4dcb 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -38,6 +38,7 @@
38#include <linux/notifier.h> 38#include <linux/notifier.h>
39#include <linux/netfilter.h> 39#include <linux/netfilter.h>
40#include <net/ip.h> 40#include <net/ip.h>
41#include <net/netlink.h>
41#include <net/route.h> 42#include <net/route.h>
42#include <linux/skbuff.h> 43#include <linux/skbuff.h>
43#include <net/sock.h> 44#include <net/sock.h>
@@ -348,7 +349,7 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
348{ 349{
349 struct fw_head *head = (struct fw_head *)tp->root; 350 struct fw_head *head = (struct fw_head *)tp->root;
350 struct fw_filter *f = (struct fw_filter*)fh; 351 struct fw_filter *f = (struct fw_filter*)fh;
351 unsigned char *b = skb->tail; 352 unsigned char *b = skb_tail_pointer(skb);
352 struct rtattr *rta; 353 struct rtattr *rta;
353 354
354 if (f == NULL) 355 if (f == NULL)
@@ -374,7 +375,7 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
374 if (tcf_exts_dump(skb, &f->exts, &fw_ext_map) < 0) 375 if (tcf_exts_dump(skb, &f->exts, &fw_ext_map) < 0)
375 goto rtattr_failure; 376 goto rtattr_failure;
376 377
377 rta->rta_len = skb->tail - b; 378 rta->rta_len = skb_tail_pointer(skb) - b;
378 379
379 if (tcf_exts_dump_stats(skb, &f->exts, &fw_ext_map) < 0) 380 if (tcf_exts_dump_stats(skb, &f->exts, &fw_ext_map) < 0)
380 goto rtattr_failure; 381 goto rtattr_failure;
@@ -382,7 +383,7 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
382 return skb->len; 383 return skb->len;
383 384
384rtattr_failure: 385rtattr_failure:
385 skb_trim(skb, b - skb->data); 386 nlmsg_trim(skb, b);
386 return -1; 387 return -1;
387} 388}
388 389
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index abc47cc48ad0..cc941d0ee3a5 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -28,6 +28,7 @@
28#include <linux/etherdevice.h> 28#include <linux/etherdevice.h>
29#include <linux/notifier.h> 29#include <linux/notifier.h>
30#include <net/ip.h> 30#include <net/ip.h>
31#include <net/netlink.h>
31#include <net/route.h> 32#include <net/route.h>
32#include <linux/skbuff.h> 33#include <linux/skbuff.h>
33#include <net/sock.h> 34#include <net/sock.h>
@@ -88,9 +89,9 @@ static __inline__ int route4_fastmap_hash(u32 id, int iif)
88static inline 89static inline
89void route4_reset_fastmap(struct net_device *dev, struct route4_head *head, u32 id) 90void route4_reset_fastmap(struct net_device *dev, struct route4_head *head, u32 id)
90{ 91{
91 spin_lock_bh(&dev->queue_lock); 92 qdisc_lock_tree(dev);
92 memset(head->fastmap, 0, sizeof(head->fastmap)); 93 memset(head->fastmap, 0, sizeof(head->fastmap));
93 spin_unlock_bh(&dev->queue_lock); 94 qdisc_unlock_tree(dev);
94} 95}
95 96
96static inline void 97static inline void
@@ -562,7 +563,7 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh,
562 struct sk_buff *skb, struct tcmsg *t) 563 struct sk_buff *skb, struct tcmsg *t)
563{ 564{
564 struct route4_filter *f = (struct route4_filter*)fh; 565 struct route4_filter *f = (struct route4_filter*)fh;
565 unsigned char *b = skb->tail; 566 unsigned char *b = skb_tail_pointer(skb);
566 struct rtattr *rta; 567 struct rtattr *rta;
567 u32 id; 568 u32 id;
568 569
@@ -591,7 +592,7 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh,
591 if (tcf_exts_dump(skb, &f->exts, &route_ext_map) < 0) 592 if (tcf_exts_dump(skb, &f->exts, &route_ext_map) < 0)
592 goto rtattr_failure; 593 goto rtattr_failure;
593 594
594 rta->rta_len = skb->tail - b; 595 rta->rta_len = skb_tail_pointer(skb) - b;
595 596
596 if (tcf_exts_dump_stats(skb, &f->exts, &route_ext_map) < 0) 597 if (tcf_exts_dump_stats(skb, &f->exts, &route_ext_map) < 0)
597 goto rtattr_failure; 598 goto rtattr_failure;
@@ -599,7 +600,7 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh,
599 return skb->len; 600 return skb->len;
600 601
601rtattr_failure: 602rtattr_failure:
602 skb_trim(skb, b - skb->data); 603 nlmsg_trim(skb, b);
603 return -1; 604 return -1;
604} 605}
605 606
diff --git a/net/sched/cls_rsvp.c b/net/sched/cls_rsvp.c
index 1d4a1fb17608..0a683c07c648 100644
--- a/net/sched/cls_rsvp.c
+++ b/net/sched/cls_rsvp.c
@@ -31,6 +31,7 @@
31#include <net/route.h> 31#include <net/route.h>
32#include <linux/skbuff.h> 32#include <linux/skbuff.h>
33#include <net/sock.h> 33#include <net/sock.h>
34#include <net/netlink.h>
34#include <net/act_api.h> 35#include <net/act_api.h>
35#include <net/pkt_cls.h> 36#include <net/pkt_cls.h>
36 37
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 7853621a04cc..22f9ede70e8f 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -143,9 +143,9 @@ static int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp,
143 u8 tunnelid = 0; 143 u8 tunnelid = 0;
144 u8 *xprt; 144 u8 *xprt;
145#if RSVP_DST_LEN == 4 145#if RSVP_DST_LEN == 4
146 struct ipv6hdr *nhptr = skb->nh.ipv6h; 146 struct ipv6hdr *nhptr = ipv6_hdr(skb);
147#else 147#else
148 struct iphdr *nhptr = skb->nh.iph; 148 struct iphdr *nhptr = ip_hdr(skb);
149#endif 149#endif
150 150
151restart: 151restart:
@@ -160,7 +160,7 @@ restart:
160 dst = &nhptr->daddr; 160 dst = &nhptr->daddr;
161 protocol = nhptr->protocol; 161 protocol = nhptr->protocol;
162 xprt = ((u8*)nhptr) + (nhptr->ihl<<2); 162 xprt = ((u8*)nhptr) + (nhptr->ihl<<2);
163 if (nhptr->frag_off&__constant_htons(IP_MF|IP_OFFSET)) 163 if (nhptr->frag_off & htons(IP_MF|IP_OFFSET))
164 return -1; 164 return -1;
165#endif 165#endif
166 166
@@ -593,7 +593,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
593{ 593{
594 struct rsvp_filter *f = (struct rsvp_filter*)fh; 594 struct rsvp_filter *f = (struct rsvp_filter*)fh;
595 struct rsvp_session *s; 595 struct rsvp_session *s;
596 unsigned char *b = skb->tail; 596 unsigned char *b = skb_tail_pointer(skb);
597 struct rtattr *rta; 597 struct rtattr *rta;
598 struct tc_rsvp_pinfo pinfo; 598 struct tc_rsvp_pinfo pinfo;
599 599
@@ -623,14 +623,14 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
623 if (tcf_exts_dump(skb, &f->exts, &rsvp_ext_map) < 0) 623 if (tcf_exts_dump(skb, &f->exts, &rsvp_ext_map) < 0)
624 goto rtattr_failure; 624 goto rtattr_failure;
625 625
626 rta->rta_len = skb->tail - b; 626 rta->rta_len = skb_tail_pointer(skb) - b;
627 627
628 if (tcf_exts_dump_stats(skb, &f->exts, &rsvp_ext_map) < 0) 628 if (tcf_exts_dump_stats(skb, &f->exts, &rsvp_ext_map) < 0)
629 goto rtattr_failure; 629 goto rtattr_failure;
630 return skb->len; 630 return skb->len;
631 631
632rtattr_failure: 632rtattr_failure:
633 skb_trim(skb, b - skb->data); 633 nlmsg_trim(skb, b);
634 return -1; 634 return -1;
635} 635}
636 636
diff --git a/net/sched/cls_rsvp6.c b/net/sched/cls_rsvp6.c
index a2979d89798f..93b6abed57db 100644
--- a/net/sched/cls_rsvp6.c
+++ b/net/sched/cls_rsvp6.c
@@ -34,6 +34,7 @@
34#include <net/sock.h> 34#include <net/sock.h>
35#include <net/act_api.h> 35#include <net/act_api.h>
36#include <net/pkt_cls.h> 36#include <net/pkt_cls.h>
37#include <net/netlink.h>
37 38
38#define RSVP_DST_LEN 4 39#define RSVP_DST_LEN 4
39#define RSVP_ID "rsvp6" 40#define RSVP_ID "rsvp6"
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 7563fdcef4b7..47ac0c556429 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -12,6 +12,7 @@
12#include <linux/netdevice.h> 12#include <linux/netdevice.h>
13#include <net/ip.h> 13#include <net/ip.h>
14#include <net/act_api.h> 14#include <net/act_api.h>
15#include <net/netlink.h>
15#include <net/pkt_cls.h> 16#include <net/pkt_cls.h>
16#include <net/route.h> 17#include <net/route.h>
17 18
@@ -448,7 +449,7 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
448{ 449{
449 struct tcindex_data *p = PRIV(tp); 450 struct tcindex_data *p = PRIV(tp);
450 struct tcindex_filter_result *r = (struct tcindex_filter_result *) fh; 451 struct tcindex_filter_result *r = (struct tcindex_filter_result *) fh;
451 unsigned char *b = skb->tail; 452 unsigned char *b = skb_tail_pointer(skb);
452 struct rtattr *rta; 453 struct rtattr *rta;
453 454
454 DPRINTK("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p,b %p\n", 455 DPRINTK("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p,b %p\n",
@@ -463,7 +464,7 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
463 RTA_PUT(skb,TCA_TCINDEX_SHIFT,sizeof(p->shift),&p->shift); 464 RTA_PUT(skb,TCA_TCINDEX_SHIFT,sizeof(p->shift),&p->shift);
464 RTA_PUT(skb,TCA_TCINDEX_FALL_THROUGH,sizeof(p->fall_through), 465 RTA_PUT(skb,TCA_TCINDEX_FALL_THROUGH,sizeof(p->fall_through),
465 &p->fall_through); 466 &p->fall_through);
466 rta->rta_len = skb->tail-b; 467 rta->rta_len = skb_tail_pointer(skb) - b;
467 } else { 468 } else {
468 if (p->perfect) { 469 if (p->perfect) {
469 t->tcm_handle = r-p->perfect; 470 t->tcm_handle = r-p->perfect;
@@ -486,7 +487,7 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
486 487
487 if (tcf_exts_dump(skb, &r->exts, &tcindex_ext_map) < 0) 488 if (tcf_exts_dump(skb, &r->exts, &tcindex_ext_map) < 0)
488 goto rtattr_failure; 489 goto rtattr_failure;
489 rta->rta_len = skb->tail-b; 490 rta->rta_len = skb_tail_pointer(skb) - b;
490 491
491 if (tcf_exts_dump_stats(skb, &r->exts, &tcindex_ext_map) < 0) 492 if (tcf_exts_dump_stats(skb, &r->exts, &tcindex_ext_map) < 0)
492 goto rtattr_failure; 493 goto rtattr_failure;
@@ -495,7 +496,7 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
495 return skb->len; 496 return skb->len;
496 497
497rtattr_failure: 498rtattr_failure:
498 skb_trim(skb, b - skb->data); 499 nlmsg_trim(skb, b);
499 return -1; 500 return -1;
500} 501}
501 502
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 0bcb16928d25..c7a347bd6d70 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -50,6 +50,7 @@
50#include <linux/notifier.h> 50#include <linux/notifier.h>
51#include <linux/rtnetlink.h> 51#include <linux/rtnetlink.h>
52#include <net/ip.h> 52#include <net/ip.h>
53#include <net/netlink.h>
53#include <net/route.h> 54#include <net/route.h>
54#include <linux/skbuff.h> 55#include <linux/skbuff.h>
55#include <net/sock.h> 56#include <net/sock.h>
@@ -119,7 +120,7 @@ static int u32_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_re
119 } stack[TC_U32_MAXDEPTH]; 120 } stack[TC_U32_MAXDEPTH];
120 121
121 struct tc_u_hnode *ht = (struct tc_u_hnode*)tp->root; 122 struct tc_u_hnode *ht = (struct tc_u_hnode*)tp->root;
122 u8 *ptr = skb->nh.raw; 123 u8 *ptr = skb_network_header(skb);
123 struct tc_u_knode *n; 124 struct tc_u_knode *n;
124 int sdepth = 0; 125 int sdepth = 0;
125 int off2 = 0; 126 int off2 = 0;
@@ -213,7 +214,7 @@ check_terminal:
213 off2 = 0; 214 off2 = 0;
214 } 215 }
215 216
216 if (ptr < skb->tail) 217 if (ptr < skb_tail_pointer(skb))
217 goto next_ht; 218 goto next_ht;
218 } 219 }
219 220
@@ -435,7 +436,7 @@ static void u32_destroy(struct tcf_proto *tp)
435 BUG_TRAP(ht->refcnt == 0); 436 BUG_TRAP(ht->refcnt == 0);
436 437
437 kfree(ht); 438 kfree(ht);
438 }; 439 }
439 440
440 kfree(tp_c); 441 kfree(tp_c);
441 } 442 }
@@ -718,7 +719,7 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh,
718 struct sk_buff *skb, struct tcmsg *t) 719 struct sk_buff *skb, struct tcmsg *t)
719{ 720{
720 struct tc_u_knode *n = (struct tc_u_knode*)fh; 721 struct tc_u_knode *n = (struct tc_u_knode*)fh;
721 unsigned char *b = skb->tail; 722 unsigned char *b = skb_tail_pointer(skb);
722 struct rtattr *rta; 723 struct rtattr *rta;
723 724
724 if (n == NULL) 725 if (n == NULL)
@@ -765,14 +766,14 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh,
765#endif 766#endif
766 } 767 }
767 768
768 rta->rta_len = skb->tail - b; 769 rta->rta_len = skb_tail_pointer(skb) - b;
769 if (TC_U32_KEY(n->handle)) 770 if (TC_U32_KEY(n->handle))
770 if (tcf_exts_dump_stats(skb, &n->exts, &u32_ext_map) < 0) 771 if (tcf_exts_dump_stats(skb, &n->exts, &u32_ext_map) < 0)
771 goto rtattr_failure; 772 goto rtattr_failure;
772 return skb->len; 773 return skb->len;
773 774
774rtattr_failure: 775rtattr_failure:
775 skb_trim(skb, b - skb->data); 776 nlmsg_trim(skb, b);
776 return -1; 777 return -1;
777} 778}
778 779
diff --git a/net/sched/em_u32.c b/net/sched/em_u32.c
index cd0600c67969..0a2a7fe08de3 100644
--- a/net/sched/em_u32.c
+++ b/net/sched/em_u32.c
@@ -22,7 +22,7 @@ static int em_u32_match(struct sk_buff *skb, struct tcf_ematch *em,
22 struct tcf_pkt_info *info) 22 struct tcf_pkt_info *info)
23{ 23{
24 struct tc_u32_key *key = (struct tc_u32_key *) em->data; 24 struct tc_u32_key *key = (struct tc_u32_key *) em->data;
25 unsigned char *ptr = skb->nh.raw; 25 const unsigned char *ptr = skb_network_header(skb);
26 26
27 if (info) { 27 if (info) {
28 if (info->ptr) 28 if (info->ptr)
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index 959c306c5714..63146d339d81 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -418,17 +418,19 @@ void tcf_em_tree_destroy(struct tcf_proto *tp, struct tcf_ematch_tree *tree)
418int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv) 418int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv)
419{ 419{
420 int i; 420 int i;
421 struct rtattr * top_start = (struct rtattr*) skb->tail; 421 u8 *tail;
422 struct rtattr * list_start; 422 struct rtattr *top_start = (struct rtattr *)skb_tail_pointer(skb);
423 struct rtattr *list_start;
423 424
424 RTA_PUT(skb, tlv, 0, NULL); 425 RTA_PUT(skb, tlv, 0, NULL);
425 RTA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr); 426 RTA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr);
426 427
427 list_start = (struct rtattr *) skb->tail; 428 list_start = (struct rtattr *)skb_tail_pointer(skb);
428 RTA_PUT(skb, TCA_EMATCH_TREE_LIST, 0, NULL); 429 RTA_PUT(skb, TCA_EMATCH_TREE_LIST, 0, NULL);
429 430
431 tail = skb_tail_pointer(skb);
430 for (i = 0; i < tree->hdr.nmatches; i++) { 432 for (i = 0; i < tree->hdr.nmatches; i++) {
431 struct rtattr *match_start = (struct rtattr*) skb->tail; 433 struct rtattr *match_start = (struct rtattr *)tail;
432 struct tcf_ematch *em = tcf_em_get_match(tree, i); 434 struct tcf_ematch *em = tcf_em_get_match(tree, i);
433 struct tcf_ematch_hdr em_hdr = { 435 struct tcf_ematch_hdr em_hdr = {
434 .kind = em->ops ? em->ops->kind : TCF_EM_CONTAINER, 436 .kind = em->ops ? em->ops->kind : TCF_EM_CONTAINER,
@@ -447,11 +449,12 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv)
447 } else if (em->datalen > 0) 449 } else if (em->datalen > 0)
448 RTA_PUT_NOHDR(skb, em->datalen, (void *) em->data); 450 RTA_PUT_NOHDR(skb, em->datalen, (void *) em->data);
449 451
450 match_start->rta_len = skb->tail - (u8*) match_start; 452 tail = skb_tail_pointer(skb);
453 match_start->rta_len = tail - (u8 *)match_start;
451 } 454 }
452 455
453 list_start->rta_len = skb->tail - (u8 *) list_start; 456 list_start->rta_len = tail - (u8 *)list_start;
454 top_start->rta_len = skb->tail - (u8 *) top_start; 457 top_start->rta_len = tail - (u8 *)top_start;
455 458
456 return 0; 459 return 0;
457 460
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index ecc988af4a9a..8699e7006d80 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -27,14 +27,15 @@
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/netdevice.h> 28#include <linux/netdevice.h>
29#include <linux/skbuff.h> 29#include <linux/skbuff.h>
30#include <linux/rtnetlink.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/proc_fs.h> 31#include <linux/proc_fs.h>
33#include <linux/seq_file.h> 32#include <linux/seq_file.h>
34#include <linux/kmod.h> 33#include <linux/kmod.h>
35#include <linux/list.h> 34#include <linux/list.h>
36#include <linux/bitops.h> 35#include <linux/bitops.h>
36#include <linux/hrtimer.h>
37 37
38#include <net/netlink.h>
38#include <net/sock.h> 39#include <net/sock.h>
39#include <net/pkt_sched.h> 40#include <net/pkt_sched.h>
40 41
@@ -190,7 +191,7 @@ int unregister_qdisc(struct Qdisc_ops *qops)
190 (root qdisc, all its children, children of children etc.) 191 (root qdisc, all its children, children of children etc.)
191 */ 192 */
192 193
193static struct Qdisc *__qdisc_lookup(struct net_device *dev, u32 handle) 194struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
194{ 195{
195 struct Qdisc *q; 196 struct Qdisc *q;
196 197
@@ -201,16 +202,6 @@ static struct Qdisc *__qdisc_lookup(struct net_device *dev, u32 handle)
201 return NULL; 202 return NULL;
202} 203}
203 204
204struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
205{
206 struct Qdisc *q;
207
208 read_lock(&qdisc_tree_lock);
209 q = __qdisc_lookup(dev, handle);
210 read_unlock(&qdisc_tree_lock);
211 return q;
212}
213
214static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) 205static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
215{ 206{
216 unsigned long cl; 207 unsigned long cl;
@@ -291,6 +282,48 @@ void qdisc_put_rtab(struct qdisc_rate_table *tab)
291 } 282 }
292} 283}
293 284
285static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
286{
287 struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog,
288 timer);
289 struct net_device *dev = wd->qdisc->dev;
290
291 wd->qdisc->flags &= ~TCQ_F_THROTTLED;
292 smp_wmb();
293 if (spin_trylock(&dev->queue_lock)) {
294 qdisc_run(dev);
295 spin_unlock(&dev->queue_lock);
296 } else
297 netif_schedule(dev);
298
299 return HRTIMER_NORESTART;
300}
301
302void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc)
303{
304 hrtimer_init(&wd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
305 wd->timer.function = qdisc_watchdog;
306 wd->qdisc = qdisc;
307}
308EXPORT_SYMBOL(qdisc_watchdog_init);
309
310void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, psched_time_t expires)
311{
312 ktime_t time;
313
314 wd->qdisc->flags |= TCQ_F_THROTTLED;
315 time = ktime_set(0, 0);
316 time = ktime_add_ns(time, PSCHED_US2NS(expires));
317 hrtimer_start(&wd->timer, time, HRTIMER_MODE_ABS);
318}
319EXPORT_SYMBOL(qdisc_watchdog_schedule);
320
321void qdisc_watchdog_cancel(struct qdisc_watchdog *wd)
322{
323 hrtimer_cancel(&wd->timer);
324 wd->qdisc->flags &= ~TCQ_F_THROTTLED;
325}
326EXPORT_SYMBOL(qdisc_watchdog_cancel);
294 327
295/* Allocate an unique handle from space managed by kernel */ 328/* Allocate an unique handle from space managed by kernel */
296 329
@@ -362,7 +395,7 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
362 if (n == 0) 395 if (n == 0)
363 return; 396 return;
364 while ((parentid = sch->parent)) { 397 while ((parentid = sch->parent)) {
365 sch = __qdisc_lookup(sch->dev, TC_H_MAJ(parentid)); 398 sch = qdisc_lookup(sch->dev, TC_H_MAJ(parentid));
366 cops = sch->ops->cl_ops; 399 cops = sch->ops->cl_ops;
367 if (cops->qlen_notify) { 400 if (cops->qlen_notify) {
368 cl = cops->get(sch, parentid); 401 cl = cops->get(sch, parentid);
@@ -467,12 +500,16 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
467 500
468 if (handle == TC_H_INGRESS) { 501 if (handle == TC_H_INGRESS) {
469 sch->flags |= TCQ_F_INGRESS; 502 sch->flags |= TCQ_F_INGRESS;
503 sch->stats_lock = &dev->ingress_lock;
470 handle = TC_H_MAKE(TC_H_INGRESS, 0); 504 handle = TC_H_MAKE(TC_H_INGRESS, 0);
471 } else if (handle == 0) { 505 } else {
472 handle = qdisc_alloc_handle(dev); 506 sch->stats_lock = &dev->queue_lock;
473 err = -ENOMEM; 507 if (handle == 0) {
474 if (handle == 0) 508 handle = qdisc_alloc_handle(dev);
475 goto err_out3; 509 err = -ENOMEM;
510 if (handle == 0)
511 goto err_out3;
512 }
476 } 513 }
477 514
478 sch->handle = handle; 515 sch->handle = handle;
@@ -621,9 +658,9 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
621 return err; 658 return err;
622 if (q) { 659 if (q) {
623 qdisc_notify(skb, n, clid, q, NULL); 660 qdisc_notify(skb, n, clid, q, NULL);
624 spin_lock_bh(&dev->queue_lock); 661 qdisc_lock_tree(dev);
625 qdisc_destroy(q); 662 qdisc_destroy(q);
626 spin_unlock_bh(&dev->queue_lock); 663 qdisc_unlock_tree(dev);
627 } 664 }
628 } else { 665 } else {
629 qdisc_notify(skb, n, clid, NULL, q); 666 qdisc_notify(skb, n, clid, NULL, q);
@@ -756,17 +793,17 @@ graft:
756 err = qdisc_graft(dev, p, clid, q, &old_q); 793 err = qdisc_graft(dev, p, clid, q, &old_q);
757 if (err) { 794 if (err) {
758 if (q) { 795 if (q) {
759 spin_lock_bh(&dev->queue_lock); 796 qdisc_lock_tree(dev);
760 qdisc_destroy(q); 797 qdisc_destroy(q);
761 spin_unlock_bh(&dev->queue_lock); 798 qdisc_unlock_tree(dev);
762 } 799 }
763 return err; 800 return err;
764 } 801 }
765 qdisc_notify(skb, n, clid, old_q, q); 802 qdisc_notify(skb, n, clid, old_q, q);
766 if (old_q) { 803 if (old_q) {
767 spin_lock_bh(&dev->queue_lock); 804 qdisc_lock_tree(dev);
768 qdisc_destroy(old_q); 805 qdisc_destroy(old_q);
769 spin_unlock_bh(&dev->queue_lock); 806 qdisc_unlock_tree(dev);
770 } 807 }
771 } 808 }
772 return 0; 809 return 0;
@@ -777,7 +814,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
777{ 814{
778 struct tcmsg *tcm; 815 struct tcmsg *tcm;
779 struct nlmsghdr *nlh; 816 struct nlmsghdr *nlh;
780 unsigned char *b = skb->tail; 817 unsigned char *b = skb_tail_pointer(skb);
781 struct gnet_dump d; 818 struct gnet_dump d;
782 819
783 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); 820 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
@@ -811,12 +848,12 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
811 if (gnet_stats_finish_copy(&d) < 0) 848 if (gnet_stats_finish_copy(&d) < 0)
812 goto rtattr_failure; 849 goto rtattr_failure;
813 850
814 nlh->nlmsg_len = skb->tail - b; 851 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
815 return skb->len; 852 return skb->len;
816 853
817nlmsg_failure: 854nlmsg_failure:
818rtattr_failure: 855rtattr_failure:
819 skb_trim(skb, b - skb->data); 856 nlmsg_trim(skb, b);
820 return -1; 857 return -1;
821} 858}
822 859
@@ -862,7 +899,6 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
862 continue; 899 continue;
863 if (idx > s_idx) 900 if (idx > s_idx)
864 s_q_idx = 0; 901 s_q_idx = 0;
865 read_lock(&qdisc_tree_lock);
866 q_idx = 0; 902 q_idx = 0;
867 list_for_each_entry(q, &dev->qdisc_list, list) { 903 list_for_each_entry(q, &dev->qdisc_list, list) {
868 if (q_idx < s_q_idx) { 904 if (q_idx < s_q_idx) {
@@ -870,13 +906,10 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
870 continue; 906 continue;
871 } 907 }
872 if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid, 908 if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid,
873 cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) { 909 cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0)
874 read_unlock(&qdisc_tree_lock);
875 goto done; 910 goto done;
876 }
877 q_idx++; 911 q_idx++;
878 } 912 }
879 read_unlock(&qdisc_tree_lock);
880 } 913 }
881 914
882done: 915done:
@@ -1015,7 +1048,7 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
1015{ 1048{
1016 struct tcmsg *tcm; 1049 struct tcmsg *tcm;
1017 struct nlmsghdr *nlh; 1050 struct nlmsghdr *nlh;
1018 unsigned char *b = skb->tail; 1051 unsigned char *b = skb_tail_pointer(skb);
1019 struct gnet_dump d; 1052 struct gnet_dump d;
1020 struct Qdisc_class_ops *cl_ops = q->ops->cl_ops; 1053 struct Qdisc_class_ops *cl_ops = q->ops->cl_ops;
1021 1054
@@ -1040,12 +1073,12 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
1040 if (gnet_stats_finish_copy(&d) < 0) 1073 if (gnet_stats_finish_copy(&d) < 0)
1041 goto rtattr_failure; 1074 goto rtattr_failure;
1042 1075
1043 nlh->nlmsg_len = skb->tail - b; 1076 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1044 return skb->len; 1077 return skb->len;
1045 1078
1046nlmsg_failure: 1079nlmsg_failure:
1047rtattr_failure: 1080rtattr_failure:
1048 skb_trim(skb, b - skb->data); 1081 nlmsg_trim(skb, b);
1049 return -1; 1082 return -1;
1050} 1083}
1051 1084
@@ -1099,7 +1132,6 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1099 s_t = cb->args[0]; 1132 s_t = cb->args[0];
1100 t = 0; 1133 t = 0;
1101 1134
1102 read_lock(&qdisc_tree_lock);
1103 list_for_each_entry(q, &dev->qdisc_list, list) { 1135 list_for_each_entry(q, &dev->qdisc_list, list) {
1104 if (t < s_t || !q->ops->cl_ops || 1136 if (t < s_t || !q->ops->cl_ops ||
1105 (tcm->tcm_parent && 1137 (tcm->tcm_parent &&
@@ -1121,7 +1153,6 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1121 break; 1153 break;
1122 t++; 1154 t++;
1123 } 1155 }
1124 read_unlock(&qdisc_tree_lock);
1125 1156
1126 cb->args[0] = t; 1157 cb->args[0] = t;
1127 1158
@@ -1146,7 +1177,7 @@ reclassify:
1146 1177
1147 for ( ; tp; tp = tp->next) { 1178 for ( ; tp; tp = tp->next) {
1148 if ((tp->protocol == protocol || 1179 if ((tp->protocol == protocol ||
1149 tp->protocol == __constant_htons(ETH_P_ALL)) && 1180 tp->protocol == htons(ETH_P_ALL)) &&
1150 (err = tp->classify(skb, tp, res)) >= 0) { 1181 (err = tp->classify(skb, tp, res)) >= 0) {
1151#ifdef CONFIG_NET_CLS_ACT 1182#ifdef CONFIG_NET_CLS_ACT
1152 if ( TC_ACT_RECLASSIFY == err) { 1183 if ( TC_ACT_RECLASSIFY == err) {
@@ -1175,15 +1206,31 @@ reclassify:
1175 return -1; 1206 return -1;
1176} 1207}
1177 1208
1178static int psched_us_per_tick = 1; 1209void tcf_destroy(struct tcf_proto *tp)
1179static int psched_tick_per_us = 1; 1210{
1211 tp->ops->destroy(tp);
1212 module_put(tp->ops->owner);
1213 kfree(tp);
1214}
1215
1216void tcf_destroy_chain(struct tcf_proto *fl)
1217{
1218 struct tcf_proto *tp;
1219
1220 while ((tp = fl) != NULL) {
1221 fl = tp->next;
1222 tcf_destroy(tp);
1223 }
1224}
1225EXPORT_SYMBOL(tcf_destroy_chain);
1180 1226
1181#ifdef CONFIG_PROC_FS 1227#ifdef CONFIG_PROC_FS
1182static int psched_show(struct seq_file *seq, void *v) 1228static int psched_show(struct seq_file *seq, void *v)
1183{ 1229{
1184 seq_printf(seq, "%08x %08x %08x %08x\n", 1230 seq_printf(seq, "%08x %08x %08x %08x\n",
1185 psched_tick_per_us, psched_us_per_tick, 1231 (u32)NSEC_PER_USEC, (u32)PSCHED_US2NS(1),
1186 1000000, HZ); 1232 1000000,
1233 (u32)NSEC_PER_SEC/(u32)ktime_to_ns(KTIME_MONOTONIC_RES));
1187 1234
1188 return 0; 1235 return 0;
1189} 1236}
@@ -1202,101 +1249,19 @@ static const struct file_operations psched_fops = {
1202}; 1249};
1203#endif 1250#endif
1204 1251
1205#ifdef CONFIG_NET_SCH_CLK_CPU
1206psched_tdiff_t psched_clock_per_hz;
1207int psched_clock_scale;
1208EXPORT_SYMBOL(psched_clock_per_hz);
1209EXPORT_SYMBOL(psched_clock_scale);
1210
1211psched_time_t psched_time_base;
1212cycles_t psched_time_mark;
1213EXPORT_SYMBOL(psched_time_mark);
1214EXPORT_SYMBOL(psched_time_base);
1215
1216/*
1217 * Periodically adjust psched_time_base to avoid overflow
1218 * with 32-bit get_cycles(). Safe up to 4GHz CPU.
1219 */
1220static void psched_tick(unsigned long);
1221static DEFINE_TIMER(psched_timer, psched_tick, 0, 0);
1222
1223static void psched_tick(unsigned long dummy)
1224{
1225 if (sizeof(cycles_t) == sizeof(u32)) {
1226 psched_time_t dummy_stamp;
1227 PSCHED_GET_TIME(dummy_stamp);
1228 psched_timer.expires = jiffies + 1*HZ;
1229 add_timer(&psched_timer);
1230 }
1231}
1232
1233int __init psched_calibrate_clock(void)
1234{
1235 psched_time_t stamp, stamp1;
1236 struct timeval tv, tv1;
1237 psched_tdiff_t delay;
1238 long rdelay;
1239 unsigned long stop;
1240
1241 psched_tick(0);
1242 stop = jiffies + HZ/10;
1243 PSCHED_GET_TIME(stamp);
1244 do_gettimeofday(&tv);
1245 while (time_before(jiffies, stop)) {
1246 barrier();
1247 cpu_relax();
1248 }
1249 PSCHED_GET_TIME(stamp1);
1250 do_gettimeofday(&tv1);
1251
1252 delay = PSCHED_TDIFF(stamp1, stamp);
1253 rdelay = tv1.tv_usec - tv.tv_usec;
1254 rdelay += (tv1.tv_sec - tv.tv_sec)*1000000;
1255 if (rdelay > delay)
1256 return -1;
1257 delay /= rdelay;
1258 psched_tick_per_us = delay;
1259 while ((delay>>=1) != 0)
1260 psched_clock_scale++;
1261 psched_us_per_tick = 1<<psched_clock_scale;
1262 psched_clock_per_hz = (psched_tick_per_us*(1000000/HZ))>>psched_clock_scale;
1263 return 0;
1264}
1265#endif
1266
1267static int __init pktsched_init(void) 1252static int __init pktsched_init(void)
1268{ 1253{
1269 struct rtnetlink_link *link_p;
1270
1271#ifdef CONFIG_NET_SCH_CLK_CPU
1272 if (psched_calibrate_clock() < 0)
1273 return -1;
1274#elif defined(CONFIG_NET_SCH_CLK_JIFFIES)
1275 psched_tick_per_us = HZ<<PSCHED_JSCALE;
1276 psched_us_per_tick = 1000000;
1277#endif
1278
1279 link_p = rtnetlink_links[PF_UNSPEC];
1280
1281 /* Setup rtnetlink links. It is made here to avoid
1282 exporting large number of public symbols.
1283 */
1284
1285 if (link_p) {
1286 link_p[RTM_NEWQDISC-RTM_BASE].doit = tc_modify_qdisc;
1287 link_p[RTM_DELQDISC-RTM_BASE].doit = tc_get_qdisc;
1288 link_p[RTM_GETQDISC-RTM_BASE].doit = tc_get_qdisc;
1289 link_p[RTM_GETQDISC-RTM_BASE].dumpit = tc_dump_qdisc;
1290 link_p[RTM_NEWTCLASS-RTM_BASE].doit = tc_ctl_tclass;
1291 link_p[RTM_DELTCLASS-RTM_BASE].doit = tc_ctl_tclass;
1292 link_p[RTM_GETTCLASS-RTM_BASE].doit = tc_ctl_tclass;
1293 link_p[RTM_GETTCLASS-RTM_BASE].dumpit = tc_dump_tclass;
1294 }
1295
1296 register_qdisc(&pfifo_qdisc_ops); 1254 register_qdisc(&pfifo_qdisc_ops);
1297 register_qdisc(&bfifo_qdisc_ops); 1255 register_qdisc(&bfifo_qdisc_ops);
1298 proc_net_fops_create("psched", 0, &psched_fops); 1256 proc_net_fops_create("psched", 0, &psched_fops);
1299 1257
1258 rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL);
1259 rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL);
1260 rtnl_register(PF_UNSPEC, RTM_GETQDISC, tc_get_qdisc, tc_dump_qdisc);
1261 rtnl_register(PF_UNSPEC, RTM_NEWTCLASS, tc_ctl_tclass, NULL);
1262 rtnl_register(PF_UNSPEC, RTM_DELTCLASS, tc_ctl_tclass, NULL);
1263 rtnl_register(PF_UNSPEC, RTM_GETTCLASS, tc_ctl_tclass, tc_dump_tclass);
1264
1300 return 0; 1265 return 0;
1301} 1266}
1302 1267
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index afb3bbd571f2..be7d299acd73 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -14,6 +14,7 @@
14#include <linux/netdevice.h> 14#include <linux/netdevice.h>
15#include <linux/rtnetlink.h> 15#include <linux/rtnetlink.h>
16#include <linux/file.h> /* for fput */ 16#include <linux/file.h> /* for fput */
17#include <net/netlink.h>
17#include <net/pkt_sched.h> 18#include <net/pkt_sched.h>
18#include <net/sock.h> 19#include <net/sock.h>
19 20
@@ -157,19 +158,6 @@ static unsigned long atm_tc_bind_filter(struct Qdisc *sch,
157 return atm_tc_get(sch,classid); 158 return atm_tc_get(sch,classid);
158} 159}
159 160
160
161static void destroy_filters(struct atm_flow_data *flow)
162{
163 struct tcf_proto *filter;
164
165 while ((filter = flow->filter_list)) {
166 DPRINTK("destroy_filters: destroying filter %p\n",filter);
167 flow->filter_list = filter->next;
168 tcf_destroy(filter);
169 }
170}
171
172
173/* 161/*
174 * atm_tc_put handles all destructions, including the ones that are explicitly 162 * atm_tc_put handles all destructions, including the ones that are explicitly
175 * requested (atm_tc_destroy, etc.). The assumption here is that we never drop 163 * requested (atm_tc_destroy, etc.). The assumption here is that we never drop
@@ -194,7 +182,7 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
194 *prev = flow->next; 182 *prev = flow->next;
195 DPRINTK("atm_tc_put: qdisc %p\n",flow->q); 183 DPRINTK("atm_tc_put: qdisc %p\n",flow->q);
196 qdisc_destroy(flow->q); 184 qdisc_destroy(flow->q);
197 destroy_filters(flow); 185 tcf_destroy_chain(flow->filter_list);
198 if (flow->sock) { 186 if (flow->sock) {
199 DPRINTK("atm_tc_put: f_count %d\n", 187 DPRINTK("atm_tc_put: f_count %d\n",
200 file_count(flow->sock->file)); 188 file_count(flow->sock->file));
@@ -503,7 +491,7 @@ static void sch_atm_dequeue(unsigned long data)
503 } 491 }
504 D2PRINTK("atm_tc_dequeue: sending on class %p\n",flow); 492 D2PRINTK("atm_tc_dequeue: sending on class %p\n",flow);
505 /* remove any LL header somebody else has attached */ 493 /* remove any LL header somebody else has attached */
506 skb_pull(skb,(char *) skb->nh.iph-(char *) skb->data); 494 skb_pull(skb, skb_network_offset(skb));
507 if (skb_headroom(skb) < flow->hdr_len) { 495 if (skb_headroom(skb) < flow->hdr_len) {
508 struct sk_buff *new; 496 struct sk_buff *new;
509 497
@@ -513,7 +501,7 @@ static void sch_atm_dequeue(unsigned long data)
513 skb = new; 501 skb = new;
514 } 502 }
515 D2PRINTK("sch_atm_dequeue: ip %p, data %p\n", 503 D2PRINTK("sch_atm_dequeue: ip %p, data %p\n",
516 skb->nh.iph,skb->data); 504 skb_network_header(skb), skb->data);
517 ATM_SKB(skb)->vcc = flow->vcc; 505 ATM_SKB(skb)->vcc = flow->vcc;
518 memcpy(skb_push(skb,flow->hdr_len),flow->hdr, 506 memcpy(skb_push(skb,flow->hdr_len),flow->hdr,
519 flow->hdr_len); 507 flow->hdr_len);
@@ -610,7 +598,7 @@ static void atm_tc_destroy(struct Qdisc *sch)
610 DPRINTK("atm_tc_destroy(sch %p,[qdisc %p])\n",sch,p); 598 DPRINTK("atm_tc_destroy(sch %p,[qdisc %p])\n",sch,p);
611 /* races ? */ 599 /* races ? */
612 while ((flow = p->flows)) { 600 while ((flow = p->flows)) {
613 destroy_filters(flow); 601 tcf_destroy_chain(flow->filter_list);
614 if (flow->ref > 1) 602 if (flow->ref > 1)
615 printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow, 603 printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow,
616 flow->ref); 604 flow->ref);
@@ -631,7 +619,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
631{ 619{
632 struct atm_qdisc_data *p = PRIV(sch); 620 struct atm_qdisc_data *p = PRIV(sch);
633 struct atm_flow_data *flow = (struct atm_flow_data *) cl; 621 struct atm_flow_data *flow = (struct atm_flow_data *) cl;
634 unsigned char *b = skb->tail; 622 unsigned char *b = skb_tail_pointer(skb);
635 struct rtattr *rta; 623 struct rtattr *rta;
636 624
637 DPRINTK("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n", 625 DPRINTK("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n",
@@ -661,11 +649,11 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
661 649
662 RTA_PUT(skb,TCA_ATM_EXCESS,sizeof(zero),&zero); 650 RTA_PUT(skb,TCA_ATM_EXCESS,sizeof(zero),&zero);
663 } 651 }
664 rta->rta_len = skb->tail-b; 652 rta->rta_len = skb_tail_pointer(skb) - b;
665 return skb->len; 653 return skb->len;
666 654
667rtattr_failure: 655rtattr_failure:
668 skb_trim(skb,b-skb->data); 656 nlmsg_trim(skb, b);
669 return -1; 657 return -1;
670} 658}
671static int 659static int
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 76c92e710a33..a294542cb8e4 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -29,6 +29,7 @@
29#include <linux/etherdevice.h> 29#include <linux/etherdevice.h>
30#include <linux/notifier.h> 30#include <linux/notifier.h>
31#include <net/ip.h> 31#include <net/ip.h>
32#include <net/netlink.h>
32#include <net/route.h> 33#include <net/route.h>
33#include <linux/skbuff.h> 34#include <linux/skbuff.h>
34#include <net/sock.h> 35#include <net/sock.h>
@@ -112,7 +113,7 @@ struct cbq_class
112 113
113 /* Overlimit strategy parameters */ 114 /* Overlimit strategy parameters */
114 void (*overlimit)(struct cbq_class *cl); 115 void (*overlimit)(struct cbq_class *cl);
115 long penalty; 116 psched_tdiff_t penalty;
116 117
117 /* General scheduler (WRR) parameters */ 118 /* General scheduler (WRR) parameters */
118 long allot; 119 long allot;
@@ -143,7 +144,7 @@ struct cbq_class
143 psched_time_t undertime; 144 psched_time_t undertime;
144 long avgidle; 145 long avgidle;
145 long deficit; /* Saved deficit for WRR */ 146 long deficit; /* Saved deficit for WRR */
146 unsigned long penalized; 147 psched_time_t penalized;
147 struct gnet_stats_basic bstats; 148 struct gnet_stats_basic bstats;
148 struct gnet_stats_queue qstats; 149 struct gnet_stats_queue qstats;
149 struct gnet_stats_rate_est rate_est; 150 struct gnet_stats_rate_est rate_est;
@@ -180,12 +181,12 @@ struct cbq_sched_data
180 psched_time_t now_rt; /* Cached real time */ 181 psched_time_t now_rt; /* Cached real time */
181 unsigned pmask; 182 unsigned pmask;
182 183
183 struct timer_list delay_timer; 184 struct hrtimer delay_timer;
184 struct timer_list wd_timer; /* Watchdog timer, 185 struct qdisc_watchdog watchdog; /* Watchdog timer,
185 started when CBQ has 186 started when CBQ has
186 backlog, but cannot 187 backlog, but cannot
187 transmit just now */ 188 transmit just now */
188 long wd_expires; 189 psched_tdiff_t wd_expires;
189 int toplevel; 190 int toplevel;
190 u32 hgenerator; 191 u32 hgenerator;
191}; 192};
@@ -384,12 +385,12 @@ cbq_mark_toplevel(struct cbq_sched_data *q, struct cbq_class *cl)
384 psched_time_t now; 385 psched_time_t now;
385 psched_tdiff_t incr; 386 psched_tdiff_t incr;
386 387
387 PSCHED_GET_TIME(now); 388 now = psched_get_time();
388 incr = PSCHED_TDIFF(now, q->now_rt); 389 incr = now - q->now_rt;
389 PSCHED_TADD2(q->now, incr, now); 390 now = q->now + incr;
390 391
391 do { 392 do {
392 if (PSCHED_TLESS(cl->undertime, now)) { 393 if (cl->undertime < now) {
393 q->toplevel = cl->level; 394 q->toplevel = cl->level;
394 return; 395 return;
395 } 396 }
@@ -473,7 +474,7 @@ cbq_requeue(struct sk_buff *skb, struct Qdisc *sch)
473static void cbq_ovl_classic(struct cbq_class *cl) 474static void cbq_ovl_classic(struct cbq_class *cl)
474{ 475{
475 struct cbq_sched_data *q = qdisc_priv(cl->qdisc); 476 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
476 psched_tdiff_t delay = PSCHED_TDIFF(cl->undertime, q->now); 477 psched_tdiff_t delay = cl->undertime - q->now;
477 478
478 if (!cl->delayed) { 479 if (!cl->delayed) {
479 delay += cl->offtime; 480 delay += cl->offtime;
@@ -491,7 +492,7 @@ static void cbq_ovl_classic(struct cbq_class *cl)
491 cl->avgidle = cl->minidle; 492 cl->avgidle = cl->minidle;
492 if (delay <= 0) 493 if (delay <= 0)
493 delay = 1; 494 delay = 1;
494 PSCHED_TADD2(q->now, delay, cl->undertime); 495 cl->undertime = q->now + delay;
495 496
496 cl->xstats.overactions++; 497 cl->xstats.overactions++;
497 cl->delayed = 1; 498 cl->delayed = 1;
@@ -508,7 +509,7 @@ static void cbq_ovl_classic(struct cbq_class *cl)
508 psched_tdiff_t base_delay = q->wd_expires; 509 psched_tdiff_t base_delay = q->wd_expires;
509 510
510 for (b = cl->borrow; b; b = b->borrow) { 511 for (b = cl->borrow; b; b = b->borrow) {
511 delay = PSCHED_TDIFF(b->undertime, q->now); 512 delay = b->undertime - q->now;
512 if (delay < base_delay) { 513 if (delay < base_delay) {
513 if (delay <= 0) 514 if (delay <= 0)
514 delay = 1; 515 delay = 1;
@@ -546,27 +547,32 @@ static void cbq_ovl_rclassic(struct cbq_class *cl)
546static void cbq_ovl_delay(struct cbq_class *cl) 547static void cbq_ovl_delay(struct cbq_class *cl)
547{ 548{
548 struct cbq_sched_data *q = qdisc_priv(cl->qdisc); 549 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
549 psched_tdiff_t delay = PSCHED_TDIFF(cl->undertime, q->now); 550 psched_tdiff_t delay = cl->undertime - q->now;
550 551
551 if (!cl->delayed) { 552 if (!cl->delayed) {
552 unsigned long sched = jiffies; 553 psched_time_t sched = q->now;
554 ktime_t expires;
553 555
554 delay += cl->offtime; 556 delay += cl->offtime;
555 if (cl->avgidle < 0) 557 if (cl->avgidle < 0)
556 delay -= (-cl->avgidle) - ((-cl->avgidle) >> cl->ewma_log); 558 delay -= (-cl->avgidle) - ((-cl->avgidle) >> cl->ewma_log);
557 if (cl->avgidle < cl->minidle) 559 if (cl->avgidle < cl->minidle)
558 cl->avgidle = cl->minidle; 560 cl->avgidle = cl->minidle;
559 PSCHED_TADD2(q->now, delay, cl->undertime); 561 cl->undertime = q->now + delay;
560 562
561 if (delay > 0) { 563 if (delay > 0) {
562 sched += PSCHED_US2JIFFIE(delay) + cl->penalty; 564 sched += delay + cl->penalty;
563 cl->penalized = sched; 565 cl->penalized = sched;
564 cl->cpriority = TC_CBQ_MAXPRIO; 566 cl->cpriority = TC_CBQ_MAXPRIO;
565 q->pmask |= (1<<TC_CBQ_MAXPRIO); 567 q->pmask |= (1<<TC_CBQ_MAXPRIO);
566 if (del_timer(&q->delay_timer) && 568
567 (long)(q->delay_timer.expires - sched) > 0) 569 expires = ktime_set(0, 0);
568 q->delay_timer.expires = sched; 570 expires = ktime_add_ns(expires, PSCHED_US2NS(sched));
569 add_timer(&q->delay_timer); 571 if (hrtimer_try_to_cancel(&q->delay_timer) &&
572 ktime_to_ns(ktime_sub(q->delay_timer.expires,
573 expires)) > 0)
574 q->delay_timer.expires = expires;
575 hrtimer_restart(&q->delay_timer);
570 cl->delayed = 1; 576 cl->delayed = 1;
571 cl->xstats.overactions++; 577 cl->xstats.overactions++;
572 return; 578 return;
@@ -583,7 +589,7 @@ static void cbq_ovl_lowprio(struct cbq_class *cl)
583{ 589{
584 struct cbq_sched_data *q = qdisc_priv(cl->qdisc); 590 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
585 591
586 cl->penalized = jiffies + cl->penalty; 592 cl->penalized = q->now + cl->penalty;
587 593
588 if (cl->cpriority != cl->priority2) { 594 if (cl->cpriority != cl->priority2) {
589 cl->cpriority = cl->priority2; 595 cl->cpriority = cl->priority2;
@@ -604,27 +610,19 @@ static void cbq_ovl_drop(struct cbq_class *cl)
604 cbq_ovl_classic(cl); 610 cbq_ovl_classic(cl);
605} 611}
606 612
607static void cbq_watchdog(unsigned long arg) 613static psched_tdiff_t cbq_undelay_prio(struct cbq_sched_data *q, int prio,
608{ 614 psched_time_t now)
609 struct Qdisc *sch = (struct Qdisc*)arg;
610
611 sch->flags &= ~TCQ_F_THROTTLED;
612 netif_schedule(sch->dev);
613}
614
615static unsigned long cbq_undelay_prio(struct cbq_sched_data *q, int prio)
616{ 615{
617 struct cbq_class *cl; 616 struct cbq_class *cl;
618 struct cbq_class *cl_prev = q->active[prio]; 617 struct cbq_class *cl_prev = q->active[prio];
619 unsigned long now = jiffies; 618 psched_time_t sched = now;
620 unsigned long sched = now;
621 619
622 if (cl_prev == NULL) 620 if (cl_prev == NULL)
623 return now; 621 return 0;
624 622
625 do { 623 do {
626 cl = cl_prev->next_alive; 624 cl = cl_prev->next_alive;
627 if ((long)(now - cl->penalized) > 0) { 625 if (now - cl->penalized > 0) {
628 cl_prev->next_alive = cl->next_alive; 626 cl_prev->next_alive = cl->next_alive;
629 cl->next_alive = NULL; 627 cl->next_alive = NULL;
630 cl->cpriority = cl->priority; 628 cl->cpriority = cl->priority;
@@ -640,30 +638,34 @@ static unsigned long cbq_undelay_prio(struct cbq_sched_data *q, int prio)
640 } 638 }
641 639
642 cl = cl_prev->next_alive; 640 cl = cl_prev->next_alive;
643 } else if ((long)(sched - cl->penalized) > 0) 641 } else if (sched - cl->penalized > 0)
644 sched = cl->penalized; 642 sched = cl->penalized;
645 } while ((cl_prev = cl) != q->active[prio]); 643 } while ((cl_prev = cl) != q->active[prio]);
646 644
647 return (long)(sched - now); 645 return sched - now;
648} 646}
649 647
650static void cbq_undelay(unsigned long arg) 648static enum hrtimer_restart cbq_undelay(struct hrtimer *timer)
651{ 649{
652 struct Qdisc *sch = (struct Qdisc*)arg; 650 struct cbq_sched_data *q = container_of(timer, struct cbq_sched_data,
653 struct cbq_sched_data *q = qdisc_priv(sch); 651 delay_timer);
654 long delay = 0; 652 struct Qdisc *sch = q->watchdog.qdisc;
653 psched_time_t now;
654 psched_tdiff_t delay = 0;
655 unsigned pmask; 655 unsigned pmask;
656 656
657 now = psched_get_time();
658
657 pmask = q->pmask; 659 pmask = q->pmask;
658 q->pmask = 0; 660 q->pmask = 0;
659 661
660 while (pmask) { 662 while (pmask) {
661 int prio = ffz(~pmask); 663 int prio = ffz(~pmask);
662 long tmp; 664 psched_tdiff_t tmp;
663 665
664 pmask &= ~(1<<prio); 666 pmask &= ~(1<<prio);
665 667
666 tmp = cbq_undelay_prio(q, prio); 668 tmp = cbq_undelay_prio(q, prio, now);
667 if (tmp > 0) { 669 if (tmp > 0) {
668 q->pmask |= 1<<prio; 670 q->pmask |= 1<<prio;
669 if (tmp < delay || delay == 0) 671 if (tmp < delay || delay == 0)
@@ -672,12 +674,16 @@ static void cbq_undelay(unsigned long arg)
672 } 674 }
673 675
674 if (delay) { 676 if (delay) {
675 q->delay_timer.expires = jiffies + delay; 677 ktime_t time;
676 add_timer(&q->delay_timer); 678
679 time = ktime_set(0, 0);
680 time = ktime_add_ns(time, PSCHED_US2NS(now + delay));
681 hrtimer_start(&q->delay_timer, time, HRTIMER_MODE_ABS);
677 } 682 }
678 683
679 sch->flags &= ~TCQ_F_THROTTLED; 684 sch->flags &= ~TCQ_F_THROTTLED;
680 netif_schedule(sch->dev); 685 netif_schedule(sch->dev);
686 return HRTIMER_NORESTART;
681} 687}
682 688
683 689
@@ -732,7 +738,7 @@ cbq_update_toplevel(struct cbq_sched_data *q, struct cbq_class *cl,
732 if (cl && q->toplevel >= borrowed->level) { 738 if (cl && q->toplevel >= borrowed->level) {
733 if (cl->q->q.qlen > 1) { 739 if (cl->q->q.qlen > 1) {
734 do { 740 do {
735 if (PSCHED_IS_PASTPERFECT(borrowed->undertime)) { 741 if (borrowed->undertime == PSCHED_PASTPERFECT) {
736 q->toplevel = borrowed->level; 742 q->toplevel = borrowed->level;
737 return; 743 return;
738 } 744 }
@@ -770,7 +776,7 @@ cbq_update(struct cbq_sched_data *q)
770 idle = (now - last) - last_pktlen/rate 776 idle = (now - last) - last_pktlen/rate
771 */ 777 */
772 778
773 idle = PSCHED_TDIFF(q->now, cl->last); 779 idle = q->now - cl->last;
774 if ((unsigned long)idle > 128*1024*1024) { 780 if ((unsigned long)idle > 128*1024*1024) {
775 avgidle = cl->maxidle; 781 avgidle = cl->maxidle;
776 } else { 782 } else {
@@ -814,13 +820,11 @@ cbq_update(struct cbq_sched_data *q)
814 idle -= L2T(&q->link, len); 820 idle -= L2T(&q->link, len);
815 idle += L2T(cl, len); 821 idle += L2T(cl, len);
816 822
817 PSCHED_AUDIT_TDIFF(idle); 823 cl->undertime = q->now + idle;
818
819 PSCHED_TADD2(q->now, idle, cl->undertime);
820 } else { 824 } else {
821 /* Underlimit */ 825 /* Underlimit */
822 826
823 PSCHED_SET_PASTPERFECT(cl->undertime); 827 cl->undertime = PSCHED_PASTPERFECT;
824 if (avgidle > cl->maxidle) 828 if (avgidle > cl->maxidle)
825 cl->avgidle = cl->maxidle; 829 cl->avgidle = cl->maxidle;
826 else 830 else
@@ -841,8 +845,7 @@ cbq_under_limit(struct cbq_class *cl)
841 if (cl->tparent == NULL) 845 if (cl->tparent == NULL)
842 return cl; 846 return cl;
843 847
844 if (PSCHED_IS_PASTPERFECT(cl->undertime) || 848 if (cl->undertime == PSCHED_PASTPERFECT || q->now >= cl->undertime) {
845 !PSCHED_TLESS(q->now, cl->undertime)) {
846 cl->delayed = 0; 849 cl->delayed = 0;
847 return cl; 850 return cl;
848 } 851 }
@@ -865,8 +868,7 @@ cbq_under_limit(struct cbq_class *cl)
865 } 868 }
866 if (cl->level > q->toplevel) 869 if (cl->level > q->toplevel)
867 return NULL; 870 return NULL;
868 } while (!PSCHED_IS_PASTPERFECT(cl->undertime) && 871 } while (cl->undertime != PSCHED_PASTPERFECT && q->now < cl->undertime);
869 PSCHED_TLESS(q->now, cl->undertime));
870 872
871 cl->delayed = 0; 873 cl->delayed = 0;
872 return cl; 874 return cl;
@@ -1001,8 +1003,8 @@ cbq_dequeue(struct Qdisc *sch)
1001 psched_time_t now; 1003 psched_time_t now;
1002 psched_tdiff_t incr; 1004 psched_tdiff_t incr;
1003 1005
1004 PSCHED_GET_TIME(now); 1006 now = psched_get_time();
1005 incr = PSCHED_TDIFF(now, q->now_rt); 1007 incr = now - q->now_rt;
1006 1008
1007 if (q->tx_class) { 1009 if (q->tx_class) {
1008 psched_tdiff_t incr2; 1010 psched_tdiff_t incr2;
@@ -1014,12 +1016,12 @@ cbq_dequeue(struct Qdisc *sch)
1014 cbq_time = max(real_time, work); 1016 cbq_time = max(real_time, work);
1015 */ 1017 */
1016 incr2 = L2T(&q->link, q->tx_len); 1018 incr2 = L2T(&q->link, q->tx_len);
1017 PSCHED_TADD(q->now, incr2); 1019 q->now += incr2;
1018 cbq_update(q); 1020 cbq_update(q);
1019 if ((incr -= incr2) < 0) 1021 if ((incr -= incr2) < 0)
1020 incr = 0; 1022 incr = 0;
1021 } 1023 }
1022 PSCHED_TADD(q->now, incr); 1024 q->now += incr;
1023 q->now_rt = now; 1025 q->now_rt = now;
1024 1026
1025 for (;;) { 1027 for (;;) {
@@ -1051,11 +1053,11 @@ cbq_dequeue(struct Qdisc *sch)
1051 */ 1053 */
1052 1054
1053 if (q->toplevel == TC_CBQ_MAXLEVEL && 1055 if (q->toplevel == TC_CBQ_MAXLEVEL &&
1054 PSCHED_IS_PASTPERFECT(q->link.undertime)) 1056 q->link.undertime == PSCHED_PASTPERFECT)
1055 break; 1057 break;
1056 1058
1057 q->toplevel = TC_CBQ_MAXLEVEL; 1059 q->toplevel = TC_CBQ_MAXLEVEL;
1058 PSCHED_SET_PASTPERFECT(q->link.undertime); 1060 q->link.undertime = PSCHED_PASTPERFECT;
1059 } 1061 }
1060 1062
1061 /* No packets in scheduler or nobody wants to give them to us :-( 1063 /* No packets in scheduler or nobody wants to give them to us :-(
@@ -1063,13 +1065,9 @@ cbq_dequeue(struct Qdisc *sch)
1063 1065
1064 if (sch->q.qlen) { 1066 if (sch->q.qlen) {
1065 sch->qstats.overlimits++; 1067 sch->qstats.overlimits++;
1066 if (q->wd_expires) { 1068 if (q->wd_expires)
1067 long delay = PSCHED_US2JIFFIE(q->wd_expires); 1069 qdisc_watchdog_schedule(&q->watchdog,
1068 if (delay <= 0) 1070 now + q->wd_expires);
1069 delay = 1;
1070 mod_timer(&q->wd_timer, jiffies + delay);
1071 sch->flags |= TCQ_F_THROTTLED;
1072 }
1073 } 1071 }
1074 return NULL; 1072 return NULL;
1075} 1073}
@@ -1276,10 +1274,10 @@ cbq_reset(struct Qdisc* sch)
1276 q->pmask = 0; 1274 q->pmask = 0;
1277 q->tx_class = NULL; 1275 q->tx_class = NULL;
1278 q->tx_borrowed = NULL; 1276 q->tx_borrowed = NULL;
1279 del_timer(&q->wd_timer); 1277 qdisc_watchdog_cancel(&q->watchdog);
1280 del_timer(&q->delay_timer); 1278 hrtimer_cancel(&q->delay_timer);
1281 q->toplevel = TC_CBQ_MAXLEVEL; 1279 q->toplevel = TC_CBQ_MAXLEVEL;
1282 PSCHED_GET_TIME(q->now); 1280 q->now = psched_get_time();
1283 q->now_rt = q->now; 1281 q->now_rt = q->now;
1284 1282
1285 for (prio = 0; prio <= TC_CBQ_MAXPRIO; prio++) 1283 for (prio = 0; prio <= TC_CBQ_MAXPRIO; prio++)
@@ -1290,7 +1288,7 @@ cbq_reset(struct Qdisc* sch)
1290 qdisc_reset(cl->q); 1288 qdisc_reset(cl->q);
1291 1289
1292 cl->next_alive = NULL; 1290 cl->next_alive = NULL;
1293 PSCHED_SET_PASTPERFECT(cl->undertime); 1291 cl->undertime = PSCHED_PASTPERFECT;
1294 cl->avgidle = cl->maxidle; 1292 cl->avgidle = cl->maxidle;
1295 cl->deficit = cl->quantum; 1293 cl->deficit = cl->quantum;
1296 cl->cpriority = cl->priority; 1294 cl->cpriority = cl->priority;
@@ -1379,7 +1377,7 @@ static int cbq_set_overlimit(struct cbq_class *cl, struct tc_cbq_ovl *ovl)
1379 default: 1377 default:
1380 return -EINVAL; 1378 return -EINVAL;
1381 } 1379 }
1382 cl->penalty = (ovl->penalty*HZ)/1000; 1380 cl->penalty = ovl->penalty;
1383 return 0; 1381 return 0;
1384} 1382}
1385 1383
@@ -1446,14 +1444,11 @@ static int cbq_init(struct Qdisc *sch, struct rtattr *opt)
1446 q->link.minidle = -0x7FFFFFFF; 1444 q->link.minidle = -0x7FFFFFFF;
1447 q->link.stats_lock = &sch->dev->queue_lock; 1445 q->link.stats_lock = &sch->dev->queue_lock;
1448 1446
1449 init_timer(&q->wd_timer); 1447 qdisc_watchdog_init(&q->watchdog, sch);
1450 q->wd_timer.data = (unsigned long)sch; 1448 hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1451 q->wd_timer.function = cbq_watchdog;
1452 init_timer(&q->delay_timer);
1453 q->delay_timer.data = (unsigned long)sch;
1454 q->delay_timer.function = cbq_undelay; 1449 q->delay_timer.function = cbq_undelay;
1455 q->toplevel = TC_CBQ_MAXLEVEL; 1450 q->toplevel = TC_CBQ_MAXLEVEL;
1456 PSCHED_GET_TIME(q->now); 1451 q->now = psched_get_time();
1457 q->now_rt = q->now; 1452 q->now_rt = q->now;
1458 1453
1459 cbq_link_class(&q->link); 1454 cbq_link_class(&q->link);
@@ -1467,19 +1462,19 @@ static int cbq_init(struct Qdisc *sch, struct rtattr *opt)
1467 1462
1468static __inline__ int cbq_dump_rate(struct sk_buff *skb, struct cbq_class *cl) 1463static __inline__ int cbq_dump_rate(struct sk_buff *skb, struct cbq_class *cl)
1469{ 1464{
1470 unsigned char *b = skb->tail; 1465 unsigned char *b = skb_tail_pointer(skb);
1471 1466
1472 RTA_PUT(skb, TCA_CBQ_RATE, sizeof(cl->R_tab->rate), &cl->R_tab->rate); 1467 RTA_PUT(skb, TCA_CBQ_RATE, sizeof(cl->R_tab->rate), &cl->R_tab->rate);
1473 return skb->len; 1468 return skb->len;
1474 1469
1475rtattr_failure: 1470rtattr_failure:
1476 skb_trim(skb, b - skb->data); 1471 nlmsg_trim(skb, b);
1477 return -1; 1472 return -1;
1478} 1473}
1479 1474
1480static __inline__ int cbq_dump_lss(struct sk_buff *skb, struct cbq_class *cl) 1475static __inline__ int cbq_dump_lss(struct sk_buff *skb, struct cbq_class *cl)
1481{ 1476{
1482 unsigned char *b = skb->tail; 1477 unsigned char *b = skb_tail_pointer(skb);
1483 struct tc_cbq_lssopt opt; 1478 struct tc_cbq_lssopt opt;
1484 1479
1485 opt.flags = 0; 1480 opt.flags = 0;
@@ -1498,13 +1493,13 @@ static __inline__ int cbq_dump_lss(struct sk_buff *skb, struct cbq_class *cl)
1498 return skb->len; 1493 return skb->len;
1499 1494
1500rtattr_failure: 1495rtattr_failure:
1501 skb_trim(skb, b - skb->data); 1496 nlmsg_trim(skb, b);
1502 return -1; 1497 return -1;
1503} 1498}
1504 1499
1505static __inline__ int cbq_dump_wrr(struct sk_buff *skb, struct cbq_class *cl) 1500static __inline__ int cbq_dump_wrr(struct sk_buff *skb, struct cbq_class *cl)
1506{ 1501{
1507 unsigned char *b = skb->tail; 1502 unsigned char *b = skb_tail_pointer(skb);
1508 struct tc_cbq_wrropt opt; 1503 struct tc_cbq_wrropt opt;
1509 1504
1510 opt.flags = 0; 1505 opt.flags = 0;
@@ -1516,30 +1511,30 @@ static __inline__ int cbq_dump_wrr(struct sk_buff *skb, struct cbq_class *cl)
1516 return skb->len; 1511 return skb->len;
1517 1512
1518rtattr_failure: 1513rtattr_failure:
1519 skb_trim(skb, b - skb->data); 1514 nlmsg_trim(skb, b);
1520 return -1; 1515 return -1;
1521} 1516}
1522 1517
1523static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl) 1518static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl)
1524{ 1519{
1525 unsigned char *b = skb->tail; 1520 unsigned char *b = skb_tail_pointer(skb);
1526 struct tc_cbq_ovl opt; 1521 struct tc_cbq_ovl opt;
1527 1522
1528 opt.strategy = cl->ovl_strategy; 1523 opt.strategy = cl->ovl_strategy;
1529 opt.priority2 = cl->priority2+1; 1524 opt.priority2 = cl->priority2+1;
1530 opt.pad = 0; 1525 opt.pad = 0;
1531 opt.penalty = (cl->penalty*1000)/HZ; 1526 opt.penalty = cl->penalty;
1532 RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt); 1527 RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt);
1533 return skb->len; 1528 return skb->len;
1534 1529
1535rtattr_failure: 1530rtattr_failure:
1536 skb_trim(skb, b - skb->data); 1531 nlmsg_trim(skb, b);
1537 return -1; 1532 return -1;
1538} 1533}
1539 1534
1540static __inline__ int cbq_dump_fopt(struct sk_buff *skb, struct cbq_class *cl) 1535static __inline__ int cbq_dump_fopt(struct sk_buff *skb, struct cbq_class *cl)
1541{ 1536{
1542 unsigned char *b = skb->tail; 1537 unsigned char *b = skb_tail_pointer(skb);
1543 struct tc_cbq_fopt opt; 1538 struct tc_cbq_fopt opt;
1544 1539
1545 if (cl->split || cl->defmap) { 1540 if (cl->split || cl->defmap) {
@@ -1551,14 +1546,14 @@ static __inline__ int cbq_dump_fopt(struct sk_buff *skb, struct cbq_class *cl)
1551 return skb->len; 1546 return skb->len;
1552 1547
1553rtattr_failure: 1548rtattr_failure:
1554 skb_trim(skb, b - skb->data); 1549 nlmsg_trim(skb, b);
1555 return -1; 1550 return -1;
1556} 1551}
1557 1552
1558#ifdef CONFIG_NET_CLS_POLICE 1553#ifdef CONFIG_NET_CLS_POLICE
1559static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl) 1554static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl)
1560{ 1555{
1561 unsigned char *b = skb->tail; 1556 unsigned char *b = skb_tail_pointer(skb);
1562 struct tc_cbq_police opt; 1557 struct tc_cbq_police opt;
1563 1558
1564 if (cl->police) { 1559 if (cl->police) {
@@ -1570,7 +1565,7 @@ static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl)
1570 return skb->len; 1565 return skb->len;
1571 1566
1572rtattr_failure: 1567rtattr_failure:
1573 skb_trim(skb, b - skb->data); 1568 nlmsg_trim(skb, b);
1574 return -1; 1569 return -1;
1575} 1570}
1576#endif 1571#endif
@@ -1592,18 +1587,18 @@ static int cbq_dump_attr(struct sk_buff *skb, struct cbq_class *cl)
1592static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb) 1587static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb)
1593{ 1588{
1594 struct cbq_sched_data *q = qdisc_priv(sch); 1589 struct cbq_sched_data *q = qdisc_priv(sch);
1595 unsigned char *b = skb->tail; 1590 unsigned char *b = skb_tail_pointer(skb);
1596 struct rtattr *rta; 1591 struct rtattr *rta;
1597 1592
1598 rta = (struct rtattr*)b; 1593 rta = (struct rtattr*)b;
1599 RTA_PUT(skb, TCA_OPTIONS, 0, NULL); 1594 RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
1600 if (cbq_dump_attr(skb, &q->link) < 0) 1595 if (cbq_dump_attr(skb, &q->link) < 0)
1601 goto rtattr_failure; 1596 goto rtattr_failure;
1602 rta->rta_len = skb->tail - b; 1597 rta->rta_len = skb_tail_pointer(skb) - b;
1603 return skb->len; 1598 return skb->len;
1604 1599
1605rtattr_failure: 1600rtattr_failure:
1606 skb_trim(skb, b - skb->data); 1601 nlmsg_trim(skb, b);
1607 return -1; 1602 return -1;
1608} 1603}
1609 1604
@@ -1621,7 +1616,7 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg,
1621 struct sk_buff *skb, struct tcmsg *tcm) 1616 struct sk_buff *skb, struct tcmsg *tcm)
1622{ 1617{
1623 struct cbq_class *cl = (struct cbq_class*)arg; 1618 struct cbq_class *cl = (struct cbq_class*)arg;
1624 unsigned char *b = skb->tail; 1619 unsigned char *b = skb_tail_pointer(skb);
1625 struct rtattr *rta; 1620 struct rtattr *rta;
1626 1621
1627 if (cl->tparent) 1622 if (cl->tparent)
@@ -1635,11 +1630,11 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg,
1635 RTA_PUT(skb, TCA_OPTIONS, 0, NULL); 1630 RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
1636 if (cbq_dump_attr(skb, cl) < 0) 1631 if (cbq_dump_attr(skb, cl) < 0)
1637 goto rtattr_failure; 1632 goto rtattr_failure;
1638 rta->rta_len = skb->tail - b; 1633 rta->rta_len = skb_tail_pointer(skb) - b;
1639 return skb->len; 1634 return skb->len;
1640 1635
1641rtattr_failure: 1636rtattr_failure:
1642 skb_trim(skb, b - skb->data); 1637 nlmsg_trim(skb, b);
1643 return -1; 1638 return -1;
1644} 1639}
1645 1640
@@ -1654,8 +1649,8 @@ cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
1654 cl->xstats.avgidle = cl->avgidle; 1649 cl->xstats.avgidle = cl->avgidle;
1655 cl->xstats.undertime = 0; 1650 cl->xstats.undertime = 0;
1656 1651
1657 if (!PSCHED_IS_PASTPERFECT(cl->undertime)) 1652 if (cl->undertime != PSCHED_PASTPERFECT)
1658 cl->xstats.undertime = PSCHED_TDIFF(cl->undertime, q->now); 1653 cl->xstats.undertime = cl->undertime - q->now;
1659 1654
1660 if (gnet_stats_copy_basic(d, &cl->bstats) < 0 || 1655 if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
1661#ifdef CONFIG_NET_ESTIMATOR 1656#ifdef CONFIG_NET_ESTIMATOR
@@ -1722,23 +1717,13 @@ static unsigned long cbq_get(struct Qdisc *sch, u32 classid)
1722 return 0; 1717 return 0;
1723} 1718}
1724 1719
1725static void cbq_destroy_filters(struct cbq_class *cl)
1726{
1727 struct tcf_proto *tp;
1728
1729 while ((tp = cl->filter_list) != NULL) {
1730 cl->filter_list = tp->next;
1731 tcf_destroy(tp);
1732 }
1733}
1734
1735static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl) 1720static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
1736{ 1721{
1737 struct cbq_sched_data *q = qdisc_priv(sch); 1722 struct cbq_sched_data *q = qdisc_priv(sch);
1738 1723
1739 BUG_TRAP(!cl->filters); 1724 BUG_TRAP(!cl->filters);
1740 1725
1741 cbq_destroy_filters(cl); 1726 tcf_destroy_chain(cl->filter_list);
1742 qdisc_destroy(cl->q); 1727 qdisc_destroy(cl->q);
1743 qdisc_put_rtab(cl->R_tab); 1728 qdisc_put_rtab(cl->R_tab);
1744#ifdef CONFIG_NET_ESTIMATOR 1729#ifdef CONFIG_NET_ESTIMATOR
@@ -1765,7 +1750,7 @@ cbq_destroy(struct Qdisc* sch)
1765 */ 1750 */
1766 for (h = 0; h < 16; h++) 1751 for (h = 0; h < 16; h++)
1767 for (cl = q->classes[h]; cl; cl = cl->next) 1752 for (cl = q->classes[h]; cl; cl = cl->next)
1768 cbq_destroy_filters(cl); 1753 tcf_destroy_chain(cl->filter_list);
1769 1754
1770 for (h = 0; h < 16; h++) { 1755 for (h = 0; h < 16; h++) {
1771 struct cbq_class *next; 1756 struct cbq_class *next;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 96324cf4e6a9..3c6fd181263f 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -216,17 +216,17 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
216 /* FIXME: Safe with non-linear skbs? --RR */ 216 /* FIXME: Safe with non-linear skbs? --RR */
217 switch (skb->protocol) { 217 switch (skb->protocol) {
218 case __constant_htons(ETH_P_IP): 218 case __constant_htons(ETH_P_IP):
219 skb->tc_index = ipv4_get_dsfield(skb->nh.iph) 219 skb->tc_index = ipv4_get_dsfield(ip_hdr(skb))
220 & ~INET_ECN_MASK; 220 & ~INET_ECN_MASK;
221 break; 221 break;
222 case __constant_htons(ETH_P_IPV6): 222 case __constant_htons(ETH_P_IPV6):
223 skb->tc_index = ipv6_get_dsfield(skb->nh.ipv6h) 223 skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
224 & ~INET_ECN_MASK; 224 & ~INET_ECN_MASK;
225 break; 225 break;
226 default: 226 default:
227 skb->tc_index = 0; 227 skb->tc_index = 0;
228 break; 228 break;
229 }; 229 }
230 } 230 }
231 231
232 if (TC_H_MAJ(skb->priority) == sch->handle) 232 if (TC_H_MAJ(skb->priority) == sch->handle)
@@ -257,7 +257,7 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
257 if (p->default_index != NO_DEFAULT_INDEX) 257 if (p->default_index != NO_DEFAULT_INDEX)
258 skb->tc_index = p->default_index; 258 skb->tc_index = p->default_index;
259 break; 259 break;
260 }; 260 }
261 } 261 }
262 262
263 err = p->q->enqueue(skb,p->q); 263 err = p->q->enqueue(skb,p->q);
@@ -292,11 +292,11 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
292 292
293 switch (skb->protocol) { 293 switch (skb->protocol) {
294 case __constant_htons(ETH_P_IP): 294 case __constant_htons(ETH_P_IP):
295 ipv4_change_dsfield(skb->nh.iph, p->mask[index], 295 ipv4_change_dsfield(ip_hdr(skb), p->mask[index],
296 p->value[index]); 296 p->value[index]);
297 break; 297 break;
298 case __constant_htons(ETH_P_IPV6): 298 case __constant_htons(ETH_P_IPV6):
299 ipv6_change_dsfield(skb->nh.ipv6h, p->mask[index], 299 ipv6_change_dsfield(ipv6_hdr(skb), p->mask[index],
300 p->value[index]); 300 p->value[index]);
301 break; 301 break;
302 default: 302 default:
@@ -310,7 +310,7 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
310 "unsupported protocol %d\n", 310 "unsupported protocol %d\n",
311 ntohs(skb->protocol)); 311 ntohs(skb->protocol));
312 break; 312 break;
313 }; 313 }
314 314
315 return skb; 315 return skb;
316} 316}
@@ -412,16 +412,10 @@ static void dsmark_reset(struct Qdisc *sch)
412static void dsmark_destroy(struct Qdisc *sch) 412static void dsmark_destroy(struct Qdisc *sch)
413{ 413{
414 struct dsmark_qdisc_data *p = PRIV(sch); 414 struct dsmark_qdisc_data *p = PRIV(sch);
415 struct tcf_proto *tp;
416 415
417 DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p); 416 DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p);
418 417
419 while (p->filter_list) { 418 tcf_destroy_chain(p->filter_list);
420 tp = p->filter_list;
421 p->filter_list = tp->next;
422 tcf_destroy(tp);
423 }
424
425 qdisc_destroy(p->q); 419 qdisc_destroy(p->q);
426 kfree(p->mask); 420 kfree(p->mask);
427} 421}
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 52eb3439d7c6..3385ee592541 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -36,34 +36,27 @@
36 36
37/* Main transmission queue. */ 37/* Main transmission queue. */
38 38
39/* Main qdisc structure lock. 39/* Modifications to data participating in scheduling must be protected with
40 40 * dev->queue_lock spinlock.
41 However, modifications 41 *
42 to data, participating in scheduling must be additionally 42 * The idea is the following:
43 protected with dev->queue_lock spinlock. 43 * - enqueue, dequeue are serialized via top level device
44 44 * spinlock dev->queue_lock.
45 The idea is the following: 45 * - ingress filtering is serialized via top level device
46 - enqueue, dequeue are serialized via top level device 46 * spinlock dev->ingress_lock.
47 spinlock dev->queue_lock. 47 * - updates to tree and tree walking are only done under the rtnl mutex.
48 - tree walking is protected by read_lock(qdisc_tree_lock)
49 and this lock is used only in process context.
50 - updates to tree are made only under rtnl semaphore,
51 hence this lock may be made without local bh disabling.
52
53 qdisc_tree_lock must be grabbed BEFORE dev->queue_lock!
54 */ 48 */
55DEFINE_RWLOCK(qdisc_tree_lock);
56 49
57void qdisc_lock_tree(struct net_device *dev) 50void qdisc_lock_tree(struct net_device *dev)
58{ 51{
59 write_lock(&qdisc_tree_lock);
60 spin_lock_bh(&dev->queue_lock); 52 spin_lock_bh(&dev->queue_lock);
53 spin_lock(&dev->ingress_lock);
61} 54}
62 55
63void qdisc_unlock_tree(struct net_device *dev) 56void qdisc_unlock_tree(struct net_device *dev)
64{ 57{
58 spin_unlock(&dev->ingress_lock);
65 spin_unlock_bh(&dev->queue_lock); 59 spin_unlock_bh(&dev->queue_lock);
66 write_unlock(&qdisc_tree_lock);
67} 60}
68 61
69/* 62/*
@@ -442,7 +435,6 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops)
442 sch->dequeue = ops->dequeue; 435 sch->dequeue = ops->dequeue;
443 sch->dev = dev; 436 sch->dev = dev;
444 dev_hold(dev); 437 dev_hold(dev);
445 sch->stats_lock = &dev->queue_lock;
446 atomic_set(&sch->refcnt, 1); 438 atomic_set(&sch->refcnt, 1);
447 439
448 return sch; 440 return sch;
@@ -458,6 +450,7 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops,
458 sch = qdisc_alloc(dev, ops); 450 sch = qdisc_alloc(dev, ops);
459 if (IS_ERR(sch)) 451 if (IS_ERR(sch))
460 goto errout; 452 goto errout;
453 sch->stats_lock = &dev->queue_lock;
461 sch->parent = parentid; 454 sch->parent = parentid;
462 455
463 if (!ops->init || ops->init(sch, NULL) == 0) 456 if (!ops->init || ops->init(sch, NULL) == 0)
@@ -528,15 +521,11 @@ void dev_activate(struct net_device *dev)
528 printk(KERN_INFO "%s: activation failed\n", dev->name); 521 printk(KERN_INFO "%s: activation failed\n", dev->name);
529 return; 522 return;
530 } 523 }
531 write_lock(&qdisc_tree_lock);
532 list_add_tail(&qdisc->list, &dev->qdisc_list); 524 list_add_tail(&qdisc->list, &dev->qdisc_list);
533 write_unlock(&qdisc_tree_lock);
534 } else { 525 } else {
535 qdisc = &noqueue_qdisc; 526 qdisc = &noqueue_qdisc;
536 } 527 }
537 write_lock(&qdisc_tree_lock);
538 dev->qdisc_sleeping = qdisc; 528 dev->qdisc_sleeping = qdisc;
539 write_unlock(&qdisc_tree_lock);
540 } 529 }
541 530
542 if (!netif_carrier_ok(dev)) 531 if (!netif_carrier_ok(dev))
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 407c6fb1ba14..9d124c4ee3a7 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -59,13 +59,13 @@
59#include <linux/skbuff.h> 59#include <linux/skbuff.h>
60#include <linux/string.h> 60#include <linux/string.h>
61#include <linux/slab.h> 61#include <linux/slab.h>
62#include <linux/timer.h>
63#include <linux/list.h> 62#include <linux/list.h>
64#include <linux/rbtree.h> 63#include <linux/rbtree.h>
65#include <linux/init.h> 64#include <linux/init.h>
66#include <linux/netdevice.h> 65#include <linux/netdevice.h>
67#include <linux/rtnetlink.h> 66#include <linux/rtnetlink.h>
68#include <linux/pkt_sched.h> 67#include <linux/pkt_sched.h>
68#include <net/netlink.h>
69#include <net/pkt_sched.h> 69#include <net/pkt_sched.h>
70#include <net/pkt_cls.h> 70#include <net/pkt_cls.h>
71#include <asm/system.h> 71#include <asm/system.h>
@@ -192,23 +192,9 @@ struct hfsc_sched
192 struct list_head droplist; /* active leaf class list (for 192 struct list_head droplist; /* active leaf class list (for
193 dropping) */ 193 dropping) */
194 struct sk_buff_head requeue; /* requeued packet */ 194 struct sk_buff_head requeue; /* requeued packet */
195 struct timer_list wd_timer; /* watchdog timer */ 195 struct qdisc_watchdog watchdog; /* watchdog timer */
196}; 196};
197 197
198/*
199 * macros
200 */
201#ifdef CONFIG_NET_SCH_CLK_GETTIMEOFDAY
202#include <linux/time.h>
203#undef PSCHED_GET_TIME
204#define PSCHED_GET_TIME(stamp) \
205do { \
206 struct timeval tv; \
207 do_gettimeofday(&tv); \
208 (stamp) = 1ULL * USEC_PER_SEC * tv.tv_sec + tv.tv_usec; \
209} while (0)
210#endif
211
212#define HT_INFINITY 0xffffffffffffffffULL /* infinite time value */ 198#define HT_INFINITY 0xffffffffffffffffULL /* infinite time value */
213 199
214 200
@@ -394,28 +380,17 @@ cftree_update(struct hfsc_class *cl)
394 * ism: (psched_us/byte) << ISM_SHIFT 380 * ism: (psched_us/byte) << ISM_SHIFT
395 * dx: psched_us 381 * dx: psched_us
396 * 382 *
397 * Clock source resolution (CONFIG_NET_SCH_CLK_*) 383 * The clock source resolution with ktime is 1.024us.
398 * JIFFIES: for 48<=HZ<=1534 resolution is between 0.63us and 1.27us.
399 * CPU: resolution is between 0.5us and 1us.
400 * GETTIMEOFDAY: resolution is exactly 1us.
401 * 384 *
402 * sm and ism are scaled in order to keep effective digits. 385 * sm and ism are scaled in order to keep effective digits.
403 * SM_SHIFT and ISM_SHIFT are selected to keep at least 4 effective 386 * SM_SHIFT and ISM_SHIFT are selected to keep at least 4 effective
404 * digits in decimal using the following table. 387 * digits in decimal using the following table.
405 * 388 *
406 * Note: We can afford the additional accuracy (altq hfsc keeps at most
407 * 3 effective digits) thanks to the fact that linux clock is bounded
408 * much more tightly.
409 *
410 * bits/sec 100Kbps 1Mbps 10Mbps 100Mbps 1Gbps 389 * bits/sec 100Kbps 1Mbps 10Mbps 100Mbps 1Gbps
411 * ------------+------------------------------------------------------- 390 * ------------+-------------------------------------------------------
412 * bytes/0.5us 6.25e-3 62.5e-3 625e-3 6250e-e 62500e-3 391 * bytes/1.024us 12.8e-3 128e-3 1280e-3 12800e-3 128000e-3
413 * bytes/us 12.5e-3 125e-3 1250e-3 12500e-3 125000e-3
414 * bytes/1.27us 15.875e-3 158.75e-3 1587.5e-3 15875e-3 158750e-3
415 * 392 *
416 * 0.5us/byte 160 16 1.6 0.16 0.016 393 * 1.024us/byte 78.125 7.8125 0.78125 0.078125 0.0078125
417 * us/byte 80 8 0.8 0.08 0.008
418 * 1.27us/byte 63 6.3 0.63 0.063 0.0063
419 */ 394 */
420#define SM_SHIFT 20 395#define SM_SHIFT 20
421#define ISM_SHIFT 18 396#define ISM_SHIFT 18
@@ -460,8 +435,8 @@ m2sm(u32 m)
460 u64 sm; 435 u64 sm;
461 436
462 sm = ((u64)m << SM_SHIFT); 437 sm = ((u64)m << SM_SHIFT);
463 sm += PSCHED_JIFFIE2US(HZ) - 1; 438 sm += PSCHED_TICKS_PER_SEC - 1;
464 do_div(sm, PSCHED_JIFFIE2US(HZ)); 439 do_div(sm, PSCHED_TICKS_PER_SEC);
465 return sm; 440 return sm;
466} 441}
467 442
@@ -474,7 +449,7 @@ m2ism(u32 m)
474 if (m == 0) 449 if (m == 0)
475 ism = HT_INFINITY; 450 ism = HT_INFINITY;
476 else { 451 else {
477 ism = ((u64)PSCHED_JIFFIE2US(HZ) << ISM_SHIFT); 452 ism = ((u64)PSCHED_TICKS_PER_SEC << ISM_SHIFT);
478 ism += m - 1; 453 ism += m - 1;
479 do_div(ism, m); 454 do_div(ism, m);
480 } 455 }
@@ -487,7 +462,7 @@ d2dx(u32 d)
487{ 462{
488 u64 dx; 463 u64 dx;
489 464
490 dx = ((u64)d * PSCHED_JIFFIE2US(HZ)); 465 dx = ((u64)d * PSCHED_TICKS_PER_SEC);
491 dx += USEC_PER_SEC - 1; 466 dx += USEC_PER_SEC - 1;
492 do_div(dx, USEC_PER_SEC); 467 do_div(dx, USEC_PER_SEC);
493 return dx; 468 return dx;
@@ -499,7 +474,7 @@ sm2m(u64 sm)
499{ 474{
500 u64 m; 475 u64 m;
501 476
502 m = (sm * PSCHED_JIFFIE2US(HZ)) >> SM_SHIFT; 477 m = (sm * PSCHED_TICKS_PER_SEC) >> SM_SHIFT;
503 return (u32)m; 478 return (u32)m;
504} 479}
505 480
@@ -510,7 +485,7 @@ dx2d(u64 dx)
510 u64 d; 485 u64 d;
511 486
512 d = dx * USEC_PER_SEC; 487 d = dx * USEC_PER_SEC;
513 do_div(d, PSCHED_JIFFIE2US(HZ)); 488 do_div(d, PSCHED_TICKS_PER_SEC);
514 return (u32)d; 489 return (u32)d;
515} 490}
516 491
@@ -654,9 +629,7 @@ rtsc_min(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x, u64 y)
654static void 629static void
655init_ed(struct hfsc_class *cl, unsigned int next_len) 630init_ed(struct hfsc_class *cl, unsigned int next_len)
656{ 631{
657 u64 cur_time; 632 u64 cur_time = psched_get_time();
658
659 PSCHED_GET_TIME(cur_time);
660 633
661 /* update the deadline curve */ 634 /* update the deadline curve */
662 rtsc_min(&cl->cl_deadline, &cl->cl_rsc, cur_time, cl->cl_cumul); 635 rtsc_min(&cl->cl_deadline, &cl->cl_rsc, cur_time, cl->cl_cumul);
@@ -779,7 +752,7 @@ init_vf(struct hfsc_class *cl, unsigned int len)
779 if (cl->cl_flags & HFSC_USC) { 752 if (cl->cl_flags & HFSC_USC) {
780 /* class has upper limit curve */ 753 /* class has upper limit curve */
781 if (cur_time == 0) 754 if (cur_time == 0)
782 PSCHED_GET_TIME(cur_time); 755 cur_time = psched_get_time();
783 756
784 /* update the ulimit curve */ 757 /* update the ulimit curve */
785 rtsc_min(&cl->cl_ulimit, &cl->cl_usc, cur_time, 758 rtsc_min(&cl->cl_ulimit, &cl->cl_usc, cur_time,
@@ -1063,7 +1036,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1063 if (cl->cl_parent == NULL && parentid != TC_H_ROOT) 1036 if (cl->cl_parent == NULL && parentid != TC_H_ROOT)
1064 return -EINVAL; 1037 return -EINVAL;
1065 } 1038 }
1066 PSCHED_GET_TIME(cur_time); 1039 cur_time = psched_get_time();
1067 1040
1068 sch_tree_lock(sch); 1041 sch_tree_lock(sch);
1069 if (rsc != NULL) 1042 if (rsc != NULL)
@@ -1149,22 +1122,11 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1149} 1122}
1150 1123
1151static void 1124static void
1152hfsc_destroy_filters(struct tcf_proto **fl)
1153{
1154 struct tcf_proto *tp;
1155
1156 while ((tp = *fl) != NULL) {
1157 *fl = tp->next;
1158 tcf_destroy(tp);
1159 }
1160}
1161
1162static void
1163hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl) 1125hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl)
1164{ 1126{
1165 struct hfsc_sched *q = qdisc_priv(sch); 1127 struct hfsc_sched *q = qdisc_priv(sch);
1166 1128
1167 hfsc_destroy_filters(&cl->filter_list); 1129 tcf_destroy_chain(cl->filter_list);
1168 qdisc_destroy(cl->qdisc); 1130 qdisc_destroy(cl->qdisc);
1169#ifdef CONFIG_NET_ESTIMATOR 1131#ifdef CONFIG_NET_ESTIMATOR
1170 gen_kill_estimator(&cl->bstats, &cl->rate_est); 1132 gen_kill_estimator(&cl->bstats, &cl->rate_est);
@@ -1389,7 +1351,7 @@ hfsc_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb,
1389 struct tcmsg *tcm) 1351 struct tcmsg *tcm)
1390{ 1352{
1391 struct hfsc_class *cl = (struct hfsc_class *)arg; 1353 struct hfsc_class *cl = (struct hfsc_class *)arg;
1392 unsigned char *b = skb->tail; 1354 unsigned char *b = skb_tail_pointer(skb);
1393 struct rtattr *rta = (struct rtattr *)b; 1355 struct rtattr *rta = (struct rtattr *)b;
1394 1356
1395 tcm->tcm_parent = cl->cl_parent ? cl->cl_parent->classid : TC_H_ROOT; 1357 tcm->tcm_parent = cl->cl_parent ? cl->cl_parent->classid : TC_H_ROOT;
@@ -1400,11 +1362,11 @@ hfsc_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb,
1400 RTA_PUT(skb, TCA_OPTIONS, 0, NULL); 1362 RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
1401 if (hfsc_dump_curves(skb, cl) < 0) 1363 if (hfsc_dump_curves(skb, cl) < 0)
1402 goto rtattr_failure; 1364 goto rtattr_failure;
1403 rta->rta_len = skb->tail - b; 1365 rta->rta_len = skb_tail_pointer(skb) - b;
1404 return skb->len; 1366 return skb->len;
1405 1367
1406 rtattr_failure: 1368 rtattr_failure:
1407 skb_trim(skb, b - skb->data); 1369 nlmsg_trim(skb, b);
1408 return -1; 1370 return -1;
1409} 1371}
1410 1372
@@ -1459,21 +1421,11 @@ hfsc_walk(struct Qdisc *sch, struct qdisc_walker *arg)
1459} 1421}
1460 1422
1461static void 1423static void
1462hfsc_watchdog(unsigned long arg) 1424hfsc_schedule_watchdog(struct Qdisc *sch)
1463{
1464 struct Qdisc *sch = (struct Qdisc *)arg;
1465
1466 sch->flags &= ~TCQ_F_THROTTLED;
1467 netif_schedule(sch->dev);
1468}
1469
1470static void
1471hfsc_schedule_watchdog(struct Qdisc *sch, u64 cur_time)
1472{ 1425{
1473 struct hfsc_sched *q = qdisc_priv(sch); 1426 struct hfsc_sched *q = qdisc_priv(sch);
1474 struct hfsc_class *cl; 1427 struct hfsc_class *cl;
1475 u64 next_time = 0; 1428 u64 next_time = 0;
1476 long delay;
1477 1429
1478 if ((cl = eltree_get_minel(q)) != NULL) 1430 if ((cl = eltree_get_minel(q)) != NULL)
1479 next_time = cl->cl_e; 1431 next_time = cl->cl_e;
@@ -1482,11 +1434,7 @@ hfsc_schedule_watchdog(struct Qdisc *sch, u64 cur_time)
1482 next_time = q->root.cl_cfmin; 1434 next_time = q->root.cl_cfmin;
1483 } 1435 }
1484 WARN_ON(next_time == 0); 1436 WARN_ON(next_time == 0);
1485 delay = next_time - cur_time; 1437 qdisc_watchdog_schedule(&q->watchdog, next_time);
1486 delay = PSCHED_US2JIFFIE(delay);
1487
1488 sch->flags |= TCQ_F_THROTTLED;
1489 mod_timer(&q->wd_timer, jiffies + delay);
1490} 1438}
1491 1439
1492static int 1440static int
@@ -1523,9 +1471,7 @@ hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt)
1523 1471
1524 list_add(&q->root.hlist, &q->clhash[hfsc_hash(q->root.classid)]); 1472 list_add(&q->root.hlist, &q->clhash[hfsc_hash(q->root.classid)]);
1525 1473
1526 init_timer(&q->wd_timer); 1474 qdisc_watchdog_init(&q->watchdog, sch);
1527 q->wd_timer.function = hfsc_watchdog;
1528 q->wd_timer.data = (unsigned long)sch;
1529 1475
1530 return 0; 1476 return 0;
1531} 1477}
@@ -1595,8 +1541,7 @@ hfsc_reset_qdisc(struct Qdisc *sch)
1595 __skb_queue_purge(&q->requeue); 1541 __skb_queue_purge(&q->requeue);
1596 q->eligible = RB_ROOT; 1542 q->eligible = RB_ROOT;
1597 INIT_LIST_HEAD(&q->droplist); 1543 INIT_LIST_HEAD(&q->droplist);
1598 del_timer(&q->wd_timer); 1544 qdisc_watchdog_cancel(&q->watchdog);
1599 sch->flags &= ~TCQ_F_THROTTLED;
1600 sch->q.qlen = 0; 1545 sch->q.qlen = 0;
1601} 1546}
1602 1547
@@ -1612,14 +1557,14 @@ hfsc_destroy_qdisc(struct Qdisc *sch)
1612 hfsc_destroy_class(sch, cl); 1557 hfsc_destroy_class(sch, cl);
1613 } 1558 }
1614 __skb_queue_purge(&q->requeue); 1559 __skb_queue_purge(&q->requeue);
1615 del_timer(&q->wd_timer); 1560 qdisc_watchdog_cancel(&q->watchdog);
1616} 1561}
1617 1562
1618static int 1563static int
1619hfsc_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb) 1564hfsc_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb)
1620{ 1565{
1621 struct hfsc_sched *q = qdisc_priv(sch); 1566 struct hfsc_sched *q = qdisc_priv(sch);
1622 unsigned char *b = skb->tail; 1567 unsigned char *b = skb_tail_pointer(skb);
1623 struct tc_hfsc_qopt qopt; 1568 struct tc_hfsc_qopt qopt;
1624 1569
1625 qopt.defcls = q->defcls; 1570 qopt.defcls = q->defcls;
@@ -1627,7 +1572,7 @@ hfsc_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb)
1627 return skb->len; 1572 return skb->len;
1628 1573
1629 rtattr_failure: 1574 rtattr_failure:
1630 skb_trim(skb, b - skb->data); 1575 nlmsg_trim(skb, b);
1631 return -1; 1576 return -1;
1632} 1577}
1633 1578
@@ -1681,7 +1626,7 @@ hfsc_dequeue(struct Qdisc *sch)
1681 if ((skb = __skb_dequeue(&q->requeue))) 1626 if ((skb = __skb_dequeue(&q->requeue)))
1682 goto out; 1627 goto out;
1683 1628
1684 PSCHED_GET_TIME(cur_time); 1629 cur_time = psched_get_time();
1685 1630
1686 /* 1631 /*
1687 * if there are eligible classes, use real-time criteria. 1632 * if there are eligible classes, use real-time criteria.
@@ -1698,7 +1643,7 @@ hfsc_dequeue(struct Qdisc *sch)
1698 cl = vttree_get_minvt(&q->root, cur_time); 1643 cl = vttree_get_minvt(&q->root, cur_time);
1699 if (cl == NULL) { 1644 if (cl == NULL) {
1700 sch->qstats.overlimits++; 1645 sch->qstats.overlimits++;
1701 hfsc_schedule_watchdog(sch, cur_time); 1646 hfsc_schedule_watchdog(sch);
1702 return NULL; 1647 return NULL;
1703 } 1648 }
1704 } 1649 }
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 3c3294d01041..99bcec8dd04c 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -50,6 +50,7 @@
50#include <linux/skbuff.h> 50#include <linux/skbuff.h>
51#include <linux/list.h> 51#include <linux/list.h>
52#include <linux/compiler.h> 52#include <linux/compiler.h>
53#include <net/netlink.h>
53#include <net/sock.h> 54#include <net/sock.h>
54#include <net/pkt_sched.h> 55#include <net/pkt_sched.h>
55#include <linux/rbtree.h> 56#include <linux/rbtree.h>
@@ -128,7 +129,7 @@ struct htb_class {
128 } un; 129 } un;
129 struct rb_node node[TC_HTB_NUMPRIO]; /* node for self or feed tree */ 130 struct rb_node node[TC_HTB_NUMPRIO]; /* node for self or feed tree */
130 struct rb_node pq_node; /* node for event queue */ 131 struct rb_node pq_node; /* node for event queue */
131 unsigned long pq_key; /* the same type as jiffies global */ 132 psched_time_t pq_key;
132 133
133 int prio_activity; /* for which prios are we active */ 134 int prio_activity; /* for which prios are we active */
134 enum htb_cmode cmode; /* current mode of the class */ 135 enum htb_cmode cmode; /* current mode of the class */
@@ -179,10 +180,7 @@ struct htb_sched {
179 struct rb_root wait_pq[TC_HTB_MAXDEPTH]; 180 struct rb_root wait_pq[TC_HTB_MAXDEPTH];
180 181
181 /* time of nearest event per level (row) */ 182 /* time of nearest event per level (row) */
182 unsigned long near_ev_cache[TC_HTB_MAXDEPTH]; 183 psched_time_t near_ev_cache[TC_HTB_MAXDEPTH];
183
184 /* cached value of jiffies in dequeue */
185 unsigned long jiffies;
186 184
187 /* whether we hit non-work conserving class during this dequeue; we use */ 185 /* whether we hit non-work conserving class during this dequeue; we use */
188 int nwc_hit; /* this to disable mindelay complaint in dequeue */ 186 int nwc_hit; /* this to disable mindelay complaint in dequeue */
@@ -195,7 +193,7 @@ struct htb_sched {
195 193
196 int rate2quantum; /* quant = rate / rate2quantum */ 194 int rate2quantum; /* quant = rate / rate2quantum */
197 psched_time_t now; /* cached dequeue time */ 195 psched_time_t now; /* cached dequeue time */
198 struct timer_list timer; /* send delay timer */ 196 struct qdisc_watchdog watchdog;
199#ifdef HTB_RATECM 197#ifdef HTB_RATECM
200 struct timer_list rttim; /* rate computer timer */ 198 struct timer_list rttim; /* rate computer timer */
201 int recmp_bucket; /* which hash bucket to recompute next */ 199 int recmp_bucket; /* which hash bucket to recompute next */
@@ -342,19 +340,19 @@ static void htb_add_to_wait_tree(struct htb_sched *q,
342{ 340{
343 struct rb_node **p = &q->wait_pq[cl->level].rb_node, *parent = NULL; 341 struct rb_node **p = &q->wait_pq[cl->level].rb_node, *parent = NULL;
344 342
345 cl->pq_key = q->jiffies + PSCHED_US2JIFFIE(delay); 343 cl->pq_key = q->now + delay;
346 if (cl->pq_key == q->jiffies) 344 if (cl->pq_key == q->now)
347 cl->pq_key++; 345 cl->pq_key++;
348 346
349 /* update the nearest event cache */ 347 /* update the nearest event cache */
350 if (time_after(q->near_ev_cache[cl->level], cl->pq_key)) 348 if (q->near_ev_cache[cl->level] > cl->pq_key)
351 q->near_ev_cache[cl->level] = cl->pq_key; 349 q->near_ev_cache[cl->level] = cl->pq_key;
352 350
353 while (*p) { 351 while (*p) {
354 struct htb_class *c; 352 struct htb_class *c;
355 parent = *p; 353 parent = *p;
356 c = rb_entry(parent, struct htb_class, pq_node); 354 c = rb_entry(parent, struct htb_class, pq_node);
357 if (time_after_eq(cl->pq_key, c->pq_key)) 355 if (cl->pq_key >= c->pq_key)
358 p = &parent->rb_right; 356 p = &parent->rb_right;
359 else 357 else
360 p = &parent->rb_left; 358 p = &parent->rb_left;
@@ -679,14 +677,6 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
679 return NET_XMIT_SUCCESS; 677 return NET_XMIT_SUCCESS;
680} 678}
681 679
682static void htb_timer(unsigned long arg)
683{
684 struct Qdisc *sch = (struct Qdisc *)arg;
685 sch->flags &= ~TCQ_F_THROTTLED;
686 wmb();
687 netif_schedule(sch->dev);
688}
689
690#ifdef HTB_RATECM 680#ifdef HTB_RATECM
691#define RT_GEN(D,R) R+=D-(R/HTB_EWMAC);D=0 681#define RT_GEN(D,R) R+=D-(R/HTB_EWMAC);D=0
692static void htb_rate_timer(unsigned long arg) 682static void htb_rate_timer(unsigned long arg)
@@ -739,7 +729,7 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
739 cl->T = toks 729 cl->T = toks
740 730
741 while (cl) { 731 while (cl) {
742 diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32) cl->mbuffer); 732 diff = psched_tdiff_bounded(q->now, cl->t_c, cl->mbuffer);
743 if (cl->level >= level) { 733 if (cl->level >= level) {
744 if (cl->level == level) 734 if (cl->level == level)
745 cl->xstats.lends++; 735 cl->xstats.lends++;
@@ -778,11 +768,11 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
778/** 768/**
779 * htb_do_events - make mode changes to classes at the level 769 * htb_do_events - make mode changes to classes at the level
780 * 770 *
781 * Scans event queue for pending events and applies them. Returns jiffies to 771 * Scans event queue for pending events and applies them. Returns time of
782 * next pending event (0 for no event in pq). 772 * next pending event (0 for no event in pq).
783 * Note: Aplied are events whose have cl->pq_key <= jiffies. 773 * Note: Applied are events whose have cl->pq_key <= q->now.
784 */ 774 */
785static long htb_do_events(struct htb_sched *q, int level) 775static psched_time_t htb_do_events(struct htb_sched *q, int level)
786{ 776{
787 int i; 777 int i;
788 778
@@ -795,18 +785,18 @@ static long htb_do_events(struct htb_sched *q, int level)
795 return 0; 785 return 0;
796 786
797 cl = rb_entry(p, struct htb_class, pq_node); 787 cl = rb_entry(p, struct htb_class, pq_node);
798 if (time_after(cl->pq_key, q->jiffies)) { 788 if (cl->pq_key > q->now)
799 return cl->pq_key - q->jiffies; 789 return cl->pq_key;
800 } 790
801 htb_safe_rb_erase(p, q->wait_pq + level); 791 htb_safe_rb_erase(p, q->wait_pq + level);
802 diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32) cl->mbuffer); 792 diff = psched_tdiff_bounded(q->now, cl->t_c, cl->mbuffer);
803 htb_change_class_mode(q, cl, &diff); 793 htb_change_class_mode(q, cl, &diff);
804 if (cl->cmode != HTB_CAN_SEND) 794 if (cl->cmode != HTB_CAN_SEND)
805 htb_add_to_wait_tree(q, cl, diff); 795 htb_add_to_wait_tree(q, cl, diff);
806 } 796 }
807 if (net_ratelimit()) 797 if (net_ratelimit())
808 printk(KERN_WARNING "htb: too many events !\n"); 798 printk(KERN_WARNING "htb: too many events !\n");
809 return HZ / 10; 799 return q->now + PSCHED_TICKS_PER_SEC / 10;
810} 800}
811 801
812/* Returns class->node+prio from id-tree where classe's id is >= id. NULL 802/* Returns class->node+prio from id-tree where classe's id is >= id. NULL
@@ -958,30 +948,12 @@ next:
958 return skb; 948 return skb;
959} 949}
960 950
961static void htb_delay_by(struct Qdisc *sch, long delay)
962{
963 struct htb_sched *q = qdisc_priv(sch);
964 if (delay <= 0)
965 delay = 1;
966 if (unlikely(delay > 5 * HZ)) {
967 if (net_ratelimit())
968 printk(KERN_INFO "HTB delay %ld > 5sec\n", delay);
969 delay = 5 * HZ;
970 }
971 /* why don't use jiffies here ? because expires can be in past */
972 mod_timer(&q->timer, q->jiffies + delay);
973 sch->flags |= TCQ_F_THROTTLED;
974 sch->qstats.overlimits++;
975}
976
977static struct sk_buff *htb_dequeue(struct Qdisc *sch) 951static struct sk_buff *htb_dequeue(struct Qdisc *sch)
978{ 952{
979 struct sk_buff *skb = NULL; 953 struct sk_buff *skb = NULL;
980 struct htb_sched *q = qdisc_priv(sch); 954 struct htb_sched *q = qdisc_priv(sch);
981 int level; 955 int level;
982 long min_delay; 956 psched_time_t next_event;
983
984 q->jiffies = jiffies;
985 957
986 /* try to dequeue direct packets as high prio (!) to minimize cpu work */ 958 /* try to dequeue direct packets as high prio (!) to minimize cpu work */
987 skb = __skb_dequeue(&q->direct_queue); 959 skb = __skb_dequeue(&q->direct_queue);
@@ -993,23 +965,25 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
993 965
994 if (!sch->q.qlen) 966 if (!sch->q.qlen)
995 goto fin; 967 goto fin;
996 PSCHED_GET_TIME(q->now); 968 q->now = psched_get_time();
997 969
998 min_delay = LONG_MAX; 970 next_event = q->now + 5 * PSCHED_TICKS_PER_SEC;
999 q->nwc_hit = 0; 971 q->nwc_hit = 0;
1000 for (level = 0; level < TC_HTB_MAXDEPTH; level++) { 972 for (level = 0; level < TC_HTB_MAXDEPTH; level++) {
1001 /* common case optimization - skip event handler quickly */ 973 /* common case optimization - skip event handler quickly */
1002 int m; 974 int m;
1003 long delay; 975 psched_time_t event;
1004 if (time_after_eq(q->jiffies, q->near_ev_cache[level])) { 976
1005 delay = htb_do_events(q, level); 977 if (q->now >= q->near_ev_cache[level]) {
1006 q->near_ev_cache[level] = 978 event = htb_do_events(q, level);
1007 q->jiffies + (delay ? delay : HZ); 979 q->near_ev_cache[level] = event ? event :
980 PSCHED_TICKS_PER_SEC;
1008 } else 981 } else
1009 delay = q->near_ev_cache[level] - q->jiffies; 982 event = q->near_ev_cache[level];
983
984 if (event && next_event > event)
985 next_event = event;
1010 986
1011 if (delay && min_delay > delay)
1012 min_delay = delay;
1013 m = ~q->row_mask[level]; 987 m = ~q->row_mask[level];
1014 while (m != (int)(-1)) { 988 while (m != (int)(-1)) {
1015 int prio = ffz(m); 989 int prio = ffz(m);
@@ -1022,7 +996,8 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
1022 } 996 }
1023 } 997 }
1024 } 998 }
1025 htb_delay_by(sch, min_delay > 5 * HZ ? 5 * HZ : min_delay); 999 sch->qstats.overlimits++;
1000 qdisc_watchdog_schedule(&q->watchdog, next_event);
1026fin: 1001fin:
1027 return skb; 1002 return skb;
1028} 1003}
@@ -1075,8 +1050,7 @@ static void htb_reset(struct Qdisc *sch)
1075 1050
1076 } 1051 }
1077 } 1052 }
1078 sch->flags &= ~TCQ_F_THROTTLED; 1053 qdisc_watchdog_cancel(&q->watchdog);
1079 del_timer(&q->timer);
1080 __skb_queue_purge(&q->direct_queue); 1054 __skb_queue_purge(&q->direct_queue);
1081 sch->q.qlen = 0; 1055 sch->q.qlen = 0;
1082 memset(q->row, 0, sizeof(q->row)); 1056 memset(q->row, 0, sizeof(q->row));
@@ -1113,14 +1087,12 @@ static int htb_init(struct Qdisc *sch, struct rtattr *opt)
1113 for (i = 0; i < TC_HTB_NUMPRIO; i++) 1087 for (i = 0; i < TC_HTB_NUMPRIO; i++)
1114 INIT_LIST_HEAD(q->drops + i); 1088 INIT_LIST_HEAD(q->drops + i);
1115 1089
1116 init_timer(&q->timer); 1090 qdisc_watchdog_init(&q->watchdog, sch);
1117 skb_queue_head_init(&q->direct_queue); 1091 skb_queue_head_init(&q->direct_queue);
1118 1092
1119 q->direct_qlen = sch->dev->tx_queue_len; 1093 q->direct_qlen = sch->dev->tx_queue_len;
1120 if (q->direct_qlen < 2) /* some devices have zero tx_queue_len */ 1094 if (q->direct_qlen < 2) /* some devices have zero tx_queue_len */
1121 q->direct_qlen = 2; 1095 q->direct_qlen = 2;
1122 q->timer.function = htb_timer;
1123 q->timer.data = (unsigned long)sch;
1124 1096
1125#ifdef HTB_RATECM 1097#ifdef HTB_RATECM
1126 init_timer(&q->rttim); 1098 init_timer(&q->rttim);
@@ -1139,7 +1111,7 @@ static int htb_init(struct Qdisc *sch, struct rtattr *opt)
1139static int htb_dump(struct Qdisc *sch, struct sk_buff *skb) 1111static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
1140{ 1112{
1141 struct htb_sched *q = qdisc_priv(sch); 1113 struct htb_sched *q = qdisc_priv(sch);
1142 unsigned char *b = skb->tail; 1114 unsigned char *b = skb_tail_pointer(skb);
1143 struct rtattr *rta; 1115 struct rtattr *rta;
1144 struct tc_htb_glob gopt; 1116 struct tc_htb_glob gopt;
1145 spin_lock_bh(&sch->dev->queue_lock); 1117 spin_lock_bh(&sch->dev->queue_lock);
@@ -1152,12 +1124,12 @@ static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
1152 rta = (struct rtattr *)b; 1124 rta = (struct rtattr *)b;
1153 RTA_PUT(skb, TCA_OPTIONS, 0, NULL); 1125 RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
1154 RTA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt); 1126 RTA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
1155 rta->rta_len = skb->tail - b; 1127 rta->rta_len = skb_tail_pointer(skb) - b;
1156 spin_unlock_bh(&sch->dev->queue_lock); 1128 spin_unlock_bh(&sch->dev->queue_lock);
1157 return skb->len; 1129 return skb->len;
1158rtattr_failure: 1130rtattr_failure:
1159 spin_unlock_bh(&sch->dev->queue_lock); 1131 spin_unlock_bh(&sch->dev->queue_lock);
1160 skb_trim(skb, skb->tail - skb->data); 1132 nlmsg_trim(skb, skb_tail_pointer(skb));
1161 return -1; 1133 return -1;
1162} 1134}
1163 1135
@@ -1165,7 +1137,7 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
1165 struct sk_buff *skb, struct tcmsg *tcm) 1137 struct sk_buff *skb, struct tcmsg *tcm)
1166{ 1138{
1167 struct htb_class *cl = (struct htb_class *)arg; 1139 struct htb_class *cl = (struct htb_class *)arg;
1168 unsigned char *b = skb->tail; 1140 unsigned char *b = skb_tail_pointer(skb);
1169 struct rtattr *rta; 1141 struct rtattr *rta;
1170 struct tc_htb_opt opt; 1142 struct tc_htb_opt opt;
1171 1143
@@ -1188,12 +1160,12 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
1188 opt.prio = cl->un.leaf.prio; 1160 opt.prio = cl->un.leaf.prio;
1189 opt.level = cl->level; 1161 opt.level = cl->level;
1190 RTA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt); 1162 RTA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
1191 rta->rta_len = skb->tail - b; 1163 rta->rta_len = skb_tail_pointer(skb) - b;
1192 spin_unlock_bh(&sch->dev->queue_lock); 1164 spin_unlock_bh(&sch->dev->queue_lock);
1193 return skb->len; 1165 return skb->len;
1194rtattr_failure: 1166rtattr_failure:
1195 spin_unlock_bh(&sch->dev->queue_lock); 1167 spin_unlock_bh(&sch->dev->queue_lock);
1196 skb_trim(skb, b - skb->data); 1168 nlmsg_trim(skb, b);
1197 return -1; 1169 return -1;
1198} 1170}
1199 1171
@@ -1264,16 +1236,6 @@ static unsigned long htb_get(struct Qdisc *sch, u32 classid)
1264 return (unsigned long)cl; 1236 return (unsigned long)cl;
1265} 1237}
1266 1238
1267static void htb_destroy_filters(struct tcf_proto **fl)
1268{
1269 struct tcf_proto *tp;
1270
1271 while ((tp = *fl) != NULL) {
1272 *fl = tp->next;
1273 tcf_destroy(tp);
1274 }
1275}
1276
1277static inline int htb_parent_last_child(struct htb_class *cl) 1239static inline int htb_parent_last_child(struct htb_class *cl)
1278{ 1240{
1279 if (!cl->parent) 1241 if (!cl->parent)
@@ -1302,7 +1264,7 @@ static void htb_parent_to_leaf(struct htb_class *cl, struct Qdisc *new_q)
1302 parent->un.leaf.prio = parent->prio; 1264 parent->un.leaf.prio = parent->prio;
1303 parent->tokens = parent->buffer; 1265 parent->tokens = parent->buffer;
1304 parent->ctokens = parent->cbuffer; 1266 parent->ctokens = parent->cbuffer;
1305 PSCHED_GET_TIME(parent->t_c); 1267 parent->t_c = psched_get_time();
1306 parent->cmode = HTB_CAN_SEND; 1268 parent->cmode = HTB_CAN_SEND;
1307} 1269}
1308 1270
@@ -1317,7 +1279,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl)
1317 qdisc_put_rtab(cl->rate); 1279 qdisc_put_rtab(cl->rate);
1318 qdisc_put_rtab(cl->ceil); 1280 qdisc_put_rtab(cl->ceil);
1319 1281
1320 htb_destroy_filters(&cl->filter_list); 1282 tcf_destroy_chain(cl->filter_list);
1321 1283
1322 while (!list_empty(&cl->children)) 1284 while (!list_empty(&cl->children))
1323 htb_destroy_class(sch, list_entry(cl->children.next, 1285 htb_destroy_class(sch, list_entry(cl->children.next,
@@ -1341,7 +1303,7 @@ static void htb_destroy(struct Qdisc *sch)
1341{ 1303{
1342 struct htb_sched *q = qdisc_priv(sch); 1304 struct htb_sched *q = qdisc_priv(sch);
1343 1305
1344 del_timer_sync(&q->timer); 1306 qdisc_watchdog_cancel(&q->watchdog);
1345#ifdef HTB_RATECM 1307#ifdef HTB_RATECM
1346 del_timer_sync(&q->rttim); 1308 del_timer_sync(&q->rttim);
1347#endif 1309#endif
@@ -1349,7 +1311,7 @@ static void htb_destroy(struct Qdisc *sch)
1349 and surprisingly it worked in 2.4. But it must precede it 1311 and surprisingly it worked in 2.4. But it must precede it
1350 because filter need its target class alive to be able to call 1312 because filter need its target class alive to be able to call
1351 unbind_filter on it (without Oops). */ 1313 unbind_filter on it (without Oops). */
1352 htb_destroy_filters(&q->filter_list); 1314 tcf_destroy_chain(q->filter_list);
1353 1315
1354 while (!list_empty(&q->root)) 1316 while (!list_empty(&q->root))
1355 htb_destroy_class(sch, list_entry(q->root.next, 1317 htb_destroy_class(sch, list_entry(q->root.next,
@@ -1498,8 +1460,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1498 /* set class to be in HTB_CAN_SEND state */ 1460 /* set class to be in HTB_CAN_SEND state */
1499 cl->tokens = hopt->buffer; 1461 cl->tokens = hopt->buffer;
1500 cl->ctokens = hopt->cbuffer; 1462 cl->ctokens = hopt->cbuffer;
1501 cl->mbuffer = PSCHED_JIFFIE2US(HZ * 60); /* 1min */ 1463 cl->mbuffer = 60 * PSCHED_TICKS_PER_SEC; /* 1min */
1502 PSCHED_GET_TIME(cl->t_c); 1464 cl->t_c = psched_get_time();
1503 cl->cmode = HTB_CAN_SEND; 1465 cl->cmode = HTB_CAN_SEND;
1504 1466
1505 /* attach to the hash list and parent's family */ 1467 /* attach to the hash list and parent's family */
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index cfe070ee6ee3..f8b9f1cdf738 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -16,6 +16,7 @@
16#include <linux/netfilter_ipv6.h> 16#include <linux/netfilter_ipv6.h>
17#include <linux/netfilter.h> 17#include <linux/netfilter.h>
18#include <linux/smp.h> 18#include <linux/smp.h>
19#include <net/netlink.h>
19#include <net/pkt_sched.h> 20#include <net/pkt_sched.h>
20#include <asm/byteorder.h> 21#include <asm/byteorder.h>
21#include <asm/uaccess.h> 22#include <asm/uaccess.h>
@@ -169,7 +170,7 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch)
169 skb->tc_index = TC_H_MIN(res.classid); 170 skb->tc_index = TC_H_MIN(res.classid);
170 result = TC_ACT_OK; 171 result = TC_ACT_OK;
171 break; 172 break;
172 }; 173 }
173/* backward compat */ 174/* backward compat */
174#else 175#else
175#ifdef CONFIG_NET_CLS_POLICE 176#ifdef CONFIG_NET_CLS_POLICE
@@ -186,7 +187,7 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch)
186 sch->bstats.bytes += skb->len; 187 sch->bstats.bytes += skb->len;
187 result = NF_ACCEPT; 188 result = NF_ACCEPT;
188 break; 189 break;
189 }; 190 }
190 191
191#else 192#else
192 D2PRINTK("Overriding result to ACCEPT\n"); 193 D2PRINTK("Overriding result to ACCEPT\n");
@@ -247,16 +248,11 @@ ing_hook(unsigned int hook, struct sk_buff **pskb,
247 skb->dev ? (*pskb)->dev->name : "(no dev)", 248 skb->dev ? (*pskb)->dev->name : "(no dev)",
248 skb->len); 249 skb->len);
249 250
250/*
251revisit later: Use a private since lock dev->queue_lock is also
252used on the egress (might slow things for an iota)
253*/
254
255 if (dev->qdisc_ingress) { 251 if (dev->qdisc_ingress) {
256 spin_lock(&dev->queue_lock); 252 spin_lock(&dev->ingress_lock);
257 if ((q = dev->qdisc_ingress) != NULL) 253 if ((q = dev->qdisc_ingress) != NULL)
258 fwres = q->enqueue(skb, q); 254 fwres = q->enqueue(skb, q);
259 spin_unlock(&dev->queue_lock); 255 spin_unlock(&dev->ingress_lock);
260 } 256 }
261 257
262 return fwres; 258 return fwres;
@@ -345,14 +341,9 @@ static void ingress_reset(struct Qdisc *sch)
345static void ingress_destroy(struct Qdisc *sch) 341static void ingress_destroy(struct Qdisc *sch)
346{ 342{
347 struct ingress_qdisc_data *p = PRIV(sch); 343 struct ingress_qdisc_data *p = PRIV(sch);
348 struct tcf_proto *tp;
349 344
350 DPRINTK("ingress_destroy(sch %p,[qdisc %p])\n", sch, p); 345 DPRINTK("ingress_destroy(sch %p,[qdisc %p])\n", sch, p);
351 while (p->filter_list) { 346 tcf_destroy_chain(p->filter_list);
352 tp = p->filter_list;
353 p->filter_list = tp->next;
354 tcf_destroy(tp);
355 }
356#if 0 347#if 0
357/* for future use */ 348/* for future use */
358 qdisc_destroy(p->q); 349 qdisc_destroy(p->q);
@@ -362,16 +353,16 @@ static void ingress_destroy(struct Qdisc *sch)
362 353
363static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb) 354static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb)
364{ 355{
365 unsigned char *b = skb->tail; 356 unsigned char *b = skb_tail_pointer(skb);
366 struct rtattr *rta; 357 struct rtattr *rta;
367 358
368 rta = (struct rtattr *) b; 359 rta = (struct rtattr *) b;
369 RTA_PUT(skb, TCA_OPTIONS, 0, NULL); 360 RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
370 rta->rta_len = skb->tail - b; 361 rta->rta_len = skb_tail_pointer(skb) - b;
371 return skb->len; 362 return skb->len;
372 363
373rtattr_failure: 364rtattr_failure:
374 skb_trim(skb, b - skb->data); 365 nlmsg_trim(skb, b);
375 return -1; 366 return -1;
376} 367}
377 368
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 1ccbfb55b0b8..5d9d8bc9cc3a 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -22,6 +22,7 @@
22#include <linux/skbuff.h> 22#include <linux/skbuff.h>
23#include <linux/rtnetlink.h> 23#include <linux/rtnetlink.h>
24 24
25#include <net/netlink.h>
25#include <net/pkt_sched.h> 26#include <net/pkt_sched.h>
26 27
27#define VERSION "1.2" 28#define VERSION "1.2"
@@ -54,21 +55,22 @@
54 55
55struct netem_sched_data { 56struct netem_sched_data {
56 struct Qdisc *qdisc; 57 struct Qdisc *qdisc;
57 struct timer_list timer; 58 struct qdisc_watchdog watchdog;
59
60 psched_tdiff_t latency;
61 psched_tdiff_t jitter;
58 62
59 u32 latency;
60 u32 loss; 63 u32 loss;
61 u32 limit; 64 u32 limit;
62 u32 counter; 65 u32 counter;
63 u32 gap; 66 u32 gap;
64 u32 jitter;
65 u32 duplicate; 67 u32 duplicate;
66 u32 reorder; 68 u32 reorder;
67 u32 corrupt; 69 u32 corrupt;
68 70
69 struct crndstate { 71 struct crndstate {
70 unsigned long last; 72 u32 last;
71 unsigned long rho; 73 u32 rho;
72 } delay_cor, loss_cor, dup_cor, reorder_cor, corrupt_cor; 74 } delay_cor, loss_cor, dup_cor, reorder_cor, corrupt_cor;
73 75
74 struct disttable { 76 struct disttable {
@@ -95,12 +97,12 @@ static void init_crandom(struct crndstate *state, unsigned long rho)
95 * Next number depends on last value. 97 * Next number depends on last value.
96 * rho is scaled to avoid floating point. 98 * rho is scaled to avoid floating point.
97 */ 99 */
98static unsigned long get_crandom(struct crndstate *state) 100static u32 get_crandom(struct crndstate *state)
99{ 101{
100 u64 value, rho; 102 u64 value, rho;
101 unsigned long answer; 103 unsigned long answer;
102 104
103 if (state->rho == 0) /* no correllation */ 105 if (state->rho == 0) /* no correlation */
104 return net_random(); 106 return net_random();
105 107
106 value = net_random(); 108 value = net_random();
@@ -114,11 +116,13 @@ static unsigned long get_crandom(struct crndstate *state)
114 * std deviation sigma. Uses table lookup to approximate the desired 116 * std deviation sigma. Uses table lookup to approximate the desired
115 * distribution, and a uniformly-distributed pseudo-random source. 117 * distribution, and a uniformly-distributed pseudo-random source.
116 */ 118 */
117static long tabledist(unsigned long mu, long sigma, 119static psched_tdiff_t tabledist(psched_tdiff_t mu, psched_tdiff_t sigma,
118 struct crndstate *state, const struct disttable *dist) 120 struct crndstate *state,
121 const struct disttable *dist)
119{ 122{
120 long t, x; 123 psched_tdiff_t x;
121 unsigned long rnd; 124 long t;
125 u32 rnd;
122 126
123 if (sigma == 0) 127 if (sigma == 0)
124 return mu; 128 return mu;
@@ -213,8 +217,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
213 delay = tabledist(q->latency, q->jitter, 217 delay = tabledist(q->latency, q->jitter,
214 &q->delay_cor, q->delay_dist); 218 &q->delay_cor, q->delay_dist);
215 219
216 PSCHED_GET_TIME(now); 220 now = psched_get_time();
217 PSCHED_TADD2(now, delay, cb->time_to_send); 221 cb->time_to_send = now + delay;
218 ++q->counter; 222 ++q->counter;
219 ret = q->qdisc->enqueue(skb, q->qdisc); 223 ret = q->qdisc->enqueue(skb, q->qdisc);
220 } else { 224 } else {
@@ -222,7 +226,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
222 * Do re-ordering by putting one out of N packets at the front 226 * Do re-ordering by putting one out of N packets at the front
223 * of the queue. 227 * of the queue.
224 */ 228 */
225 PSCHED_GET_TIME(cb->time_to_send); 229 cb->time_to_send = psched_get_time();
226 q->counter = 0; 230 q->counter = 0;
227 ret = q->qdisc->ops->requeue(skb, q->qdisc); 231 ret = q->qdisc->ops->requeue(skb, q->qdisc);
228 } 232 }
@@ -269,55 +273,43 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
269 struct netem_sched_data *q = qdisc_priv(sch); 273 struct netem_sched_data *q = qdisc_priv(sch);
270 struct sk_buff *skb; 274 struct sk_buff *skb;
271 275
276 smp_mb();
277 if (sch->flags & TCQ_F_THROTTLED)
278 return NULL;
279
272 skb = q->qdisc->dequeue(q->qdisc); 280 skb = q->qdisc->dequeue(q->qdisc);
273 if (skb) { 281 if (skb) {
274 const struct netem_skb_cb *cb 282 const struct netem_skb_cb *cb
275 = (const struct netem_skb_cb *)skb->cb; 283 = (const struct netem_skb_cb *)skb->cb;
276 psched_time_t now; 284 psched_time_t now = psched_get_time();
277 285
278 /* if more time remaining? */ 286 /* if more time remaining? */
279 PSCHED_GET_TIME(now); 287 if (cb->time_to_send <= now) {
280
281 if (PSCHED_TLESS(cb->time_to_send, now)) {
282 pr_debug("netem_dequeue: return skb=%p\n", skb); 288 pr_debug("netem_dequeue: return skb=%p\n", skb);
283 sch->q.qlen--; 289 sch->q.qlen--;
284 sch->flags &= ~TCQ_F_THROTTLED;
285 return skb; 290 return skb;
286 } else { 291 }
287 psched_tdiff_t delay = PSCHED_TDIFF(cb->time_to_send, now);
288
289 if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
290 qdisc_tree_decrease_qlen(q->qdisc, 1);
291 sch->qstats.drops++;
292 printk(KERN_ERR "netem: queue discpline %s could not requeue\n",
293 q->qdisc->ops->id);
294 }
295 292
296 mod_timer(&q->timer, jiffies + PSCHED_US2JIFFIE(delay)); 293 if (unlikely(q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS)) {
297 sch->flags |= TCQ_F_THROTTLED; 294 qdisc_tree_decrease_qlen(q->qdisc, 1);
295 sch->qstats.drops++;
296 printk(KERN_ERR "netem: %s could not requeue\n",
297 q->qdisc->ops->id);
298 } 298 }
299
300 qdisc_watchdog_schedule(&q->watchdog, cb->time_to_send);
299 } 301 }
300 302
301 return NULL; 303 return NULL;
302} 304}
303 305
304static void netem_watchdog(unsigned long arg)
305{
306 struct Qdisc *sch = (struct Qdisc *)arg;
307
308 pr_debug("netem_watchdog qlen=%d\n", sch->q.qlen);
309 sch->flags &= ~TCQ_F_THROTTLED;
310 netif_schedule(sch->dev);
311}
312
313static void netem_reset(struct Qdisc *sch) 306static void netem_reset(struct Qdisc *sch)
314{ 307{
315 struct netem_sched_data *q = qdisc_priv(sch); 308 struct netem_sched_data *q = qdisc_priv(sch);
316 309
317 qdisc_reset(q->qdisc); 310 qdisc_reset(q->qdisc);
318 sch->q.qlen = 0; 311 sch->q.qlen = 0;
319 sch->flags &= ~TCQ_F_THROTTLED; 312 qdisc_watchdog_cancel(&q->watchdog);
320 del_timer_sync(&q->timer);
321} 313}
322 314
323/* Pass size change message down to embedded FIFO */ 315/* Pass size change message down to embedded FIFO */
@@ -438,10 +430,11 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt)
438 q->loss = qopt->loss; 430 q->loss = qopt->loss;
439 q->duplicate = qopt->duplicate; 431 q->duplicate = qopt->duplicate;
440 432
441 /* for compatiablity with earlier versions. 433 /* for compatibility with earlier versions.
442 * if gap is set, need to assume 100% probablity 434 * if gap is set, need to assume 100% probability
443 */ 435 */
444 q->reorder = ~0; 436 if (q->gap)
437 q->reorder = ~0;
445 438
446 /* Handle nested options after initial queue options. 439 /* Handle nested options after initial queue options.
447 * Should have put all options in nested format but too late now. 440 * Should have put all options in nested format but too late now.
@@ -487,22 +480,28 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt)
487 */ 480 */
488struct fifo_sched_data { 481struct fifo_sched_data {
489 u32 limit; 482 u32 limit;
483 psched_time_t oldest;
490}; 484};
491 485
492static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) 486static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
493{ 487{
494 struct fifo_sched_data *q = qdisc_priv(sch); 488 struct fifo_sched_data *q = qdisc_priv(sch);
495 struct sk_buff_head *list = &sch->q; 489 struct sk_buff_head *list = &sch->q;
496 const struct netem_skb_cb *ncb 490 psched_time_t tnext = ((struct netem_skb_cb *)nskb->cb)->time_to_send;
497 = (const struct netem_skb_cb *)nskb->cb;
498 struct sk_buff *skb; 491 struct sk_buff *skb;
499 492
500 if (likely(skb_queue_len(list) < q->limit)) { 493 if (likely(skb_queue_len(list) < q->limit)) {
494 /* Optimize for add at tail */
495 if (likely(skb_queue_empty(list) || tnext >= q->oldest)) {
496 q->oldest = tnext;
497 return qdisc_enqueue_tail(nskb, sch);
498 }
499
501 skb_queue_reverse_walk(list, skb) { 500 skb_queue_reverse_walk(list, skb) {
502 const struct netem_skb_cb *cb 501 const struct netem_skb_cb *cb
503 = (const struct netem_skb_cb *)skb->cb; 502 = (const struct netem_skb_cb *)skb->cb;
504 503
505 if (!PSCHED_TLESS(ncb->time_to_send, cb->time_to_send)) 504 if (tnext >= cb->time_to_send)
506 break; 505 break;
507 } 506 }
508 507
@@ -515,7 +514,7 @@ static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
515 return NET_XMIT_SUCCESS; 514 return NET_XMIT_SUCCESS;
516 } 515 }
517 516
518 return qdisc_drop(nskb, sch); 517 return qdisc_reshape_fail(nskb, sch);
519} 518}
520 519
521static int tfifo_init(struct Qdisc *sch, struct rtattr *opt) 520static int tfifo_init(struct Qdisc *sch, struct rtattr *opt)
@@ -531,6 +530,7 @@ static int tfifo_init(struct Qdisc *sch, struct rtattr *opt)
531 } else 530 } else
532 q->limit = max_t(u32, sch->dev->tx_queue_len, 1); 531 q->limit = max_t(u32, sch->dev->tx_queue_len, 1);
533 532
533 q->oldest = PSCHED_PASTPERFECT;
534 return 0; 534 return 0;
535} 535}
536 536
@@ -567,9 +567,7 @@ static int netem_init(struct Qdisc *sch, struct rtattr *opt)
567 if (!opt) 567 if (!opt)
568 return -EINVAL; 568 return -EINVAL;
569 569
570 init_timer(&q->timer); 570 qdisc_watchdog_init(&q->watchdog, sch);
571 q->timer.function = netem_watchdog;
572 q->timer.data = (unsigned long) sch;
573 571
574 q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops, 572 q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops,
575 TC_H_MAKE(sch->handle, 1)); 573 TC_H_MAKE(sch->handle, 1));
@@ -590,7 +588,7 @@ static void netem_destroy(struct Qdisc *sch)
590{ 588{
591 struct netem_sched_data *q = qdisc_priv(sch); 589 struct netem_sched_data *q = qdisc_priv(sch);
592 590
593 del_timer_sync(&q->timer); 591 qdisc_watchdog_cancel(&q->watchdog);
594 qdisc_destroy(q->qdisc); 592 qdisc_destroy(q->qdisc);
595 kfree(q->delay_dist); 593 kfree(q->delay_dist);
596} 594}
@@ -598,7 +596,7 @@ static void netem_destroy(struct Qdisc *sch)
598static int netem_dump(struct Qdisc *sch, struct sk_buff *skb) 596static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
599{ 597{
600 const struct netem_sched_data *q = qdisc_priv(sch); 598 const struct netem_sched_data *q = qdisc_priv(sch);
601 unsigned char *b = skb->tail; 599 unsigned char *b = skb_tail_pointer(skb);
602 struct rtattr *rta = (struct rtattr *) b; 600 struct rtattr *rta = (struct rtattr *) b;
603 struct tc_netem_qopt qopt; 601 struct tc_netem_qopt qopt;
604 struct tc_netem_corr cor; 602 struct tc_netem_corr cor;
@@ -626,12 +624,12 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
626 corrupt.correlation = q->corrupt_cor.rho; 624 corrupt.correlation = q->corrupt_cor.rho;
627 RTA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt); 625 RTA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
628 626
629 rta->rta_len = skb->tail - b; 627 rta->rta_len = skb_tail_pointer(skb) - b;
630 628
631 return skb->len; 629 return skb->len;
632 630
633rtattr_failure: 631rtattr_failure:
634 skb_trim(skb, b - skb->data); 632 nlmsg_trim(skb, b);
635 return -1; 633 return -1;
636} 634}
637 635
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index de889f23f22a..269a6e17c6c4 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -32,6 +32,7 @@
32#include <net/ip.h> 32#include <net/ip.h>
33#include <net/route.h> 33#include <net/route.h>
34#include <linux/skbuff.h> 34#include <linux/skbuff.h>
35#include <net/netlink.h>
35#include <net/sock.h> 36#include <net/sock.h>
36#include <net/pkt_sched.h> 37#include <net/pkt_sched.h>
37 38
@@ -61,7 +62,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
61 *qerr = NET_XMIT_SUCCESS; 62 *qerr = NET_XMIT_SUCCESS;
62 case TC_ACT_SHOT: 63 case TC_ACT_SHOT:
63 return NULL; 64 return NULL;
64 }; 65 }
65 66
66 if (!q->filter_list ) { 67 if (!q->filter_list ) {
67#else 68#else
@@ -188,13 +189,8 @@ prio_destroy(struct Qdisc* sch)
188{ 189{
189 int prio; 190 int prio;
190 struct prio_sched_data *q = qdisc_priv(sch); 191 struct prio_sched_data *q = qdisc_priv(sch);
191 struct tcf_proto *tp;
192
193 while ((tp = q->filter_list) != NULL) {
194 q->filter_list = tp->next;
195 tcf_destroy(tp);
196 }
197 192
193 tcf_destroy_chain(q->filter_list);
198 for (prio=0; prio<q->bands; prio++) 194 for (prio=0; prio<q->bands; prio++)
199 qdisc_destroy(q->queues[prio]); 195 qdisc_destroy(q->queues[prio]);
200} 196}
@@ -271,7 +267,7 @@ static int prio_init(struct Qdisc *sch, struct rtattr *opt)
271static int prio_dump(struct Qdisc *sch, struct sk_buff *skb) 267static int prio_dump(struct Qdisc *sch, struct sk_buff *skb)
272{ 268{
273 struct prio_sched_data *q = qdisc_priv(sch); 269 struct prio_sched_data *q = qdisc_priv(sch);
274 unsigned char *b = skb->tail; 270 unsigned char *b = skb_tail_pointer(skb);
275 struct tc_prio_qopt opt; 271 struct tc_prio_qopt opt;
276 272
277 opt.bands = q->bands; 273 opt.bands = q->bands;
@@ -280,7 +276,7 @@ static int prio_dump(struct Qdisc *sch, struct sk_buff *skb)
280 return skb->len; 276 return skb->len;
281 277
282rtattr_failure: 278rtattr_failure:
283 skb_trim(skb, b - skb->data); 279 nlmsg_trim(skb, b);
284 return -1; 280 return -1;
285} 281}
286 282
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 66f32051a99b..96dfdf78d32c 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -30,6 +30,7 @@
30#include <linux/notifier.h> 30#include <linux/notifier.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <net/ip.h> 32#include <net/ip.h>
33#include <net/netlink.h>
33#include <linux/ipv6.h> 34#include <linux/ipv6.h>
34#include <net/route.h> 35#include <net/route.h>
35#include <linux/skbuff.h> 36#include <linux/skbuff.h>
@@ -137,7 +138,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
137 switch (skb->protocol) { 138 switch (skb->protocol) {
138 case __constant_htons(ETH_P_IP): 139 case __constant_htons(ETH_P_IP):
139 { 140 {
140 struct iphdr *iph = skb->nh.iph; 141 const struct iphdr *iph = ip_hdr(skb);
141 h = iph->daddr; 142 h = iph->daddr;
142 h2 = iph->saddr^iph->protocol; 143 h2 = iph->saddr^iph->protocol;
143 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && 144 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
@@ -152,7 +153,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
152 } 153 }
153 case __constant_htons(ETH_P_IPV6): 154 case __constant_htons(ETH_P_IPV6):
154 { 155 {
155 struct ipv6hdr *iph = skb->nh.ipv6h; 156 struct ipv6hdr *iph = ipv6_hdr(skb);
156 h = iph->daddr.s6_addr32[3]; 157 h = iph->daddr.s6_addr32[3];
157 h2 = iph->saddr.s6_addr32[3]^iph->nexthdr; 158 h2 = iph->saddr.s6_addr32[3]^iph->nexthdr;
158 if (iph->nexthdr == IPPROTO_TCP || 159 if (iph->nexthdr == IPPROTO_TCP ||
@@ -461,7 +462,7 @@ static void sfq_destroy(struct Qdisc *sch)
461static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb) 462static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)
462{ 463{
463 struct sfq_sched_data *q = qdisc_priv(sch); 464 struct sfq_sched_data *q = qdisc_priv(sch);
464 unsigned char *b = skb->tail; 465 unsigned char *b = skb_tail_pointer(skb);
465 struct tc_sfq_qopt opt; 466 struct tc_sfq_qopt opt;
466 467
467 opt.quantum = q->quantum; 468 opt.quantum = q->quantum;
@@ -476,7 +477,7 @@ static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)
476 return skb->len; 477 return skb->len;
477 478
478rtattr_failure: 479rtattr_failure:
479 skb_trim(skb, b - skb->data); 480 nlmsg_trim(skb, b);
480 return -1; 481 return -1;
481} 482}
482 483
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 85da8daa61d2..53862953baaf 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -32,6 +32,7 @@
32#include <linux/etherdevice.h> 32#include <linux/etherdevice.h>
33#include <linux/notifier.h> 33#include <linux/notifier.h>
34#include <net/ip.h> 34#include <net/ip.h>
35#include <net/netlink.h>
35#include <net/route.h> 36#include <net/route.h>
36#include <linux/skbuff.h> 37#include <linux/skbuff.h>
37#include <net/sock.h> 38#include <net/sock.h>
@@ -127,8 +128,8 @@ struct tbf_sched_data
127 long tokens; /* Current number of B tokens */ 128 long tokens; /* Current number of B tokens */
128 long ptokens; /* Current number of P tokens */ 129 long ptokens; /* Current number of P tokens */
129 psched_time_t t_c; /* Time check-point */ 130 psched_time_t t_c; /* Time check-point */
130 struct timer_list wd_timer; /* Watchdog timer */
131 struct Qdisc *qdisc; /* Inner qdisc, default - bfifo queue */ 131 struct Qdisc *qdisc; /* Inner qdisc, default - bfifo queue */
132 struct qdisc_watchdog watchdog; /* Watchdog timer */
132}; 133};
133 134
134#define L2T(q,L) ((q)->R_tab->data[(L)>>(q)->R_tab->rate.cell_log]) 135#define L2T(q,L) ((q)->R_tab->data[(L)>>(q)->R_tab->rate.cell_log])
@@ -185,14 +186,6 @@ static unsigned int tbf_drop(struct Qdisc* sch)
185 return len; 186 return len;
186} 187}
187 188
188static void tbf_watchdog(unsigned long arg)
189{
190 struct Qdisc *sch = (struct Qdisc*)arg;
191
192 sch->flags &= ~TCQ_F_THROTTLED;
193 netif_schedule(sch->dev);
194}
195
196static struct sk_buff *tbf_dequeue(struct Qdisc* sch) 189static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
197{ 190{
198 struct tbf_sched_data *q = qdisc_priv(sch); 191 struct tbf_sched_data *q = qdisc_priv(sch);
@@ -202,13 +195,12 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
202 195
203 if (skb) { 196 if (skb) {
204 psched_time_t now; 197 psched_time_t now;
205 long toks, delay; 198 long toks;
206 long ptoks = 0; 199 long ptoks = 0;
207 unsigned int len = skb->len; 200 unsigned int len = skb->len;
208 201
209 PSCHED_GET_TIME(now); 202 now = psched_get_time();
210 203 toks = psched_tdiff_bounded(now, q->t_c, q->buffer);
211 toks = PSCHED_TDIFF_SAFE(now, q->t_c, q->buffer);
212 204
213 if (q->P_tab) { 205 if (q->P_tab) {
214 ptoks = toks + q->ptokens; 206 ptoks = toks + q->ptokens;
@@ -230,12 +222,8 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
230 return skb; 222 return skb;
231 } 223 }
232 224
233 delay = PSCHED_US2JIFFIE(max_t(long, -toks, -ptoks)); 225 qdisc_watchdog_schedule(&q->watchdog,
234 226 now + max_t(long, -toks, -ptoks));
235 if (delay == 0)
236 delay = 1;
237
238 mod_timer(&q->wd_timer, jiffies+delay);
239 227
240 /* Maybe we have a shorter packet in the queue, 228 /* Maybe we have a shorter packet in the queue,
241 which can be sent now. It sounds cool, 229 which can be sent now. It sounds cool,
@@ -254,7 +242,6 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
254 sch->qstats.drops++; 242 sch->qstats.drops++;
255 } 243 }
256 244
257 sch->flags |= TCQ_F_THROTTLED;
258 sch->qstats.overlimits++; 245 sch->qstats.overlimits++;
259 } 246 }
260 return NULL; 247 return NULL;
@@ -266,11 +253,10 @@ static void tbf_reset(struct Qdisc* sch)
266 253
267 qdisc_reset(q->qdisc); 254 qdisc_reset(q->qdisc);
268 sch->q.qlen = 0; 255 sch->q.qlen = 0;
269 PSCHED_GET_TIME(q->t_c); 256 q->t_c = psched_get_time();
270 q->tokens = q->buffer; 257 q->tokens = q->buffer;
271 q->ptokens = q->mtu; 258 q->ptokens = q->mtu;
272 sch->flags &= ~TCQ_F_THROTTLED; 259 qdisc_watchdog_cancel(&q->watchdog);
273 del_timer(&q->wd_timer);
274} 260}
275 261
276static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit) 262static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit)
@@ -377,11 +363,8 @@ static int tbf_init(struct Qdisc* sch, struct rtattr *opt)
377 if (opt == NULL) 363 if (opt == NULL)
378 return -EINVAL; 364 return -EINVAL;
379 365
380 PSCHED_GET_TIME(q->t_c); 366 q->t_c = psched_get_time();
381 init_timer(&q->wd_timer); 367 qdisc_watchdog_init(&q->watchdog, sch);
382 q->wd_timer.function = tbf_watchdog;
383 q->wd_timer.data = (unsigned long)sch;
384
385 q->qdisc = &noop_qdisc; 368 q->qdisc = &noop_qdisc;
386 369
387 return tbf_change(sch, opt); 370 return tbf_change(sch, opt);
@@ -391,7 +374,7 @@ static void tbf_destroy(struct Qdisc *sch)
391{ 374{
392 struct tbf_sched_data *q = qdisc_priv(sch); 375 struct tbf_sched_data *q = qdisc_priv(sch);
393 376
394 del_timer(&q->wd_timer); 377 qdisc_watchdog_cancel(&q->watchdog);
395 378
396 if (q->P_tab) 379 if (q->P_tab)
397 qdisc_put_rtab(q->P_tab); 380 qdisc_put_rtab(q->P_tab);
@@ -404,7 +387,7 @@ static void tbf_destroy(struct Qdisc *sch)
404static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) 387static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
405{ 388{
406 struct tbf_sched_data *q = qdisc_priv(sch); 389 struct tbf_sched_data *q = qdisc_priv(sch);
407 unsigned char *b = skb->tail; 390 unsigned char *b = skb_tail_pointer(skb);
408 struct rtattr *rta; 391 struct rtattr *rta;
409 struct tc_tbf_qopt opt; 392 struct tc_tbf_qopt opt;
410 393
@@ -420,12 +403,12 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
420 opt.mtu = q->mtu; 403 opt.mtu = q->mtu;
421 opt.buffer = q->buffer; 404 opt.buffer = q->buffer;
422 RTA_PUT(skb, TCA_TBF_PARMS, sizeof(opt), &opt); 405 RTA_PUT(skb, TCA_TBF_PARMS, sizeof(opt), &opt);
423 rta->rta_len = skb->tail - b; 406 rta->rta_len = skb_tail_pointer(skb) - b;
424 407
425 return skb->len; 408 return skb->len;
426 409
427rtattr_failure: 410rtattr_failure:
428 skb_trim(skb, b - skb->data); 411 nlmsg_trim(skb, b);
429 return -1; 412 return -1;
430} 413}
431 414
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 587123c61af9..d24914db7861 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -323,7 +323,7 @@ restart:
323 nores = 1; 323 nores = 1;
324 break; 324 break;
325 } 325 }
326 __skb_pull(skb, skb->nh.raw - skb->data); 326 __skb_pull(skb, skb_network_offset(skb));
327 } while ((q = NEXT_SLAVE(q)) != start); 327 } while ((q = NEXT_SLAVE(q)) != start);
328 328
329 if (nores && skb_res == NULL) { 329 if (nores && skb_res == NULL) {