Hi Dmitry,
> -----Original Message----- > From: Singh, Aman Deep <aman.deep.si...@intel.com> > Sent: Thursday, February 3, 2022 9:52 PM > To: Dmitry Kozlyuk <dkozl...@nvidia.com>; dev@dpdk.org > Cc: Li, Xiaoyun <xiaoyun...@intel.com>; Zhang, Yuying > <yuying.zh...@intel.com>; jing.d.c...@intel.com; sta...@dpdk.org; Raslan > Darawsheh <rasl...@nvidia.com> > Subject: Re: [PATCH] app/testpmd: skip stopped queues when forwarding > > Hi Dmitry, > > Thanks for the patch. > > On 1/13/2022 2:51 PM, Dmitry Kozlyuk wrote: > > 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; Have you considered other fwd_engines such as io_fwd_engine and mac_fwd_engine? > > + /* 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; > Should we have a print here for user info, that mode has been changed or > ignored. Why need to force rxonly mode for this situation? BTW, the value of cur_fwd_eng hasn't been updated after you changed forward mode. > > + 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]; > Can we think of adding rxq_state/txq_state as part of existing structures > under rte_port->rte_eth_rxconf/rte_eth_txconf. > And if it helps, rather than bool can we use u8 with eth_dev defines- #define > RTE_ETH_QUEUE_STATE_STOPPED 0 /**< Queue stopped. */ #define > RTE_ETH_QUEUE_STATE_STARTED 1 /**< Queue started. */ The same. > > }; > > > > /**