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")
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;
+
        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;
                        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++) {
-- 
2.43.0

Reply via email to