summaryrefslogtreecommitdiff
path: root/net/sched
diff options
context:
space:
mode:
authorTianyi Gou <tgou@codeaurora.org>2012-06-26 10:11:05 -0600
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:05:55 -0700
commit12fae71b184dade2cedf154bbc8fd7870c5cd71c (patch)
tree091a565b8045b29831cf1ddec547e494bbff517c /net/sched
parent6ff0325a57b4a29c2f7d745e7cba68b51034a7e1 (diff)
net: sched: Schedule PRIO qdisc when flow control released
The PRIO qdisc supports flow control, such that packet dequeue can be disabled based on boolean flag 'enable_flow'. When flow is re-enabled, the latency for new packets arriving at network driver is high. To reduce the delay in scheduling packets, the qdisc will now invoke __netif_schedule() to expedite dequeue. This significantly reduces the latency of packets arriving at network driver. Change-Id: Ic5fe3faf86f177300d3018b9f60974ba3811641c CRs-Fixed: 355156 Acked-by: Jimi Shah <jimis@qualcomm.com> Signed-off-by: Tianyi Gou <tgou@codeaurora.org>
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/sch_prio.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index a8891a51af34..59ef2daf652c 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
+#include <linux/netdevice.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
@@ -178,6 +179,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
struct prio_sched_data *q = qdisc_priv(sch);
struct tc_prio_qopt *qopt;
int i;
+ int flow_change = 0;
if (nla_len(opt) < sizeof(*qopt))
return -EINVAL;
@@ -192,7 +194,10 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
}
sch_tree_lock(sch);
- q->enable_flow = qopt->enable_flow;
+ if (q->enable_flow != qopt->enable_flow) {
+ q->enable_flow = qopt->enable_flow;
+ flow_change = 1;
+ }
q->bands = qopt->bands;
memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1);
@@ -227,6 +232,13 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
}
}
}
+
+ /* Schedule qdisc when flow re-enabled */
+ if (flow_change && q->enable_flow) {
+ if (!test_bit(__QDISC_STATE_DEACTIVATED,
+ &sch->state))
+ __netif_schedule(qdisc_root(sch));
+ }
return 0;
}