aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-03-11 23:54:56 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-11 23:54:56 -0400
commit62cf4be9899dafe0fd84cbdf5352a01d8f1ea326 (patch)
tree64becbfd442aed1f89f4058609eaa042c8e6f417
parentbonding: force cast of IP address in options (diff)
parentpkt_sched: add cond_resched() to class and qdisc dump (diff)
downloadlinux-dev-62cf4be9899dafe0fd84cbdf5352a01d8f1ea326.tar.xz
linux-dev-62cf4be9899dafe0fd84cbdf5352a01d8f1ea326.zip
Merge branch 'pkt_sched_cond_resched'
Eric Dumazet says: ==================== pkt_sched: allow scheduling points We have seen delays of more than 50ms in class or qdisc dumps, in case device is under high TX stress, even with the prior 4KB per skb limit. With the new 16KB limit, this could translate to 200ms delays. Add cond_resched() to give a chance to higher prio tasks to get cpu. But before doing so, we need to remove the rcu locking from tc_dump_qdisc() as David spotted. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/sched/sch_api.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 1313145e3b86..0a99d7ced71e 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1303,6 +1303,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
struct gnet_dump d;
struct qdisc_size_table *stab;
+ cond_resched();
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
if (!nlh)
goto out_nlmsg_trim;
@@ -1434,9 +1435,9 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
s_idx = cb->args[0];
s_q_idx = q_idx = cb->args[1];
- rcu_read_lock();
idx = 0;
- for_each_netdev_rcu(net, dev) {
+ ASSERT_RTNL();
+ for_each_netdev(net, dev) {
struct netdev_queue *dev_queue;
if (idx < s_idx)
@@ -1459,8 +1460,6 @@ cont:
}
done:
- rcu_read_unlock();
-
cb->args[0] = idx;
cb->args[1] = q_idx;
@@ -1617,6 +1616,7 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
struct gnet_dump d;
const struct Qdisc_class_ops *cl_ops = q->ops->cl_ops;
+ cond_resched();
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
if (!nlh)
goto out_nlmsg_trim;