[6/7] net/hns3: fix queue state when concurrent with reset
Checks
Commit Message
From: Chengchang Tang <tangchengchang@huawei.com>
At the end of the reset, the state of queues need to be restored according
to the states saved in the driver. If the start and stop operations of the
queues are concurrent at this time, it may cause the final status to be
uncertain.
This patch requires queues to acquire the hw lock before starting and
stopping. If the device is being restored due to reset at this time, it
will block until the reset is completed.
Fixes: fa29fe45a7b4 ("net/hns3: support queue start and stop")
Cc: stable@dpdk.org
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
drivers/net/hns3/hns3_rxtx.c | 11 +++++++++++
1 file changed, 11 insertions(+)
@@ -4270,10 +4270,12 @@ hns3_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
if (!hns3_dev_indep_txrx_supported(hw))
return -ENOTSUP;
+ rte_spinlock_lock(&hw->lock);
ret = hns3_reset_queue(hw, rx_queue_id, HNS3_RING_TYPE_RX);
if (ret) {
hns3_err(hw, "fail to reset Rx queue %u, ret = %d.",
rx_queue_id, ret);
+ rte_spinlock_unlock(&hw->lock);
return ret;
}
@@ -4281,11 +4283,13 @@ hns3_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
if (ret) {
hns3_err(hw, "fail to init Rx queue %u, ret = %d.",
rx_queue_id, ret);
+ rte_spinlock_unlock(&hw->lock);
return ret;
}
hns3_enable_rxq(rxq, true);
dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
+ rte_spinlock_unlock(&hw->lock);
return ret;
}
@@ -4312,12 +4316,14 @@ hns3_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
if (!hns3_dev_indep_txrx_supported(hw))
return -ENOTSUP;
+ rte_spinlock_lock(&hw->lock);
hns3_enable_rxq(rxq, false);
hns3_rx_queue_release_mbufs(rxq);
hns3_reset_sw_rxq(rxq);
dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+ rte_spinlock_unlock(&hw->lock);
return 0;
}
@@ -4332,16 +4338,19 @@ hns3_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
if (!hns3_dev_indep_txrx_supported(hw))
return -ENOTSUP;
+ rte_spinlock_lock(&hw->lock);
ret = hns3_reset_queue(hw, tx_queue_id, HNS3_RING_TYPE_TX);
if (ret) {
hns3_err(hw, "fail to reset Tx queue %u, ret = %d.",
tx_queue_id, ret);
+ rte_spinlock_unlock(&hw->lock);
return ret;
}
hns3_init_txq(txq);
hns3_enable_txq(txq, true);
dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
+ rte_spinlock_unlock(&hw->lock);
return ret;
}
@@ -4355,6 +4364,7 @@ hns3_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
if (!hns3_dev_indep_txrx_supported(hw))
return -ENOTSUP;
+ rte_spinlock_lock(&hw->lock);
hns3_enable_txq(txq, false);
hns3_tx_queue_release_mbufs(txq);
/*
@@ -4366,6 +4376,7 @@ hns3_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
*/
hns3_init_txq(txq);
dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+ rte_spinlock_unlock(&hw->lock);
return 0;
}