After "port <port_id> rxq|txq <queue_id> stop" the stopped queue was used in forwarding nonetheless, which may cause undefined behavior in the PMD.
Record the configured queue state and account for it when launching forwarding as follows: +--------+---------+-----------------+---------------+ |RxQ |TxQ |Configured mode |Launch routine | +--------+---------+-----------------+---------------+ |stopped |stopped |* |- | |stopped |started |txonly |(configured) | |stopped |started |* |- | |started |stopped |* |rxonly | |started |started |* |(configured) | +--------+---------+-----------------+---------------+ Display stopped queues on "show port config rxtx". Fixes: 5f4ec54f1d16 ("testpmd: queue start and stop") Cc: jing.d.c...@intel.com Cc: sta...@dpdk.org Signed-off-by: Dmitry Kozlyuk <dkozl...@nvidia.com> Reviewed-by: Raslan Darawsheh <rasl...@nvidia.com> --- app/test-pmd/cmdline.c | 8 ++++++++ app/test-pmd/config.c | 6 ++++++ app/test-pmd/testpmd.c | 18 ++++++++++++++++-- app/test-pmd/testpmd.h | 10 ++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index e626b1c7d9..8b0920e23d 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -2702,6 +2702,14 @@ cmd_config_rxtx_queue_parsed(void *parsed_result, if (ret == -ENOTSUP) fprintf(stderr, "Function not supported in PMD\n"); + if (ret == 0) { + struct rte_port *port; + struct queue_state *states; + + port = &ports[res->portid]; + states = isrx ? port->rxq_state : port->txq_state; + states[res->qid].stopped = !isstart; + } } cmdline_parse_token_string_t cmd_config_rxtx_queue_port = diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 1722d6c8f8..7ce9cb483a 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -2817,6 +2817,9 @@ rxtx_config_display(void) rx_conf->share_qid); printf("\n"); } + for (qid = 0; qid < nb_rxq; qid++) + if (ports[pid].rxq_state[qid].stopped) + printf(" RX queue %d is stopped\n", qid); /* per tx queue config only for first queue to be less verbose */ for (qid = 0; qid < 1; qid++) { @@ -2850,6 +2853,9 @@ rxtx_config_display(void) printf(" TX offloads=0x%"PRIx64" - TX RS bit threshold=%d\n", offloads_tmp, tx_rs_thresh_tmp); } + for (qid = 0; qid < nb_txq; qid++) + if (ports[pid].txq_state[qid].stopped) + printf(" TX queue %d is stopped\n", qid); } } diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 6c387bde84..36ff845181 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -2152,6 +2152,8 @@ flush_fwd_rx_queues(void) for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) { for (rxq = 0; rxq < nb_rxq; rxq++) { port_id = fwd_ports_ids[rxp]; + if (ports[port_id].rxq_state[rxq].stopped) + continue; /** * testpmd can stuck in the below do while loop * if rte_eth_rx_burst() always returns nonzero @@ -2223,8 +2225,20 @@ run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd) static int start_pkt_forward_on_core(void *fwd_arg) { - run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg, - cur_fwd_config.fwd_eng->packet_fwd); + struct fwd_lcore *fc = fwd_arg; + struct fwd_stream *fsm = fwd_streams[fc->stream_idx]; + struct queue_state *rxq = &ports[fsm->rx_port].rxq_state[fsm->rx_queue]; + struct queue_state *txq = &ports[fsm->tx_port].txq_state[fsm->tx_queue]; + struct fwd_engine *fwd_engine = cur_fwd_config.fwd_eng; + packet_fwd_t packet_fwd; + + /* Check if there will ever be any packets to send. */ + if (rxq->stopped && (txq->stopped || fwd_engine != &tx_only_engine)) + return 0; + /* Force rxonly mode if RxQ is started, but TxQ is stopped. */ + packet_fwd = !rxq->stopped && txq->stopped ? rx_only_engine.packet_fwd + : fwd_engine->packet_fwd; + run_pkt_fwd_on_lcore(fc, packet_fwd); return 0; } diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 2149ecd93a..2744fa4d76 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -216,6 +216,12 @@ struct xstat_display_info { bool allocated; }; +/** Application state of a queue. */ +struct queue_state { + /** The queue is stopped and should not be used. */ + bool stopped; +}; + /** * The data structure associated with each port. */ @@ -256,6 +262,10 @@ struct rte_port { uint64_t mbuf_dynf; const struct rte_eth_rxtx_callback *tx_set_dynf_cb[RTE_MAX_QUEUES_PER_PORT+1]; struct xstat_display_info xstats_info; + /** Per-Rx-queue state. */ + struct queue_state rxq_state[RTE_MAX_QUEUES_PER_PORT]; + /** Per-Tx-queue state. */ + struct queue_state txq_state[RTE_MAX_QUEUES_PER_PORT]; }; /** -- 2.25.1