mirror of
https://github.com/torvalds/linux.git
synced 2026-09-12 20:53:03 +02:00
octeontx2-pf: reset HTB scheduler topology before freeing queues
HTB offload programs NIX_AF_TLxX_TOPOLOGY on QoS-allocated scheduler
queues via otx2_qos_txschq_set_parent_topology(), but teardown freed
those queues without clearing TOPOLOGY. The AF only restores PARENT and
SCHEDULE on free, so PRIO_ANCHOR/RR_PRIO settings can survive in the
shared scheduler pool and affect later allocations.
Add otx2_qos_reset_schq_topology() and otx2_qos_free_hw_schq() to zero
TL4 through TL2 TOPOLOGY before each schq is returned to the AF during
hierarchy teardown and cfg rollback. Skip the aggregation level (TL1):
it is a per-tx-link queue shared by the PF, default Tx hierarchy and VFs,
and is not freed back to the AF by nix_txschq_free_one().
Fixes: 5e6808b4c6 ("octeontx2-pf: Add support for HTB offload")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260903020533.3068041-1-rkannoth@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
66ef5adb75
commit
ef39fca850
|
|
@ -235,13 +235,63 @@ static int otx2_qos_txschq_set_parent_topology(struct otx2_nic *pfvf,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int otx2_qos_reset_schq_topology(struct otx2_nic *pfvf, u16 lvl,
|
||||
u16 schq)
|
||||
{
|
||||
struct mbox *mbox = &pfvf->mbox;
|
||||
struct nix_txschq_config *cfg;
|
||||
int rc;
|
||||
|
||||
if (lvl < NIX_TXSCH_LVL_TL4 || lvl >= NIX_TXSCH_LVL_TL1)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&mbox->lock);
|
||||
|
||||
cfg = otx2_mbox_alloc_msg_nix_txschq_cfg(mbox);
|
||||
if (!cfg) {
|
||||
mutex_unlock(&mbox->lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cfg->lvl = lvl;
|
||||
cfg->num_regs = 1;
|
||||
|
||||
if (lvl == NIX_TXSCH_LVL_TL4)
|
||||
cfg->reg[0] = NIX_AF_TL4X_TOPOLOGY(schq);
|
||||
else if (lvl == NIX_TXSCH_LVL_TL3)
|
||||
cfg->reg[0] = NIX_AF_TL3X_TOPOLOGY(schq);
|
||||
else if (lvl == NIX_TXSCH_LVL_TL2)
|
||||
cfg->reg[0] = NIX_AF_TL2X_TOPOLOGY(schq);
|
||||
|
||||
cfg->regval[0] = 0;
|
||||
|
||||
rc = otx2_sync_mbox_msg(mbox);
|
||||
|
||||
mutex_unlock(&mbox->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void otx2_qos_free_hw_schq(struct otx2_nic *pfvf, u16 lvl, u16 schq)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = otx2_qos_reset_schq_topology(pfvf, lvl, schq);
|
||||
if (err)
|
||||
netdev_warn(pfvf->netdev,
|
||||
"QoS: failed to reset topology for schq %u at level %u: %d\n",
|
||||
schq, lvl, err);
|
||||
|
||||
otx2_txschq_free_one(pfvf, lvl, schq);
|
||||
}
|
||||
|
||||
static void otx2_qos_free_hw_node_schq(struct otx2_nic *pfvf,
|
||||
struct otx2_qos_node *parent)
|
||||
{
|
||||
struct otx2_qos_node *node;
|
||||
|
||||
list_for_each_entry_reverse(node, &parent->child_schq_list, list)
|
||||
otx2_txschq_free_one(pfvf, node->level, node->schq);
|
||||
otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
|
||||
}
|
||||
|
||||
static void otx2_qos_free_hw_node(struct otx2_nic *pfvf,
|
||||
|
|
@ -252,7 +302,7 @@ static void otx2_qos_free_hw_node(struct otx2_nic *pfvf,
|
|||
list_for_each_entry_safe(node, tmp, &parent->child_list, list) {
|
||||
otx2_qos_free_hw_node(pfvf, node);
|
||||
otx2_qos_free_hw_node_schq(pfvf, node);
|
||||
otx2_txschq_free_one(pfvf, node->level, node->schq);
|
||||
otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -266,7 +316,7 @@ static void otx2_qos_free_hw_cfg(struct otx2_nic *pfvf,
|
|||
otx2_qos_free_hw_node_schq(pfvf, node);
|
||||
|
||||
/* free node hw mappings */
|
||||
otx2_txschq_free_one(pfvf, node->level, node->schq);
|
||||
otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
|
||||
|
||||
mutex_unlock(&pfvf->qos.qos_lock);
|
||||
}
|
||||
|
|
@ -913,7 +963,7 @@ static void otx2_qos_free_cfg(struct otx2_nic *pfvf, struct otx2_qos_cfg *cfg)
|
|||
for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
|
||||
for (idx = 0; idx < cfg->schq[lvl]; idx++) {
|
||||
schq = cfg->schq_list[lvl][idx];
|
||||
otx2_txschq_free_one(pfvf, lvl, schq);
|
||||
otx2_qos_free_hw_schq(pfvf, lvl, schq);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -921,7 +971,7 @@ static void otx2_qos_free_cfg(struct otx2_nic *pfvf, struct otx2_qos_cfg *cfg)
|
|||
for (idx = 0; idx < cfg->schq_contig[lvl]; idx++) {
|
||||
if (cfg->schq_index_used[lvl][idx]) {
|
||||
schq = cfg->schq_contig_list[lvl][idx];
|
||||
otx2_txschq_free_one(pfvf, lvl, schq);
|
||||
otx2_qos_free_hw_schq(pfvf, lvl, schq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user