aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarek Poplawski <jarkao2@gmail.com>2009-02-01 01:12:42 -0800
committerDavid S. Miller <davem@davemloft.net>2009-02-01 01:12:42 -0800
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 4082f39f507..e37fe3129c1 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,
struct nlattr *tab);
extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
extern void qdisc_put_stab(struct qdisc_size_table *tab);
+extern void qdisc_warn_nonwc(char *txt, struct Qdisc *qdisc);
extern void __qdisc_run(struct Qdisc *q);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index f8c47429044..3d78a4d2246 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -42,9 +42,10 @@ struct Qdisc
int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
struct sk_buff * (*dequeue)(struct Qdisc *dev);
unsigned flags;
-#define TCQ_F_BUILTIN 1
-#define TCQ_F_THROTTLED 2
-#define TCQ_F_INGRESS 4
+#define TCQ_F_BUILTIN 1
+#define TCQ_F_THROTTLED 2
+#define TCQ_F_INGRESS 4
+#define TCQ_F_WARN_NONWC (1 << 16)
int padded;
struct Qdisc_ops *ops;
struct qdisc_size_table *stab;
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 0fc4a18fd96..32009793307 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -444,6 +444,17 @@ out:
}
EXPORT_SYMBOL(qdisc_calculate_pkt_len);
+void qdisc_warn_nonwc(char *txt, struct Qdisc *qdisc)
+{
+ if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
+ printk(KERN_WARNING
+ "%s: %s qdisc %X: is non-work-conserving?\n",
+ txt, qdisc->ops->id, qdisc->handle >> 16);
+ qdisc->flags |= TCQ_F_WARN_NONWC;
+ }
+}
+EXPORT_SYMBOL(qdisc_warn_nonwc);
+
static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
{
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 45c31b1a4e1..74226b26552 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -887,8 +887,7 @@ qdisc_peek_len(struct Qdisc *sch)
skb = sch->ops->peek(sch);
if (skb == NULL) {
- if (net_ratelimit())
- printk("qdisc_peek_len: non work-conserving qdisc ?\n");
+ qdisc_warn_nonwc("qdisc_peek_len", sch);
return 0;
}
len = qdisc_pkt_len(skb);
@@ -1642,8 +1641,7 @@ hfsc_dequeue(struct Qdisc *sch)
skb = qdisc_dequeue_peeked(cl->qdisc);
if (skb == NULL) {
- if (net_ratelimit())
- printk("HFSC: Non-work-conserving qdisc ?\n");
+ qdisc_warn_nonwc("HFSC", cl->qdisc);
return NULL;
}
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 2f0f0b04d3f..77ff510ef8a 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -114,8 +114,6 @@ struct htb_class {
struct tcf_proto *filter_list;
int filter_cnt;
- int warned; /* only one warning about non work conserving .. */
-
/* token bucket parameters */
struct qdisc_rate_table *rate; /* rate table of the class itself */
struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */
@@ -809,13 +807,8 @@ next:
skb = cl->un.leaf.q->dequeue(cl->un.leaf.q);
if (likely(skb != NULL))
break;
- if (!cl->warned) {
- printk(KERN_WARNING
- "htb: class %X isn't work conserving ?!\n",
- cl->common.classid);
- cl->warned = 1;
- }
+ qdisc_warn_nonwc("htb", cl->un.leaf.q);
htb_next_rb_node((level ? cl->parent->un.inner.ptr : q->
ptr[0]) + prio);
cl = htb_lookup_leaf(q->row[level] + prio, prio,