sfq: deadlock in error path
The change to allow divisor to be a parameter (in 2.6.38-rc1)
commit 817fb15dfd
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>
This commit is contained in:
parent
b299e4f001
commit
119b3d3869
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue