Commit b00355db authored by Jarek Poplawski's avatar Jarek Poplawski Committed by David S. Miller

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: default avatarJarek Poplawski <jarkao2@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eefef1cf
...@@ -85,6 +85,7 @@ extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, ...@@ -85,6 +85,7 @@ extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
struct nlattr *tab); struct nlattr *tab);
extern void qdisc_put_rtab(struct qdisc_rate_table *tab); extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
extern void qdisc_put_stab(struct qdisc_size_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); extern void __qdisc_run(struct Qdisc *q);
......
...@@ -42,9 +42,10 @@ struct Qdisc ...@@ -42,9 +42,10 @@ struct Qdisc
int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev); int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
struct sk_buff * (*dequeue)(struct Qdisc *dev); struct sk_buff * (*dequeue)(struct Qdisc *dev);
unsigned flags; unsigned flags;
#define TCQ_F_BUILTIN 1 #define TCQ_F_BUILTIN 1
#define TCQ_F_THROTTLED 2 #define TCQ_F_THROTTLED 2
#define TCQ_F_INGRESS 4 #define TCQ_F_INGRESS 4
#define TCQ_F_WARN_NONWC (1 << 16)
int padded; int padded;
struct Qdisc_ops *ops; struct Qdisc_ops *ops;
struct qdisc_size_table *stab; struct qdisc_size_table *stab;
......
...@@ -444,6 +444,17 @@ void qdisc_calculate_pkt_len(struct sk_buff *skb, struct qdisc_size_table *stab) ...@@ -444,6 +444,17 @@ void qdisc_calculate_pkt_len(struct sk_buff *skb, struct qdisc_size_table *stab)
} }
EXPORT_SYMBOL(qdisc_calculate_pkt_len); 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) static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
{ {
struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog, struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog,
......
...@@ -887,8 +887,7 @@ qdisc_peek_len(struct Qdisc *sch) ...@@ -887,8 +887,7 @@ qdisc_peek_len(struct Qdisc *sch)
skb = sch->ops->peek(sch); skb = sch->ops->peek(sch);
if (skb == NULL) { if (skb == NULL) {
if (net_ratelimit()) qdisc_warn_nonwc("qdisc_peek_len", sch);
printk("qdisc_peek_len: non work-conserving qdisc ?\n");
return 0; return 0;
} }
len = qdisc_pkt_len(skb); len = qdisc_pkt_len(skb);
...@@ -1642,8 +1641,7 @@ hfsc_dequeue(struct Qdisc *sch) ...@@ -1642,8 +1641,7 @@ hfsc_dequeue(struct Qdisc *sch)
skb = qdisc_dequeue_peeked(cl->qdisc); skb = qdisc_dequeue_peeked(cl->qdisc);
if (skb == NULL) { if (skb == NULL) {
if (net_ratelimit()) qdisc_warn_nonwc("HFSC", cl->qdisc);
printk("HFSC: Non-work-conserving qdisc ?\n");
return NULL; return NULL;
} }
......
...@@ -114,8 +114,6 @@ struct htb_class { ...@@ -114,8 +114,6 @@ struct htb_class {
struct tcf_proto *filter_list; struct tcf_proto *filter_list;
int filter_cnt; int filter_cnt;
int warned; /* only one warning about non work conserving .. */
/* token bucket parameters */ /* token bucket parameters */
struct qdisc_rate_table *rate; /* rate table of the class itself */ struct qdisc_rate_table *rate; /* rate table of the class itself */
struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */ struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */
...@@ -809,13 +807,8 @@ static struct sk_buff *htb_dequeue_tree(struct htb_sched *q, int prio, ...@@ -809,13 +807,8 @@ static struct sk_buff *htb_dequeue_tree(struct htb_sched *q, int prio,
skb = cl->un.leaf.q->dequeue(cl->un.leaf.q); skb = cl->un.leaf.q->dequeue(cl->un.leaf.q);
if (likely(skb != NULL)) if (likely(skb != NULL))
break; 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-> htb_next_rb_node((level ? cl->parent->un.inner.ptr : q->
ptr[0]) + prio); ptr[0]) + prio);
cl = htb_lookup_leaf(q->row[level] + prio, prio, cl = htb_lookup_leaf(q->row[level] + prio, prio,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment