From: Igor Romanov Date: Fri, 31 Aug 2018 16:16:32 +0000 (+0100) Subject: net/failsafe: fix crash on slave queue release X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=6b35f4d88b40645425b4b8e156423982471eccf5;p=dpdk.git net/failsafe: fix crash on slave queue release Releasing a queue that is already released by slave may cause a segmentation fault. For example, after a successfull device configuration a queue is set up. Afterwards the device is reconfigured with an invalid argument, forcing slaves to release the queues (e.g. rte_eth_dev.data.tx_queues). Finally the failsafe's queues are released. The queue release functions also try to release slaves' queues using ETH(sdev)->data->tx_queues which is NULL at the time. Add checks for NULL slaves' Tx and Rx queues before releasing them. Fixes: a46f8d584eb8 ("net/failsafe: add fail-safe PMD") Cc: stable@dpdk.org Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Acked-by: Gaetan Rivet --- diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c index d989a17bf9..49b155045d 100644 --- a/drivers/net/failsafe/failsafe_ops.c +++ b/drivers/net/failsafe/failsafe_ops.c @@ -307,9 +307,13 @@ fs_rx_queue_release(void *queue) fs_lock(dev, 0); if (rxq->event_fd > 0) close(rxq->event_fd); - FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) - SUBOPS(sdev, rx_queue_release) - (ETH(sdev)->data->rx_queues[rxq->qid]); + FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) { + if (ETH(sdev)->data->rx_queues != NULL && + ETH(sdev)->data->rx_queues[rxq->qid] != NULL) { + SUBOPS(sdev, rx_queue_release) + (ETH(sdev)->data->rx_queues[rxq->qid]); + } + } dev->data->rx_queues[rxq->qid] = NULL; rte_free(rxq); fs_unlock(dev, 0); @@ -475,9 +479,13 @@ fs_tx_queue_release(void *queue) txq = queue; dev = txq->priv->dev; fs_lock(dev, 0); - FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) - SUBOPS(sdev, tx_queue_release) - (ETH(sdev)->data->tx_queues[txq->qid]); + FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) { + if (ETH(sdev)->data->tx_queues != NULL && + ETH(sdev)->data->tx_queues[txq->qid] != NULL) { + SUBOPS(sdev, tx_queue_release) + (ETH(sdev)->data->tx_queues[txq->qid]); + } + } dev->data->tx_queues[txq->qid] = NULL; rte_free(txq); fs_unlock(dev, 0);