Skip to content

Commit

Permalink
sfq: deadlock in error path
Browse files Browse the repository at this point in the history
The change to allow divisor to be a parameter (in 2.6.38-rc1)
 commit 817fb15
introduced a possible deadlock caught by sparse.

The scheduler tree lock was left locked in the case of an incorrect
divisor value. Simplest fix is to move test outside of lock
which also solves problem of partial update.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
stephen hemminger authored and David S. Miller committed Feb 3, 2011
1 parent b299e4f commit 119b3d3
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions net/sched/sch_sfq.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,17 +491,18 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
if (opt->nla_len < nla_attr_size(sizeof(*ctl)))
return -EINVAL;

if (ctl->divisor &&
(!is_power_of_2(ctl->divisor) || ctl->divisor > 65536))
return -EINVAL;

sch_tree_lock(sch);
q->quantum = ctl->quantum ? : psched_mtu(qdisc_dev(sch));
q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
q->perturb_period = ctl->perturb_period * HZ;
if (ctl->limit)
q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 1);
if (ctl->divisor) {
if (!is_power_of_2(ctl->divisor) || ctl->divisor > 65536)
return -EINVAL;
if (ctl->divisor)
q->divisor = ctl->divisor;
}
qlen = sch->q.qlen;
while (sch->q.qlen > q->limit)
sfq_drop(sch);
Expand Down

0 comments on commit 119b3d3

Please sign in to comment.