aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2014-06-11 14:35:18 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-11 18:50:59 -0400
commit6e765a009ad33845033f94cf47159327f2ba59db (patch)
tree0e5295da4f6d42fae7336285367c577b5db7de50
parentf3591fd4c9881889dfa9203328a89316fcc834e1 (diff)
net_sched: drr: warn when qdisc is not work conserving
The DRR scheduler requires that items on the active list are work conserving, i.e. do not hold on to skbs for throttling purposes, etc. Attaching e.g. tbf renders DRR useless because all other classes on the active list are delayed as well. So, warn users that this configuration won't work as expected; we already do this in couple of other qdiscs, see e.g. commit b00355db3f88d96810a60011a30cfb2c3469409d ('pkt_sched: sch_hfsc: sch_htb: Add non-work-conserving warning handler') The 'const' change is needed to avoid compiler warning ("discards 'const' qualifier from pointer target type"). tested with: drr_hier() { parent=$1 classes=$2 for i in $(seq 1 $classes); do classid=$parent$(printf %x $i) tc class add dev eth0 parent $parent classid $classid drr tc qdisc add dev eth0 parent $classid tbf rate 64kbit burst 256kbit limit 64kbit done } tc qdisc add dev eth0 root handle 1: drr drr_hier 1: 32 tc filter add dev eth0 protocol all pref 1 parent 1: handle 1 flow hash keys dst perturb 1 divisor 32 Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/pkt_sched.h2
-rw-r--r--net/sched/sch_api.c2
-rw-r--r--net/sched/sch_drr.c4
3 files changed, 5 insertions, 3 deletions
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 891d80d2c4d2..ec030cd76616 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -96,7 +96,7 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
96 struct nlattr *tab); 96 struct nlattr *tab);
97void qdisc_put_rtab(struct qdisc_rate_table *tab); 97void qdisc_put_rtab(struct qdisc_rate_table *tab);
98void qdisc_put_stab(struct qdisc_size_table *tab); 98void qdisc_put_stab(struct qdisc_size_table *tab);
99void qdisc_warn_nonwc(char *txt, struct Qdisc *qdisc); 99void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc);
100int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, 100int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
101 struct net_device *dev, struct netdev_queue *txq, 101 struct net_device *dev, struct netdev_queue *txq,
102 spinlock_t *root_lock); 102 spinlock_t *root_lock);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index fd14df56e5ff..58bed7599db7 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -563,7 +563,7 @@ out:
563} 563}
564EXPORT_SYMBOL(__qdisc_calculate_pkt_len); 564EXPORT_SYMBOL(__qdisc_calculate_pkt_len);
565 565
566void qdisc_warn_nonwc(char *txt, struct Qdisc *qdisc) 566void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc)
567{ 567{
568 if (!(qdisc->flags & TCQ_F_WARN_NONWC)) { 568 if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
569 pr_warn("%s: %s qdisc %X: is non-work-conserving?\n", 569 pr_warn("%s: %s qdisc %X: is non-work-conserving?\n",
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 8302717ea303..7bbbfe112192 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -391,8 +391,10 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch)
391 while (1) { 391 while (1) {
392 cl = list_first_entry(&q->active, struct drr_class, alist); 392 cl = list_first_entry(&q->active, struct drr_class, alist);
393 skb = cl->qdisc->ops->peek(cl->qdisc); 393 skb = cl->qdisc->ops->peek(cl->qdisc);
394 if (skb == NULL) 394 if (skb == NULL) {
395 qdisc_warn_nonwc(__func__, cl->qdisc);
395 goto out; 396 goto out;
397 }
396 398
397 len = qdisc_pkt_len(skb); 399 len = qdisc_pkt_len(skb);
398 if (len <= cl->deficit) { 400 if (len <= cl->deficit) {