On Fri, Sep 04, 2026 at 10:51:39AM +0000, Ciara Loftus wrote:
> Currently, ice_dev_info_get() assigns the value of `vsi->nb_qps` to both
> `max_rx_queues` and `max_tx_queues`.
> 
> After a Tx scheduler hierarchy is committed, the value of nb_qps may grow
> to reflect the VSI's larger Tx scheduler capacity. However the Tx scheduler
> hierarchy change has no effect on the VSI's Rx queue allocation,
> which stays fixed at its original size for the life of the port. An
> application can then request more Rx queues than the VSI's actual Rx
> resources support when the inflated nb_qps is assigned to `max_rx_queues`.
> 
> `vsi->nb_qps` also feeds `ice_vsi_disable_queues_intr()`, which clears
> both Rx and Tx queue interrupt registers by absolute queue index on
> every port stop. Once `nb_qps` grows past the VSI's fixed queue window,
> this can clear interrupt registers belonging to a different VSI.
> 
> Fix this by introducing `vsi->nb_tm_qps` to track the Tx scheduler

Just a nit on naming here. For the tm block it doesn't deal with
queue-pairs so much as Tx queues, so the variable should probably be named
nb_tm_txqs instead.

However, that opens a wider renaming question - rather than tracking a
generic nb_qps and nb_tm_qps(nb_tm_txqs), might it be better to have vsi
variables separately called "nb_rxqs" and "nb_txqs" and ignore the whole
"tm" part of it?

> capacity as it grows, leaving `vsi->nb_qps` as the VSI's fixed
> queue allocation for the life of the port. `ice_vsi_disable_queues_intr()`
> is switched to `nb_used_qps`, which already tracks the actually configured
> queue count.
> 
> Fixes: 715d449a965b ("net/ice: enhance Tx scheduler hierarchy support")
> Cc: [email protected]
> 
> Signed-off-by: Ciara Loftus <[email protected]>
> ---
>  drivers/net/intel/ice/ice_ethdev.c | 5 +++--
>  drivers/net/intel/ice/ice_ethdev.h | 1 +
>  drivers/net/intel/ice/ice_tm.c     | 8 ++++----
>  3 files changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/intel/ice/ice_ethdev.c 
> b/drivers/net/intel/ice/ice_ethdev.c
> index fd148848d3c..149872816d8 100644
> --- a/drivers/net/intel/ice/ice_ethdev.c
> +++ b/drivers/net/intel/ice/ice_ethdev.c
> @@ -1816,6 +1816,7 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
>                                    ret);
>                       goto fail_mem;
>               }
> +             vsi->nb_tm_qps = vsi->nb_qps;
>  
>               break;
>       case ICE_VSI_CTRL:
> @@ -2924,7 +2925,7 @@ ice_vsi_disable_queues_intr(struct ice_vsi *vsi)
>       uint16_t msix_intr, i;
>  
>       /* disable interrupt and also clear all the exist config */
> -     for (i = 0; i < vsi->nb_qps; i++) {
> +     for (i = 0; i < vsi->nb_used_qps; i++) {
>               ICE_WRITE_REG(hw, QINT_TQCTL(vsi->base_queue + i), 0);
>               ICE_WRITE_REG(hw, QINT_RQCTL(vsi->base_queue + i), 0);
>               rte_wmb();
> @@ -4628,7 +4629,7 @@ ice_dev_info_get(struct rte_eth_dev *dev, struct 
> rte_eth_dev_info *dev_info)
>       dev_info->min_rx_bufsize = ICE_BUF_SIZE_MIN;
>       dev_info->max_rx_pktlen = ICE_FRAME_SIZE_MAX;
>       dev_info->max_rx_queues = vsi->nb_qps;
> -     dev_info->max_tx_queues = vsi->nb_qps;
> +     dev_info->max_tx_queues = vsi->nb_tm_qps;
>       dev_info->max_mac_addrs = vsi->max_macaddrs;
>       dev_info->max_vfs = pci_dev->max_vfs;
>       dev_info->max_mtu = dev_info->max_rx_pktlen - ICE_ETH_OVERHEAD;
> diff --git a/drivers/net/intel/ice/ice_ethdev.h 
> b/drivers/net/intel/ice/ice_ethdev.h
> index 5914454c7c2..3160c82c5e3 100644
> --- a/drivers/net/intel/ice/ice_ethdev.h
> +++ b/drivers/net/intel/ice/ice_ethdev.h
> @@ -330,6 +330,7 @@ struct ice_vsi {
>       struct ice_mac_filter_list mac_list; /* macvlan filter list */
>       struct ice_vlan_filter_list vlan_list; /* vlan filter list */
>       uint16_t nb_qps;         /* Number of queue pairs VSI can occupy */
> +     uint16_t nb_tm_qps;      /* Number of Tx queues usable by the committed 
> TM hierarchy */
>       uint16_t nb_used_qps;    /* Number of queue pairs VSI uses */
>       uint16_t max_macaddrs;   /* Maximum number of MAC addresses */
>       uint16_t base_queue;     /* The first queue index of this VSI */
> diff --git a/drivers/net/intel/ice/ice_tm.c b/drivers/net/intel/ice/ice_tm.c
> index 651d6aa932d..7afe31738ba 100644
> --- a/drivers/net/intel/ice/ice_tm.c
> +++ b/drivers/net/intel/ice/ice_tm.c
> @@ -859,9 +859,9 @@ commit_new_hierarchy(struct rte_eth_dev *dev)
>               }
>               /* TM hierarchy deleted. Restore default scheduler state. */
>               reset_hw_node_recursive(hw, 
> hw->vsi_ctx[pf->main_vsi->idx]->sched.vsi_node[0]);
> -             pf->main_vsi->nb_qps = pf->lan_nb_qps;
> +             pf->main_vsi->nb_tm_qps = pf->lan_nb_qps;
>               pf->tm_conf.committed = false;
> -             return ice_alloc_lan_q_ctx(hw, 0, 0, pf->main_vsi->nb_qps);
> +             return ice_alloc_lan_q_ctx(hw, 0, 0, pf->main_vsi->nb_tm_qps);
>       }
>  
>       /* handle case where VSI node needs to move DOWN the hierarchy */
> @@ -889,13 +889,13 @@ commit_new_hierarchy(struct rte_eth_dev *dev)
>                               nodes_created_per_level[i], i);
>       hw->vsi_ctx[pf->main_vsi->idx]->sched.vsi_node[0] = new_vsi_root;
>  
> -     pf->main_vsi->nb_qps =
> +     pf->main_vsi->nb_tm_qps =
>                       RTE_MIN(nodes_created_per_level[qg_lvl] * 
> hw->max_children[qg_lvl],
>                               hw->layer_info[q_lvl].max_device_nodes);
>  
>       pf->tm_conf.committed = true; /* set flag to be checks on queue start */
>  
> -     return ice_alloc_lan_q_ctx(hw, 0, 0, pf->main_vsi->nb_qps);
> +     return ice_alloc_lan_q_ctx(hw, 0, 0, pf->main_vsi->nb_tm_qps);
>  }
>  
>  static int

Reply via email to