aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/sch_api.c11
-rw-r--r--net/sched/sch_hfsc.c6
-rw-r--r--net/sched/sch_htb.c42
-rw-r--r--net/sched/sch_multiq.c2
4 files changed, 43 insertions, 18 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 0fc4a18fd96f..32009793307b 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -444,6 +444,17 @@ out:
444} 444}
445EXPORT_SYMBOL(qdisc_calculate_pkt_len); 445EXPORT_SYMBOL(qdisc_calculate_pkt_len);
446 446
447void qdisc_warn_nonwc(char *txt, struct Qdisc *qdisc)
448{
449 if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
450 printk(KERN_WARNING
451 "%s: %s qdisc %X: is non-work-conserving?\n",
452 txt, qdisc->ops->id, qdisc->handle >> 16);
453 qdisc->flags |= TCQ_F_WARN_NONWC;
454 }
455}
456EXPORT_SYMBOL(qdisc_warn_nonwc);
457
447static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer) 458static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
448{ 459{
449 struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog, 460 struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog,
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 45c31b1a4e1d..74226b265528 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -887,8 +887,7 @@ qdisc_peek_len(struct Qdisc *sch)
887 887
888 skb = sch->ops->peek(sch); 888 skb = sch->ops->peek(sch);
889 if (skb == NULL) { 889 if (skb == NULL) {
890 if (net_ratelimit()) 890 qdisc_warn_nonwc("qdisc_peek_len", sch);
891 printk("qdisc_peek_len: non work-conserving qdisc ?\n");
892 return 0; 891 return 0;
893 } 892 }
894 len = qdisc_pkt_len(skb); 893 len = qdisc_pkt_len(skb);
@@ -1642,8 +1641,7 @@ hfsc_dequeue(struct Qdisc *sch)
1642 1641
1643 skb = qdisc_dequeue_peeked(cl->qdisc); 1642 skb = qdisc_dequeue_peeked(cl->qdisc);
1644 if (skb == NULL) { 1643 if (skb == NULL) {
1645 if (net_ratelimit()) 1644 qdisc_warn_nonwc("HFSC", cl->qdisc);
1646 printk("HFSC: Non-work-conserving qdisc ?\n");
1647 return NULL; 1645 return NULL;
1648 } 1646 }
1649 1647
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 2f0f0b04d3fb..355974f610c5 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -35,6 +35,7 @@
35#include <linux/list.h> 35#include <linux/list.h>
36#include <linux/compiler.h> 36#include <linux/compiler.h>
37#include <linux/rbtree.h> 37#include <linux/rbtree.h>
38#include <linux/workqueue.h>
38#include <net/netlink.h> 39#include <net/netlink.h>
39#include <net/pkt_sched.h> 40#include <net/pkt_sched.h>
40 41
@@ -114,8 +115,6 @@ struct htb_class {
114 struct tcf_proto *filter_list; 115 struct tcf_proto *filter_list;
115 int filter_cnt; 116 int filter_cnt;
116 117
117 int warned; /* only one warning about non work conserving .. */
118
119 /* token bucket parameters */ 118 /* token bucket parameters */
120 struct qdisc_rate_table *rate; /* rate table of the class itself */ 119 struct qdisc_rate_table *rate; /* rate table of the class itself */
121 struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */ 120 struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */
@@ -155,6 +154,10 @@ struct htb_sched {
155 int direct_qlen; /* max qlen of above */ 154 int direct_qlen; /* max qlen of above */
156 155
157 long direct_pkts; 156 long direct_pkts;
157
158#define HTB_WARN_TOOMANYEVENTS 0x1
159 unsigned int warned; /* only one warning */
160 struct work_struct work;
158}; 161};
159 162
160/* find class in global hash table using given handle */ 163/* find class in global hash table using given handle */
@@ -658,7 +661,7 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
658 * htb_do_events - make mode changes to classes at the level 661 * htb_do_events - make mode changes to classes at the level
659 * 662 *
660 * Scans event queue for pending events and applies them. Returns time of 663 * Scans event queue for pending events and applies them. Returns time of
661 * next pending event (0 for no event in pq). 664 * next pending event (0 for no event in pq, q->now for too many events).
662 * Note: Applied are events whose have cl->pq_key <= q->now. 665 * Note: Applied are events whose have cl->pq_key <= q->now.
663 */ 666 */
664static psched_time_t htb_do_events(struct htb_sched *q, int level, 667static psched_time_t htb_do_events(struct htb_sched *q, int level,
@@ -686,8 +689,14 @@ static psched_time_t htb_do_events(struct htb_sched *q, int level,
686 if (cl->cmode != HTB_CAN_SEND) 689 if (cl->cmode != HTB_CAN_SEND)
687 htb_add_to_wait_tree(q, cl, diff); 690 htb_add_to_wait_tree(q, cl, diff);
688 } 691 }
689 /* too much load - let's continue on next jiffie (including above) */ 692
690 return q->now + 2 * PSCHED_TICKS_PER_SEC / HZ; 693 /* too much load - let's continue after a break for scheduling */
694 if (!(q->warned & HTB_WARN_TOOMANYEVENTS)) {
695 printk(KERN_WARNING "htb: too many events!\n");
696 q->warned |= HTB_WARN_TOOMANYEVENTS;
697 }
698
699 return q->now;
691} 700}
692 701
693/* Returns class->node+prio from id-tree where classe's id is >= id. NULL 702/* Returns class->node+prio from id-tree where classe's id is >= id. NULL
@@ -809,13 +818,8 @@ next:
809 skb = cl->un.leaf.q->dequeue(cl->un.leaf.q); 818 skb = cl->un.leaf.q->dequeue(cl->un.leaf.q);
810 if (likely(skb != NULL)) 819 if (likely(skb != NULL))
811 break; 820 break;
812 if (!cl->warned) {
813 printk(KERN_WARNING
814 "htb: class %X isn't work conserving ?!\n",
815 cl->common.classid);
816 cl->warned = 1;
817 }
818 821
822 qdisc_warn_nonwc("htb", cl->un.leaf.q);
819 htb_next_rb_node((level ? cl->parent->un.inner.ptr : q-> 823 htb_next_rb_node((level ? cl->parent->un.inner.ptr : q->
820 ptr[0]) + prio); 824 ptr[0]) + prio);
821 cl = htb_lookup_leaf(q->row[level] + prio, prio, 825 cl = htb_lookup_leaf(q->row[level] + prio, prio,
@@ -892,7 +896,10 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
892 } 896 }
893 } 897 }
894 sch->qstats.overlimits++; 898 sch->qstats.overlimits++;
895 qdisc_watchdog_schedule(&q->watchdog, next_event); 899 if (likely(next_event > q->now))
900 qdisc_watchdog_schedule(&q->watchdog, next_event);
901 else
902 schedule_work(&q->work);
896fin: 903fin:
897 return skb; 904 return skb;
898} 905}
@@ -962,6 +969,14 @@ static const struct nla_policy htb_policy[TCA_HTB_MAX + 1] = {
962 [TCA_HTB_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, 969 [TCA_HTB_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
963}; 970};
964 971
972static void htb_work_func(struct work_struct *work)
973{
974 struct htb_sched *q = container_of(work, struct htb_sched, work);
975 struct Qdisc *sch = q->watchdog.qdisc;
976
977 __netif_schedule(qdisc_root(sch));
978}
979
965static int htb_init(struct Qdisc *sch, struct nlattr *opt) 980static int htb_init(struct Qdisc *sch, struct nlattr *opt)
966{ 981{
967 struct htb_sched *q = qdisc_priv(sch); 982 struct htb_sched *q = qdisc_priv(sch);
@@ -996,6 +1011,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)
996 INIT_LIST_HEAD(q->drops + i); 1011 INIT_LIST_HEAD(q->drops + i);
997 1012
998 qdisc_watchdog_init(&q->watchdog, sch); 1013 qdisc_watchdog_init(&q->watchdog, sch);
1014 INIT_WORK(&q->work, htb_work_func);
999 skb_queue_head_init(&q->direct_queue); 1015 skb_queue_head_init(&q->direct_queue);
1000 1016
1001 q->direct_qlen = qdisc_dev(sch)->tx_queue_len; 1017 q->direct_qlen = qdisc_dev(sch)->tx_queue_len;
@@ -1188,7 +1204,6 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl)
1188 kfree(cl); 1204 kfree(cl);
1189} 1205}
1190 1206
1191/* always caled under BH & queue lock */
1192static void htb_destroy(struct Qdisc *sch) 1207static void htb_destroy(struct Qdisc *sch)
1193{ 1208{
1194 struct htb_sched *q = qdisc_priv(sch); 1209 struct htb_sched *q = qdisc_priv(sch);
@@ -1196,6 +1211,7 @@ static void htb_destroy(struct Qdisc *sch)
1196 struct htb_class *cl; 1211 struct htb_class *cl;
1197 unsigned int i; 1212 unsigned int i;
1198 1213
1214 cancel_work_sync(&q->work);
1199 qdisc_watchdog_cancel(&q->watchdog); 1215 qdisc_watchdog_cancel(&q->watchdog);
1200 /* This line used to be after htb_destroy_class call below 1216 /* This line used to be after htb_destroy_class call below
1201 and surprisingly it worked in 2.4. But it must precede it 1217 and surprisingly it worked in 2.4. But it must precede it
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 7e151861794b..912731203047 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -202,7 +202,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
202 int i; 202 int i;
203 203
204 if (!netif_is_multiqueue(qdisc_dev(sch))) 204 if (!netif_is_multiqueue(qdisc_dev(sch)))
205 return -EINVAL; 205 return -EOPNOTSUPP;
206 if (nla_len(opt) < sizeof(*qopt)) 206 if (nla_len(opt) < sizeof(*qopt))
207 return -EINVAL; 207 return -EINVAL;
208 208