[PATCH] app/testpmd: fix DCB forwarding TC mask and queue guard

Talluri Chaitanyababu chaitanyababux.talluri at intel.com
Wed Mar 11 09:37:51 CET 2026


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, and returning
   on failure so fwd_config_setup() is not called with a stale 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: stable at dpdk.org

Signed-off-by: Talluri Chaitanyababu <chaitanyababux.talluri at intel.com>
Signed-off-by: Shaiq Wani <shaiq.wani at intel.com>
---
 app/test-pmd/cmdline.c | 13 +++++++++++++
 app/test-pmd/config.c  |  9 ++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index c33c66f327..3fb9b940eb 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -3682,6 +3682,19 @@ cmd_config_dcb_parsed(void *parsed_result,
 		return;
 	}
 
+	/*
+	 * Update forwarding TC mask to match actual configured TCs.
+	 * Must query after init_port_dcb_config() to get updated nb_tcs.
+	 */
+	ret = rte_eth_dev_get_dcb_info(port_id, &dcb_info);
+	if (ret == 0 && dcb_info.nb_tcs > 0) {
+		dcb_fwd_tc_mask = (1u << dcb_info.nb_tcs) - 1;
+	} else if (ret != 0) {
+		fprintf(stderr, "Failed to get DCB info for port %u: %s\n",
+				port_id, rte_strerror(-ret));
+		return;
+	}
+
 	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



More information about the dev mailing list