aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarek Poplawski <jarkao2@gmail.com>2009-02-01 04:12:42 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-01 04:12:42 -0500
commitb00355db3f88d96810a60011a30cfb2c3469409d (patch)
tree43331c769665e619892d8f97a38ce1d12b3a6363
parenteefef1cf7653cd4e0aaf743c00ae8345086cdc01 (diff)
pkt_sched: sch_hfsc: sch_htb: Add non-work-conserving warning handler.
Patrick McHardy <kaber@trash.net> suggested: > How about making this flag and the warning message (in a out-of-line > function) globally available? Other qdiscs (f.i. HFSC) can't deal with > inner non-work-conserving qdiscs as well. This patch uses qdisc->flags field of "suspected" child qdisc. Signed-off-by: Jarek Poplawski <jarkao2@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/pkt_sched.h1
-rw-r--r--include/net/sch_generic.h7
-rw-r--r--net/sched/sch_api.c11
-rw-r--r--net/sched/sch_hfsc.c6
-rw-r--r--net/sched/sch_htb.c9
5 files changed, 19 insertions, 15 deletions
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 4082f39f5079..e37fe3129c17 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -85,6 +85,7 @@ extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
85 struct nlattr *tab); 85 struct nlattr *tab);
86extern void qdisc_put_rtab(struct qdisc_rate_table *tab); 86extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
87extern void qdisc_put_stab(struct qdisc_size_table *tab); 87extern void qdisc_put_stab(struct qdisc_size_table *tab);
88extern void qdisc_warn_nonwc(char *txt, struct Qdisc *qdisc);
88 89
89extern void __qdisc_run(struct Qdisc *q); 90extern void __qdisc_run(struct Qdisc *q);
90 91
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index f8c47429044a..3d78a4d22460 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -42,9 +42,10 @@ struct Qdisc
42 int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev); 42 int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
43 struct sk_buff * (*dequeue)(struct Qdisc *dev); 43 struct sk_buff * (*dequeue)(struct Qdisc *dev);
44 unsigned flags; 44 unsigned flags;
45#define TCQ_F_BUILTIN 1 45#define TCQ_F_BUILTIN 1
46#define TCQ_F_THROTTLED 2 46#define TCQ_F_THROTTLED 2
47#define TCQ_F_INGRESS 4 47#define TCQ_F_INGRESS 4
48#define TCQ_F_WARN_NONWC (1 << 16)
48 int padded; 49 int padded;
49 struct Qdisc_ops *ops; 50 struct Qdisc_ops *ops;
50 struct qdisc_size_table *stab; 51 struct qdisc_size_table *stab;
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..77ff510ef8ac 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -114,8 +114,6 @@ struct htb_class {
114 struct tcf_proto *filter_list; 114 struct tcf_proto *filter_list;
115 int filter_cnt; 115 int filter_cnt;
116 116
117 int warned; /* only one warning about non work conserving .. */
118
119 /* token bucket parameters */ 117 /* token bucket parameters */
120 struct qdisc_rate_table *rate; /* rate table of the class itself */ 118 struct qdisc_rate_table *rate; /* rate table of the class itself */
121 struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */ 119 struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */
@@ -809,13 +807,8 @@ next:
809 skb = cl->un.leaf.q->dequeue(cl->un.leaf.q); 807 skb = cl->un.leaf.q->dequeue(cl->un.leaf.q);
810 if (likely(skb != NULL)) 808 if (likely(skb != NULL))
811 break; 809 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 810
811 qdisc_warn_nonwc("htb", cl->un.leaf.q);
819 htb_next_rb_node((level ? cl->parent->un.inner.ptr : q-> 812 htb_next_rb_node((level ? cl->parent->un.inner.ptr : q->
820 ptr[0]) + prio); 813 ptr[0]) + prio);
821 cl = htb_lookup_leaf(q->row[level] + prio, prio, 814 cl = htb_lookup_leaf(q->row[level] + prio, prio,