History

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().

Ratheesh Kannoth committed 2 months ago

Commit ef39fca1 parent 66ef5ad1 file · +55 −5Browse files

Unified · Split

drivers/net/ethernet/marvell/octeontx2/nic/qos.c+55−5
@@ -235,13 +235,63 @@ static int otx2_qos_txschq_set_parent_topology(struct otx2_nic *pfvf, · 234 unmodified lines
235235 return rc;
236236 }
237237
238+static int otx2_qos_reset_schq_topology(struct otx2_nic *pfvf, u16 lvl,
239+ u16 schq)
240+{
241+ struct mbox *mbox = &pfvf->mbox;
242+ struct nix_txschq_config *cfg;
243+ int rc;
244+
245+ if (lvl < NIX_TXSCH_LVL_TL4 || lvl >= NIX_TXSCH_LVL_TL1)
246+ return 0;
247+
248+ mutex_lock(&mbox->lock);
249+
250+ cfg = otx2_mbox_alloc_msg_nix_txschq_cfg(mbox);
251+ if (!cfg) {
252+ mutex_unlock(&mbox->lock);
253+ return -ENOMEM;
254+ }
255+
256+ cfg->lvl = lvl;
257+ cfg->num_regs = 1;
258+
259+ if (lvl == NIX_TXSCH_LVL_TL4)
260+ cfg->reg[0] = NIX_AF_TL4X_TOPOLOGY(schq);
261+ else if (lvl == NIX_TXSCH_LVL_TL3)
262+ cfg->reg[0] = NIX_AF_TL3X_TOPOLOGY(schq);
263+ else if (lvl == NIX_TXSCH_LVL_TL2)
264+ cfg->reg[0] = NIX_AF_TL2X_TOPOLOGY(schq);
265+
266+ cfg->regval[0] = 0;
267+
268+ rc = otx2_sync_mbox_msg(mbox);
269+
270+ mutex_unlock(&mbox->lock);
271+
272+ return rc;
273+}
274+
275+static void otx2_qos_free_hw_schq(struct otx2_nic *pfvf, u16 lvl, u16 schq)
276+{
277+ int err;
278+
279+ err = otx2_qos_reset_schq_topology(pfvf, lvl, schq);
280+ if (err)
281+ netdev_warn(pfvf->netdev,
282+ "QoS: failed to reset topology for schq %u at level %u: %d\n",
283+ schq, lvl, err);
284+
285+ otx2_txschq_free_one(pfvf, lvl, schq);
286+}
287+
238288 static void otx2_qos_free_hw_node_schq(struct otx2_nic *pfvf,
239289 struct otx2_qos_node *parent)
240290 {
241291 struct otx2_qos_node *node;
242292
243293 list_for_each_entry_reverse(node, &parent->child_schq_list, list)
244− otx2_txschq_free_one(pfvf, node->level, node->schq);
294+ otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
245295 }
246296
247297 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, · 4 unmodified lines
252302 list_for_each_entry_safe(node, tmp, &parent->child_list, list) {
253303 otx2_qos_free_hw_node(pfvf, node);
254304 otx2_qos_free_hw_node_schq(pfvf, node);
255− otx2_txschq_free_one(pfvf, node->level, node->schq);
305+ otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
256306 }
257307 }
258308
@@ -266,7 +316,7 @@ static void otx2_qos_free_hw_cfg(struct otx2_nic *pfvf, · 7 unmodified lines
266316 otx2_qos_free_hw_node_schq(pfvf, node);
267317
268318 /* free node hw mappings */
269− otx2_txschq_free_one(pfvf, node->level, node->schq);
319+ otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
270320
271321 mutex_unlock(&pfvf->qos.qos_lock);
272322 }
@@ -913,7 +963,7 @@ static void otx2_qos_free_cfg(struct otx2_nic *pfvf, struct otx2_qos_cfg *cfg) · 640 unmodified lines
913963 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
914964 for (idx = 0; idx < cfg->schq[lvl]; idx++) {
915965 schq = cfg->schq_list[lvl][idx];
916− otx2_txschq_free_one(pfvf, lvl, schq);
966+ otx2_qos_free_hw_schq(pfvf, lvl, schq);
917967 }
918968 }
919969
@@ -921,7 +971,7 @@ static void otx2_qos_free_cfg(struct otx2_nic *pfvf, struct otx2_qos_cfg *cfg) · 1 unmodified line
921971 for (idx = 0; idx < cfg->schq_contig[lvl]; idx++) {
922972 if (cfg->schq_index_used[lvl][idx]) {
923973 schq = cfg->schq_contig_list[lvl][idx];
924− otx2_txschq_free_one(pfvf, lvl, schq);
974+ otx2_qos_free_hw_schq(pfvf, lvl, schq);
925975 }
926976 }
927977 }