Thanks for the feedback Long. I've made both changes you suggested, plus one additional one to not try and allocate an mbuf if the pool is null.
This means if a packet is received on a Rx queue that isn't being polled we will see it appear as "mbuf allocation failed" rather than causing a segfault. Cheers, Alan > -----Original Message----- > From: Long Li <lon...@microsoft.com> > Sent: Tuesday, March 12, 2024 7:09 PM > To: Alan Elder <alan.el...@microsoft.com>; Ferruh Yigit > <ferruh.yi...@amd.com>; Andrew Rybchenko > <andrew.rybche...@oktetlabs.ru> > Cc: dev@dpdk.org; stephen <step...@networkplumber.org> > Subject: RE: [PATCH v2] net/netvsc: fix number Tx queues > Rx queues > > > a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c index > > 9bf1ec5509..c0aaeaa972 100644 > > --- a/drivers/net/netvsc/hn_rxtx.c > > +++ b/drivers/net/netvsc/hn_rxtx.c > > @@ -243,6 +243,7 @@ hn_dev_tx_queue_setup(struct rte_eth_dev *dev, { > > struct hn_data *hv = dev->data->dev_private; > > struct hn_tx_queue *txq; > > + struct hn_rx_queue *rxq; > > char name[RTE_MEMPOOL_NAMESIZE]; > > uint32_t tx_free_thresh; > > int err = -ENOMEM; > > @@ -301,6 +302,22 @@ hn_dev_tx_queue_setup(struct rte_eth_dev *dev, > > goto error; > > } > > > > + /* > > + * If there are more Tx queues than Rx queues, allocate rx_queues > > + * with event buffer so that Tx completion messages can still be > > + * received > > + */ > > + if (queue_idx >= dev->data->nb_rx_queues) { > > + rxq = hn_rx_queue_alloc(hv, queue_idx, socket_id); > > Need to check if rxq is NULL. > > > + /* > > + * Don't allocate mbuf pool or rx ring. RSS is always > > configured > > + * to ensure packets aren't received by this Rx queue. > > + */ > > + rxq->mb_pool = NULL; > > + rxq->rx_ring = NULL; > > + dev->data->rx_queues[queue_idx] = rxq; > > + } > > + > > txq->agg_szmax = RTE_MIN(hv->chim_szmax, hv->rndis_agg_size); > > txq->agg_pktmax = hv->rndis_agg_pkts; > > txq->agg_align = hv->rndis_agg_align; @@ -354,6 +371,17 @@ static > > void hn_txd_put(struct hn_tx_queue *txq, struct hn_txdesc *txd) > > rte_mempool_put(txq->txdesc_pool, txd); } > > > > +static void > > +hn_rx_queue_free_common(struct hn_rx_queue *rxq) { > > + if (!rxq) > > + return; > > + > > + rte_free(rxq->rxbuf_info); > > + rte_free(rxq->event_buf); > > + rte_free(rxq); > > +} > > + > > void > > hn_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid) { @@ > > -364,6 > > +392,13 @@ hn_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t > > +qid) > > if (!txq) > > return; > > > > + /* > > + * Free any Rx queues allocated for a Tx queue without a > corresponding > > + * Rx queue > > + */ > > + if (qid >= dev->data->nb_rx_queues) > > + hn_rx_queue_free_common(dev->data->rx_queues[qid]); > > + > > rte_mempool_free(txq->txdesc_pool); > > > > rte_memzone_free(txq->tx_rndis_mz); > > @@ -942,6 +977,13 @@ hn_dev_rx_queue_setup(struct rte_eth_dev *dev, > > if (queue_idx == 0) { > > rxq = hv->primary; > > } else { > > + /* > > + * If the number of Tx queues was previously greater than > > + * the number of Rx queues, we may already have allocated > > + * an rxq. If so, free it now before allocating a new one. > > + */ > > + hn_rx_queue_free_common(dev->data- > > >rx_queues[queue_idx]); > > This logic seems strange. How about check if rxq is already allocated. If not, > allocate it. > > Something like: > > if (!dev->data->rx_queues[queue_idx]) > rxq = hn_rx_queue_alloc(hv, queue_idx, socket_id); > > > > Thanks, > > Long