net_sched: prio: properly report out of memory errors

At Qdisc creation or change time, prio_tune() creates missing
pfifo qdiscs but does not return an error code if one
qdisc could not be allocated.

Leaving a qdisc in non operational state without telling user
anything about this problem is not good.

Also, testing if we replace something different than noop_qdisc
a second time makes no sense so I removed useless code.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Eric Dumazet 2016-06-12 16:21:47 -07:00 коммит произвёл David S. Miller
Родитель 86ef7f9cbf
Коммит cbdf451164
1 изменённых файлов: 10 добавлений и 18 удалений

Просмотреть файл

@ -202,26 +202,18 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
sch_tree_unlock(sch); sch_tree_unlock(sch);
for (i = 0; i < q->bands; i++) { for (i = 0; i < q->bands; i++) {
if (q->queues[i] == &noop_qdisc) { struct Qdisc *child;
struct Qdisc *child, *old;
child = qdisc_create_dflt(sch->dev_queue, if (q->queues[i] != &noop_qdisc)
&pfifo_qdisc_ops, continue;
TC_H_MAKE(sch->handle, i + 1));
if (child) {
sch_tree_lock(sch);
old = q->queues[i];
q->queues[i] = child;
if (old != &noop_qdisc) { child = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
qdisc_tree_reduce_backlog(old, TC_H_MAKE(sch->handle, i + 1));
old->q.qlen, if (!child)
old->qstats.backlog); return -ENOMEM;
qdisc_destroy(old); sch_tree_lock(sch);
} q->queues[i] = child;
sch_tree_unlock(sch); sch_tree_unlock(sch);
}
}
} }
return 0; return 0;
} }