Fix DCB forwarding issues when RX and TX ports are configured with
different numbers of traffic classes (TCs).

When ports have asymmetric TC configurations (e.g. 4 TCs on RX and 8 TCs
on TX), the forwarding logic iterates based only on the RX port TC count.
This can lead to accessing invalid TX TC entries and incorrect queue
mapping, potentially causing multiple threads to operate on the same
queues.

Additionally, the existing VMDq pool guard in dcb_fwd_config_setup()
only checks RX queue counts and does not consider the case where the TX
port has no queues for a given pool/TC combination.

Fix this by:
1. Introducing an effective TC count using RTE_MIN() of RX and TX TC
   values, ensuring forwarding only operates on valid TCs supported by
   both ports.
2. Updating the loop condition to use the effective TC count instead of
   only the RX TC count.
3. Extending validation in dcb_fwd_check_cores_per_tc() to ensure both RX
   and TX queue counts are divisible by dcb_fwd_tc_cores, preventing
   invalid configurations.

This ensures correct queue mapping and avoids issues when switching
between different DCB configurations across ports.

Fixes: 945e9be0a803 ("app/testpmd: support multi-cores process one TC")
Cc: [email protected]

Signed-off-by: Talluri Chaitanyababu <[email protected]>
Signed-off-by: Shaiq Wani <[email protected]>
---

v4:
* Removed runtime update of dcb_fwd_tc_mask as per review comments.
* Used effective TC count (RTE_MIN of RX/TX) to handle asymmetric configs.
* Moved queue validation to dcb_fwd_check_cores_per_tc().

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/config.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index f9f3c542a6..4caa1b1237 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -5286,7 +5286,8 @@ dcb_fwd_check_cores_per_tc(void)
                (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)
+                               if 
(dcb_info.tc_queue.tc_rxq[vmdq_idx][tc].nb_queue == 0 ||
+                                   
dcb_info.tc_queue.tc_txq[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 %
@@ -5377,6 +5378,7 @@ dcb_fwd_config_setup(void)
        uint16_t nb_rx_queue, nb_tx_queue;
        uint16_t i, j, k, sm_id = 0;
        uint16_t sub_core_idx = 0;
+       uint8_t effective_nb_tcs;
        uint16_t total_tc_num;
        struct rte_port *port;
        uint8_t tc = 0;
@@ -5442,6 +5444,7 @@ dcb_fwd_config_setup(void)
        dcb_fwd_tc_update_dcb_info(&rxp_dcb_info);
        (void)rte_eth_dev_get_dcb_info(fwd_ports_ids[txp], &txp_dcb_info);
        dcb_fwd_tc_update_dcb_info(&txp_dcb_info);
+       effective_nb_tcs = RTE_MIN(rxp_dcb_info.nb_tcs, txp_dcb_info.nb_tcs);
 
        for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) {
                fwd_lcores[lc_id]->stream_nb = 0;
@@ -5450,7 +5453,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;
@@ -5480,7 +5484,7 @@ dcb_fwd_config_setup(void)
 
                sub_core_idx = 0;
                tc++;
-               if (tc < rxp_dcb_info.nb_tcs)
+               if (tc < effective_nb_tcs)
                        continue;
                /* Restart from TC 0 on next RX port */
                tc = 0;
@@ -5497,6 +5501,8 @@ dcb_fwd_config_setup(void)
                dcb_fwd_tc_update_dcb_info(&rxp_dcb_info);
                rte_eth_dev_get_dcb_info(fwd_ports_ids[txp], &txp_dcb_info);
                dcb_fwd_tc_update_dcb_info(&txp_dcb_info);
+
+               effective_nb_tcs = RTE_MIN(rxp_dcb_info.nb_tcs, 
txp_dcb_info.nb_tcs);
        }
 }
 
-- 
2.43.0

Reply via email to