summaryrefslogtreecommitdiff
path: root/drivers/net/failsafe
diff options
context:
space:
mode:
authorIgor Romanov <igor.romanov@oktetlabs.ru>2018-08-31 17:16:32 +0100
committerFerruh Yigit <ferruh.yigit@intel.com>2018-09-28 01:41:02 +0200
commit6b35f4d88b40645425b4b8e156423982471eccf5 (patch)
tree5e9d85fb34830ef9b5905b2da73050ed93211b53 /drivers/net/failsafe
parentd7fe5a2861e7be43be746592193fe57b57601c9e (diff)
downloaddpdk-next-eventdev-6b35f4d88b40645425b4b8e156423982471eccf5.zip
dpdk-next-eventdev-6b35f4d88b40645425b4b8e156423982471eccf5.tar.gz
dpdk-next-eventdev-6b35f4d88b40645425b4b8e156423982471eccf5.tar.xz
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 <igor.romanov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Diffstat (limited to 'drivers/net/failsafe')
-rw-r--r--drivers/net/failsafe/failsafe_ops.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index d989a17..49b1550 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);