On 3/16/2026 2:21 PM, Talluri Chaitanyababu wrote:
> Update forwarding TC mask based on configured traffic classes to properly
> handle both 4 TC and 8 TC modes. The bitmask calculation (1u << nb_tcs) - 1
> correctly creates masks for all available traffic classes (0xF for 4 TCs,
> 0xFF for 8 TCs).
>
> When the mask is not updated after a TC configuration change, it stays at
> the default 0xFF, which causes dcb_fwd_tc_update_dcb_info() to skip the
> compress logic entirely (early return when mask ==
> DEFAULT_DCB_FWD_TC_MASK).
> This can lead to inconsistent queue allocations.
>
> Additionally, the existing VMDQ pool guard in dcb_fwd_config_setup() only
> checks RX queue counts, missing the case where the TX port has zero queues
> for a given pool/TC combination. When nb_tx_queue is 0, the expression
> "j % nb_tx_queue" triggers a SIGFPE (integer division by zero).
>
> Fix this by:
> 1. Updating dcb_fwd_tc_mask after port DCB reconfiguration using the
> user requested num_tcs value, so fwd_config_setup() sees the correct
> mask.
> 2. Extending the existing pool guard to also check TX queue counts.
> 3. Adding a defensive break after the division by dcb_fwd_tc_cores to
> catch integer truncation to zero.
>
> Fixes: 0ecbf93f5001 ("app/testpmd: add command to disable DCB")
Why this commit?
> Cc: [email protected]
>
> Signed-off-by: Talluri Chaitanyababu <[email protected]>
> Signed-off-by: Shaiq Wani <[email protected]>
> ---
>
> v3: Removed old email address.
>
> v2:
> * Used res->num_tcs to derive dcb_fwd_tc_mask.
> * Removed redundant rte_eth_dev_get_dcb_info().
> ---
> app/test-pmd/cmdline.c | 3 +++
> app/test-pmd/config.c | 9 ++++++++-
> 2 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index e9a1331071..a53af7e72b 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -3682,6 +3682,9 @@ cmd_config_dcb_parsed(void *parsed_result,
> return;
> }
>
> + /* Update forwarding TC mask to match the configured number of TCs. */
> + dcb_fwd_tc_mask = (1u << res->num_tcs) - 1;
This is just configure, please don't modify it when run command.
Combined with your detail steps last email, I may guest your problem:
1. port stop all
2. port config 0 dcb vt off 8 pfc on
3. port config 1 dcb vt off 8 pfc on
4. port start all
5. port stop all
6. port config 0 dcb vt off 4 pfc on
When the step6 executed, the port 0 has 4 TC, but the port 1 still has 8 TC
which was configured in step3
If start forward after step6, the TC was mismatch, it may lead to multiple
thread operators the same Tx queues.
So you want to make sure only forward 4 TC in both port0 and port1 in step6 ?
> +
> fwd_config_setup();
>
> cmd_reconfig_device_queue(port_id, 1, 1);
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index f9f3c542a6..9b201ac241 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -5450,7 +5450,8 @@ dcb_fwd_config_setup(void)
> /* if the nb_queue is zero, means this tc is
> * not enabled on the POOL
> */
> - if (rxp_dcb_info.tc_queue.tc_rxq[i][tc].nb_queue == 0)
> + if (rxp_dcb_info.tc_queue.tc_rxq[i][tc].nb_queue == 0 ||
> + txp_dcb_info.tc_queue.tc_txq[i][tc].nb_queue == 0)
> break;
> k = fwd_lcores[lc_id]->stream_nb +
> fwd_lcores[lc_id]->stream_idx;
> @@ -5458,6 +5459,12 @@ dcb_fwd_config_setup(void)
> dcb_fwd_tc_cores;
> nb_tx_queue =
> txp_dcb_info.tc_queue.tc_txq[i][tc].nb_queue /
> dcb_fwd_tc_cores;
> + /* guard against integer truncation to zero (e.g.
> + * nb_queue=1, dcb_fwd_tc_cores=2) to prevent SIGFPE
> + * from "j % nb_tx_queue" below.
> + */
> + if (nb_rx_queue == 0 || nb_tx_queue == 0)
> + break;
This could add in dcb_fwd_check_cores_per_tc():
for (port = 0; port < nb_fwd_ports; port++) {
(void)rte_eth_dev_get_dcb_info(fwd_ports_ids[port], &dcb_info);
for (tc = 0; tc < dcb_info.nb_tcs; tc++) {
for (vmdq_idx = 0; vmdq_idx < RTE_ETH_MAX_VMDQ_POOL;
vmdq_idx++) {
if
(dcb_info.tc_queue.tc_rxq[vmdq_idx][tc].nb_queue == 0)
break;
/* make sure nb_rx_queue can be divisible. */
if
(dcb_info.tc_queue.tc_rxq[vmdq_idx][tc].nb_queue %
dcb_fwd_tc_cores)
return -1;
/* make sure nb_tx_queue can be divisible. */
if
(dcb_info.tc_queue.tc_txq[vmdq_idx][tc].nb_queue %
dcb_fwd_tc_cores)
return -1;
--------/// please add here!
}
}
}
> rxq = rxp_dcb_info.tc_queue.tc_rxq[i][tc].base +
> nb_rx_queue * sub_core_idx;
> txq = txp_dcb_info.tc_queue.tc_txq[i][tc].base +
> nb_tx_queue * sub_core_idx;
> for (j = 0; j < nb_rx_queue; j++) {