From: Chengchang Tang <[email protected]>
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: [email protected]
Signed-off-by: Chengchang Tang <[email protected]>
Signed-off-by: Min Hu (Connor) <[email protected]>
---
drivers/net/hns3/hns3_rxtx.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index be93618..b45afcd 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -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;
}
--
2.7.4