Skip to content

Commit

Permalink
mlxsw: spectrum: qdiscs: prio: Delete child qdiscs when removing bands
Browse files Browse the repository at this point in the history
When the number the bands of sch_prio is decreased, child qdiscs on the
deleted bands would get deleted as well.
This change and deletions are being done under sch_tree_lock of the
sch_prio qdisc. Part of the destruction of qdisc is unoffloading it, if
it is offloaded. Un-offloading can't be done inside this lock.
Move the offload command to be done before reducing the number of bands,
so unoffloading of the qdiscs that are about to be deleted could be done
outside of the lock.

Signed-off-by: Nogah Frankel <nogahf@mellanox.com>
Reviewed-by: Yuval Mintz <yuvalm@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Nogah Frankel authored and David S. Miller committed Feb 28, 2018
1 parent 23f2b40 commit 98ceb7b
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 8 deletions.
7 changes: 6 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,12 @@ mlxsw_sp_qdisc_prio_replace(struct mlxsw_sp_port *mlxsw_sp_port,
child_qdisc->stats_base.backlog = backlog;
}
}

for (; band < IEEE_8021QAZ_MAX_TCS; band++) {
tclass = MLXSW_SP_PRIO_BAND_TO_TCLASS(band);
child_qdisc = &mlxsw_sp_port->tclass_qdiscs[tclass];
child_qdisc->prio_bitmap = 0;
mlxsw_sp_qdisc_destroy(mlxsw_sp_port, child_qdisc);
}
return 0;
}

Expand Down
13 changes: 6 additions & 7 deletions net/sched/sch_prio.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,8 @@ prio_reset(struct Qdisc *sch)
sch->q.qlen = 0;
}

static int prio_offload(struct Qdisc *sch, bool enable)
static int prio_offload(struct Qdisc *sch, struct tc_prio_qopt *qopt)
{
struct prio_sched_data *q = qdisc_priv(sch);
struct net_device *dev = qdisc_dev(sch);
struct tc_prio_qopt_offload opt = {
.handle = sch->handle,
Expand All @@ -154,10 +153,10 @@ static int prio_offload(struct Qdisc *sch, bool enable)
if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
return -EOPNOTSUPP;

if (enable) {
if (qopt) {
opt.command = TC_PRIO_REPLACE;
opt.replace_params.bands = q->bands;
memcpy(&opt.replace_params.priomap, q->prio2band,
opt.replace_params.bands = qopt->bands;
memcpy(&opt.replace_params.priomap, qopt->priomap,
TC_PRIO_MAX + 1);
opt.replace_params.qstats = &sch->qstats;
} else {
Expand All @@ -174,7 +173,7 @@ prio_destroy(struct Qdisc *sch)
struct prio_sched_data *q = qdisc_priv(sch);

tcf_block_put(q->block);
prio_offload(sch, false);
prio_offload(sch, NULL);
for (prio = 0; prio < q->bands; prio++)
qdisc_destroy(q->queues[prio]);
}
Expand Down Expand Up @@ -211,6 +210,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt,
}
}

prio_offload(sch, qopt);
sch_tree_lock(sch);
q->bands = qopt->bands;
memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1);
Expand All @@ -230,7 +230,6 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt,
}

sch_tree_unlock(sch);
prio_offload(sch, true);
return 0;
}

Expand Down

0 comments on commit 98ceb7b

Please sign in to comment.