| From 95010a93cae6ca60726cb1929e8f791f58ae1ca9 Mon Sep 17 00:00:00 2001 |
| From: Petr Machata <petrm@mellanox.com> |
| Date: Mon, 6 Jan 2020 18:01:56 +0000 |
| Subject: [PATCH] net: sch_prio: When ungrafting, replace with FIFO |
| |
| commit 240ce7f6428ff5188b9eedc066e1e4d645b8635f upstream. |
| |
| When a child Qdisc is removed from one of the PRIO Qdisc's bands, it is |
| replaced unconditionally by a NOOP qdisc. As a result, any traffic hitting |
| that band gets dropped. That is incorrect--no Qdisc was explicitly added |
| when PRIO was created, and after removal, none should have to be added |
| either. |
| |
| Fix PRIO by first attempting to create a default Qdisc and only falling |
| back to noop when that fails. This pattern of attempting to create an |
| invisible FIFO, using NOOP only as a fallback, is also seen in other |
| Qdiscs. |
| |
| Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") |
| Signed-off-by: Petr Machata <petrm@mellanox.com> |
| Acked-by: Jiri Pirko <jiri@mellanox.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c |
| index 18b884cfdfe8..647941702f9f 100644 |
| --- a/net/sched/sch_prio.c |
| +++ b/net/sched/sch_prio.c |
| @@ -292,8 +292,14 @@ static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, |
| struct tc_prio_qopt_offload graft_offload; |
| unsigned long band = arg - 1; |
| |
| - if (new == NULL) |
| - new = &noop_qdisc; |
| + if (!new) { |
| + new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, |
| + TC_H_MAKE(sch->handle, arg), extack); |
| + if (!new) |
| + new = &noop_qdisc; |
| + else |
| + qdisc_hash_add(new, true); |
| + } |
| |
| *old = qdisc_replace(sch, new, &q->queues[band]); |
| |
| -- |
| 2.7.4 |
| |