The leaf node ID boundary is checked against the compile-time constant
`RTE_MAX_QUEUES_PER_PORT` (1024) rather than the number of configured Tx
queues. The rte_tm specification reserves IDs 0 to N-1 for leaf nodes
where N is the configured queue count, so using the constant produces
wrong results whenever N is less than 1024.

Fix by using `nb_tx_queues` as the boundary when queues have been
configured, falling back to `RTE_MAX_QUEUES_PER_PORT` when `nb_tx_queues`
is zero. The zero case arises when the TM hierarchy is built before port
queue configuration, which is required to support queue counts beyond
the hardware default.

Also add an explicit check in the non-leaf validation path that rejects
IDs in the leaf-reserved range. This condition can be triggered two ways:
adding a leaf node before its parent chain is complete (the node resolves
to a non-leaf level), or assigning a leaf-range ID to a node intended
as non-leaf.

Fixes: 715d449a965b ("net/ice: enhance Tx scheduler hierarchy support")
Cc: [email protected]

Signed-off-by: Ciara Loftus <[email protected]>
---
 drivers/net/intel/ice/ice_tm.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/net/intel/ice/ice_tm.c b/drivers/net/intel/ice/ice_tm.c
index 015a827d7a..bf2ac117b1 100644
--- a/drivers/net/intel/ice/ice_tm.c
+++ b/drivers/net/intel/ice/ice_tm.c
@@ -88,8 +88,11 @@ ice_node_param_check(uint32_t node_id,
                      uint32_t priority, uint32_t weight,
                      const struct rte_tm_node_params *params,
                      bool is_leaf,
+                     uint16_t nb_txq,
                      struct rte_tm_error *error)
 {
+       uint32_t max_leaf_id = (nb_txq != 0) ? nb_txq : RTE_MAX_QUEUES_PER_PORT;
+
        /* checked all the unsupported parameter */
        if (node_id == RTE_TM_NODE_ID_NULL) {
                error->type = RTE_TM_ERROR_TYPE_NODE_ID;
@@ -123,6 +126,11 @@ ice_node_param_check(uint32_t node_id,
 
        /* for non-leaf node */
        if (!is_leaf) {
+               if (node_id < max_leaf_id) {
+                       error->type = RTE_TM_ERROR_TYPE_NODE_ID;
+                       error->message = "node ID is reserved for leaf nodes";
+                       return -EINVAL;
+               }
                if (params->nonleaf.wfq_weight_mode) {
                        error->type =
                                RTE_TM_ERROR_TYPE_NODE_PARAMS_WFQ_WEIGHT_MODE;
@@ -146,7 +154,7 @@ ice_node_param_check(uint32_t node_id,
        }
 
        /* for leaf node */
-       if (node_id >= RTE_MAX_QUEUES_PER_PORT) {
+       if (node_id >= max_leaf_id) {
                error->type = RTE_TM_ERROR_TYPE_NODE_ID;
                error->message = "Node ID out of range for a leaf node.";
                return -EINVAL;
@@ -440,7 +448,8 @@ ice_tm_node_add(struct rte_eth_dev *dev, uint32_t node_id,
                        return -EINVAL;
                }
 
-               ret = ice_node_param_check(node_id, priority, weight, params, 
false, error);
+               ret = ice_node_param_check(node_id, priority, weight, params, 
false,
+                               dev->data->nb_tx_queues, error);
                if (ret)
                        return ret;
 
@@ -481,7 +490,8 @@ ice_tm_node_add(struct rte_eth_dev *dev, uint32_t node_id,
        }
 
        ret = ice_node_param_check(node_id, priority, weight,
-                       params, level_id == ice_get_leaf_level(pf), error);
+                       params, level_id == ice_get_leaf_level(pf),
+                       dev->data->nb_tx_queues, error);
        if (ret)
                return ret;
 
-- 
2.43.0

Reply via email to