> -----Original Message----- > From: Liu, Mingxia <mingxia....@intel.com> > Sent: Monday, April 24, 2023 5:48 PM > To: Xing, Beilei <beilei.x...@intel.com>; Wu, Jingjing <jingjing...@intel.com> > Cc: dev@dpdk.org; Wang, Xiao W <xiao.w.w...@intel.com> > Subject: RE: [PATCH 06/10] net/cpfl: support hairpin queue configuration > > > > > -----Original Message----- > > From: Xing, Beilei <beilei.x...@intel.com> > > Sent: Friday, April 21, 2023 2:51 PM > > To: Wu, Jingjing <jingjing...@intel.com> > > Cc: dev@dpdk.org; Liu, Mingxia <mingxia....@intel.com>; Xing, Beilei > > <beilei.x...@intel.com>; Wang, Xiao W <xiao.w.w...@intel.com> > > Subject: [PATCH 06/10] net/cpfl: support hairpin queue configuration > > > > From: Beilei Xing <beilei.x...@intel.com> > > > > This patch supports Rx/Tx hairpin queue configuration. > > > > Signed-off-by: Xiao Wang <xiao.w.w...@intel.com> > > Signed-off-by: Mingxia Liu <mingxia....@intel.com> > > Signed-off-by: Beilei Xing <beilei.x...@intel.com> > > --- > > drivers/common/idpf/idpf_common_virtchnl.c | 70 +++++++++++ > > drivers/common/idpf/idpf_common_virtchnl.h | 6 + > > drivers/common/idpf/version.map | 2 + > > drivers/net/cpfl/cpfl_ethdev.c | 136 ++++++++++++++++++++- > > drivers/net/cpfl/cpfl_rxtx.c | 80 ++++++++++++ > > drivers/net/cpfl/cpfl_rxtx.h | 7 ++ > > 6 files changed, 297 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/common/idpf/idpf_common_virtchnl.c > > b/drivers/common/idpf/idpf_common_virtchnl.c > > index 76a658bb26..50cd43a8dd 100644 > > --- a/drivers/common/idpf/idpf_common_virtchnl.c > > +++ b/drivers/common/idpf/idpf_common_virtchnl.c <...> > > static int > > cpfl_start_queues(struct rte_eth_dev *dev) { > > + struct cpfl_vport *cpfl_vport = dev->data->dev_private; > > + struct idpf_vport *vport = &cpfl_vport->base; > > struct cpfl_rx_queue *cpfl_rxq; > > struct cpfl_tx_queue *cpfl_txq; > > + int tx_cmplq_flag = 0; > > + int rx_bufq_flag = 0; > > + int flag = 0; > > int err = 0; > > int i; > > > > + /* For normal data queues, configure, init and enale Txq. > > + * For non-cross vport hairpin queues, configure Txq. > > + */ > > for (i = 0; i < dev->data->nb_tx_queues; i++) { > > cpfl_txq = dev->data->tx_queues[i]; > > if (cpfl_txq == NULL || cpfl_txq->base.tx_deferred_start) > > continue; > > - err = cpfl_tx_queue_start(dev, i); > > + if (!cpfl_txq->hairpin_info.hairpin_q) { > > + err = cpfl_tx_queue_start(dev, i); > > + if (err != 0) { > > + PMD_DRV_LOG(ERR, "Fail to start Tx > > queue %u", i); > > + return err; > > + } > > + } else if (!cpfl_txq->hairpin_info.manual_bind) { > > + if (flag == 0) { > > + err = cpfl_txq_hairpin_info_update(dev, > > + cpfl_txq- > > >hairpin_info.peer_rxp); > > + if (err != 0) { > > + PMD_DRV_LOG(ERR, "Fail to update > Tx > > hairpin queue info"); > > + return err; > > + } > > + flag = 1; > [Liu, Mingxia] The variable flag is not been used, can it be removed? It's used in above code, txq_hairpin_info should be updated once. > > + } > > + err = cpfl_hairpin_txq_config(vport, cpfl_txq); > > + if (err != 0) { > > + PMD_DRV_LOG(ERR, "Fail to configure hairpin > > Tx queue %u", i); > > + return err; > > + } > > + tx_cmplq_flag = 1; > > + } > > + } > > + > > > + /* For non-cross vport hairpin queues, configure Tx completion queue > > first.*/ > > + if (tx_cmplq_flag == 1 && cpfl_vport->p2p_tx_complq != NULL) { > > + err = cpfl_hairpin_tx_complq_config(cpfl_vport); > > if (err != 0) { > > - PMD_DRV_LOG(ERR, "Fail to start Tx queue %u", i); > > + PMD_DRV_LOG(ERR, "Fail to config Tx completion > > queue"); > > return err; > > } > > } > > > [Liu, Mingxia] Better to move this code next to > + err = cpfl_hairpin_txq_config(vport, cpfl_txq); > + if (err != 0) { > + PMD_DRV_LOG(ERR, "Fail to configure hairpin > Tx queue %u", i); > + return err; > + } > When cpfl_rxq->hairpin_info.hairpin_q is true, then cpfl_vport- > >p2p_tx_complq is not null, right ? > And remove tx_cmplq_flag? Hairpin tx completion queue should only be configured once, so it should not be in for loop. However, code is refined in v2. > > > + /* For normal data queues, configure, init and enale Rxq. > > + * For non-cross vport hairpin queues, configure Rxq, and then init Rxq. > > + */ > > + cpfl_rxq_hairpin_mz_bind(dev); > > for (i = 0; i < dev->data->nb_rx_queues; i++) { > > cpfl_rxq = dev->data->rx_queues[i]; > > if (cpfl_rxq == NULL || cpfl_rxq->base.rx_deferred_start) > > continue; > > - err = cpfl_rx_queue_start(dev, i); > > + if (!cpfl_rxq->hairpin_info.hairpin_q) { > > + err = cpfl_rx_queue_start(dev, i); > > + if (err != 0) { > > + PMD_DRV_LOG(ERR, "Fail to start Rx > > queue %u", i); > > + return err; > > + } > > + } else if (!cpfl_rxq->hairpin_info.manual_bind) { > > + err = cpfl_hairpin_rxq_config(vport, cpfl_rxq); > > + if (err != 0) { > > + PMD_DRV_LOG(ERR, "Fail to configure hairpin > > Rx queue %u", i); > > + return err; > > + } > > + err = cpfl_rx_queue_init(dev, i); > > + if (err != 0) { > > + PMD_DRV_LOG(ERR, "Fail to init hairpin Rx > > queue %u", i); > > + return err; > > + } > > + rx_bufq_flag = 1; > > + } > > + } > > + > > > + /* For non-cross vport hairpin queues, configure Rx buffer queue.*/ > > + if (rx_bufq_flag == 1 && cpfl_vport->p2p_rx_bufq != NULL) { > > + err = cpfl_hairpin_rx_bufq_config(cpfl_vport); > > if (err != 0) { > > - PMD_DRV_LOG(ERR, "Fail to start Rx queue %u", i); > > + PMD_DRV_LOG(ERR, "Fail to config Rx buffer queue"); > > return err; > > } > > } > [Liu, Mingxia] Similar to above. > > > diff --git a/drivers/net/cpfl/cpfl_rxtx.c > > b/drivers/net/cpfl/cpfl_rxtx.c index 64ed331a6d..040beb5bac 100644 > > --- a/drivers/net/cpfl/cpfl_rxtx.c > > +++ b/drivers/net/cpfl/cpfl_rxtx.c > > @@ -930,6 +930,86 @@ cpfl_tx_hairpin_queue_setup(struct rte_eth_dev > > *dev, uint16_t queue_idx, > > return 0; > > } > > > > +int > > +cpfl_hairpin_rx_bufq_config(struct cpfl_vport *cpfl_vport) { > > + struct idpf_rx_queue *rx_bufq = cpfl_vport->p2p_rx_bufq; > > + struct virtchnl2_rxq_info rxq_info[1] = {0}; > > + > > + rxq_info[0].type = VIRTCHNL2_QUEUE_TYPE_RX_BUFFER; > > + rxq_info[0].queue_id = rx_bufq->queue_id; > > + rxq_info[0].ring_len = rx_bufq->nb_rx_desc; > > + rxq_info[0].dma_ring_addr = rx_bufq->rx_ring_phys_addr; > > + rxq_info[0].desc_ids = VIRTCHNL2_RXDID_2_FLEX_SPLITQ_M; > > + rxq_info[0].rx_buffer_low_watermark = > > CPFL_RXBUF_LOW_WATERMARK; > > + rxq_info[0].model = VIRTCHNL2_QUEUE_MODEL_SPLIT; > > + rxq_info[0].data_buffer_size = rx_bufq->rx_buf_len; > > + rxq_info[0].buffer_notif_stride = CPFL_RX_BUF_STRIDE; > > + > > + return idpf_vc_rxq_config_by_info(&cpfl_vport->base, rxq_info, 1); } > > + > > +int > > +cpfl_hairpin_rxq_config(struct idpf_vport *vport, struct > > +cpfl_rx_queue > > +*cpfl_rxq) { > > + struct virtchnl2_rxq_info rxq_info[1] = {0}; > > + struct idpf_rx_queue *rxq = &cpfl_rxq->base; > > + > > + rxq_info[0].type = VIRTCHNL2_QUEUE_TYPE_RX; > > + rxq_info[0].queue_id = rxq->queue_id; > > + rxq_info[0].ring_len = rxq->nb_rx_desc; > > + rxq_info[0].dma_ring_addr = rxq->rx_ring_phys_addr; > > + rxq_info[0].rx_bufq1_id = rxq->bufq1->queue_id; > > + rxq_info[0].max_pkt_size = vport->max_pkt_len; > > + rxq_info[0].desc_ids = VIRTCHNL2_RXDID_2_FLEX_SPLITQ_M; > > + rxq_info[0].qflags |= VIRTCHNL2_RX_DESC_SIZE_16BYTE; > > + > > + rxq_info[0].data_buffer_size = rxq->rx_buf_len; > > + rxq_info[0].model = VIRTCHNL2_QUEUE_MODEL_SPLIT; > > + rxq_info[0].rx_buffer_low_watermark = > > CPFL_RXBUF_LOW_WATERMARK; > > + > > + PMD_DRV_LOG(NOTICE, "hairpin: vport %u, Rxq id 0x%x", > > + vport->vport_id, rxq_info[0].queue_id); > > + > > + return idpf_vc_rxq_config_by_info(vport, rxq_info, 1); } > > + > > +int > > +cpfl_hairpin_tx_complq_config(struct cpfl_vport *cpfl_vport) { > > + struct idpf_tx_queue *tx_complq = cpfl_vport->p2p_tx_complq; > > + struct virtchnl2_txq_info txq_info[1] = {0}; > > + > > + txq_info[0].dma_ring_addr = tx_complq->tx_ring_phys_addr; > > + txq_info[0].type = VIRTCHNL2_QUEUE_TYPE_TX_COMPLETION; > > + txq_info[0].queue_id = tx_complq->queue_id; > > + txq_info[0].ring_len = tx_complq->nb_tx_desc; > > + txq_info[0].peer_rx_queue_id = cpfl_vport->p2p_rx_bufq->queue_id; > > + txq_info[0].model = VIRTCHNL2_QUEUE_MODEL_SPLIT; > > + txq_info[0].sched_mode = VIRTCHNL2_TXQ_SCHED_MODE_FLOW; > > + > > + return idpf_vc_txq_config_by_info(&cpfl_vport->base, txq_info, 1); } > > + > > +int > > +cpfl_hairpin_txq_config(struct idpf_vport *vport, struct > > +cpfl_tx_queue > > +*cpfl_txq) { > > + struct idpf_tx_queue *txq = &cpfl_txq->base; > > + struct virtchnl2_txq_info txq_info[1] = {0}; > > + > > + txq_info[0].dma_ring_addr = txq->tx_ring_phys_addr; > > + txq_info[0].type = VIRTCHNL2_QUEUE_TYPE_TX; > > + txq_info[0].queue_id = txq->queue_id; > > + txq_info[0].ring_len = txq->nb_tx_desc; > > + txq_info[0].tx_compl_queue_id = txq->complq->queue_id; > > + txq_info[0].relative_queue_id = txq->queue_id; > > + txq_info[0].peer_rx_queue_id = cpfl_txq->hairpin_info.peer_rxq_id; > > + txq_info[0].model = VIRTCHNL2_QUEUE_MODEL_SPLIT; > > + txq_info[0].sched_mode = VIRTCHNL2_TXQ_SCHED_MODE_FLOW; > > + > > + return idpf_vc_txq_config_by_info(vport, txq_info, 1); } > > + > > int > > cpfl_rx_queue_init(struct rte_eth_dev *dev, uint16_t rx_queue_id) { > > diff --git a/drivers/net/cpfl/cpfl_rxtx.h > > b/drivers/net/cpfl/cpfl_rxtx.h index > > d844c9f057..b01ce5edf9 100644 > > --- a/drivers/net/cpfl/cpfl_rxtx.h > > +++ b/drivers/net/cpfl/cpfl_rxtx.h > > @@ -30,12 +30,15 @@ > > #define CPFL_RING_BASE_ALIGN 128 > > > > #define CPFL_DEFAULT_RX_FREE_THRESH 32 > > +#define CPFL_RXBUF_LOW_WATERMARK 64 > > > > #define CPFL_DEFAULT_TX_RS_THRESH 32 > > #define CPFL_DEFAULT_TX_FREE_THRESH 32 > > > > #define CPFL_SUPPORT_CHAIN_NUM 5 > > > > +#define CPFL_RX_BUF_STRIDE 64 > > + > > struct cpfl_rxq_hairpin_info { > > bool hairpin_q; /* if rx queue is a hairpin queue */ > > bool manual_bind; /* for cross vport */ > > @@ -85,4 +88,8 @@ int cpfl_rx_hairpin_queue_setup(struct rte_eth_dev > > *dev, uint16_t queue_idx, int cpfl_tx_hairpin_queue_setup(struct > > rte_eth_dev *dev, uint16_t queue_idx, > > uint16_t nb_desc, > > const struct rte_eth_hairpin_conf *conf); > > +int cpfl_hairpin_tx_complq_config(struct cpfl_vport *cpfl_vport); int > > +cpfl_hairpin_txq_config(struct idpf_vport *vport, struct > > +cpfl_tx_queue *cpfl_txq); int cpfl_hairpin_rx_bufq_config(struct > > +cpfl_vport *cpfl_vport); int cpfl_hairpin_rxq_config(struct > > +idpf_vport *vport, struct cpfl_rx_queue *cpfl_rxq); > > #endif /* _CPFL_RXTX_H_ */ > > -- > > 2.26.2