The Tx queue was set up first and left in place when the Rx queue
setup failed. A new setup of the same queue pair, either a retry after
such a failure or a reconfiguration, then overwrote the previous queue
pointers without freeing them.
Check the shared configuration before setting up any queue, release
the queues of a previous setup, and release the Tx queue if the Rx
queue setup fails. As the previous queues are released, refuse the
setup while the device is started.
Fixes: c39d1e082a4b ("raw/ntb: setup queues")
Cc: [email protected]
Suggested-by: Stephen Hemminger <[email protected]>
Signed-off-by: Raghavendra Ningoji <[email protected]>
---
drivers/raw/ntb/ntb.c | 64 +++++++++++++++++++++++++------------------
1 file changed, 37 insertions(+), 27 deletions(-)
diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index 8b1c332fbb..68137c4237 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -235,10 +235,8 @@ ntb_rxq_release_mbufs(struct ntb_rx_queue *q)
static void
ntb_rxq_release(struct ntb_rx_queue *rxq)
{
- if (!rxq) {
- NTB_LOG(ERR, "Pointer to rxq is NULL");
+ if (!rxq)
return;
- }
ntb_rxq_release_mbufs(rxq);
@@ -273,11 +271,6 @@ ntb_rxq_setup(struct rte_rawdev *dev,
if (conf_size != sizeof(*rxq_conf))
return -EINVAL;
- if (rxq_conf->rx_mp == NULL) {
- NTB_LOG(ERR, "Invalid null mempool pointer.");
- return -EINVAL;
- }
-
if (ntb_queue_nb_desc_check(rxq_conf->nb_desc) < 0)
return -EINVAL;
@@ -338,10 +331,8 @@ ntb_txq_release_mbufs(struct ntb_tx_queue *q)
static void
ntb_txq_release(struct ntb_tx_queue *txq)
{
- if (!txq) {
- NTB_LOG(ERR, "Pointer to txq is NULL");
+ if (!txq)
return;
- }
ntb_txq_release_mbufs(txq);
@@ -422,43 +413,62 @@ ntb_txq_setup(struct rte_rawdev *dev,
}
+static int
+ntb_queue_release(struct rte_rawdev *dev, uint16_t queue_id)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (queue_id >= hw->queue_pairs)
+ return -EINVAL;
+
+ ntb_txq_release(hw->tx_queues[queue_id]);
+ hw->tx_queues[queue_id] = NULL;
+ ntb_rxq_release(hw->rx_queues[queue_id]);
+ hw->rx_queues[queue_id] = NULL;
+
+ return 0;
+}
+
static int
ntb_queue_setup(struct rte_rawdev *dev,
uint16_t queue_id,
rte_rawdev_obj_t queue_conf,
size_t conf_size)
{
+ struct ntb_queue_conf *conf = queue_conf;
struct ntb_hw *hw = dev->dev_private;
int ret;
if (queue_id >= hw->queue_pairs)
return -EINVAL;
+ if (conf == NULL || conf_size != sizeof(*conf))
+ return -EINVAL;
+
+ if (conf->rx_mp == NULL) {
+ NTB_LOG(ERR, "Invalid null mempool pointer.");
+ return -EINVAL;
+ }
+
+ if (dev->started) {
+ NTB_LOG(ERR, "Cannot setup queue %u of a started device.",
queue_id);
+ return -EBUSY;
+ }
+
+ /* Release the queues of a previous setup. */
+ ntb_queue_release(dev, queue_id);
+
ret = ntb_txq_setup(dev, queue_id, queue_conf, conf_size);
if (ret < 0)
return ret;
ret = ntb_rxq_setup(dev, queue_id, queue_conf, conf_size);
+ if (ret < 0)
+ ntb_queue_release(dev, queue_id);
return ret;
}
-static int
-ntb_queue_release(struct rte_rawdev *dev, uint16_t queue_id)
-{
- struct ntb_hw *hw = dev->dev_private;
-
- if (queue_id >= hw->queue_pairs)
- return -EINVAL;
-
- ntb_txq_release(hw->tx_queues[queue_id]);
- hw->tx_queues[queue_id] = NULL;
- ntb_rxq_release(hw->rx_queues[queue_id]);
- hw->rx_queues[queue_id] = NULL;
-
- return 0;
-}
-
static uint16_t
ntb_queue_count(struct rte_rawdev *dev)
{
--
2.34.1