net/netvsc: free all queues on close

When dev_close is called, the netvsc driver will clean up all
queues including the primary ring buffer.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
This commit is contained in:
Stephen Hemminger 2019-04-30 11:12:17 -07:00 committed by Ferruh Yigit
parent 05bfd4b491
commit 8428da7285
4 changed files with 54 additions and 12 deletions

View File

@ -112,6 +112,9 @@ eth_dev_vmbus_allocate(struct rte_vmbus_device *dev, size_t private_data_size)
eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
eth_dev->intr_handle = &dev->intr_handle;
/* allow ethdev to remove on close */
eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
return eth_dev;
}
@ -632,11 +635,12 @@ hn_dev_stop(struct rte_eth_dev *dev)
}
static void
hn_dev_close(struct rte_eth_dev *dev __rte_unused)
hn_dev_close(struct rte_eth_dev *dev)
{
PMD_INIT_LOG(DEBUG, "close");
PMD_INIT_FUNC_TRACE();
hn_vf_close(dev);
hn_dev_free_queues(dev);
}
static const struct eth_dev_ops hn_eth_dev_ops = {

View File

@ -840,12 +840,9 @@ hn_dev_rx_queue_setup(struct rte_eth_dev *dev,
return error;
}
void
hn_dev_rx_queue_release(void *arg)
static void
hn_rx_queue_free(struct hn_rx_queue *rxq, bool keep_primary)
{
struct hn_rx_queue *rxq = arg;
PMD_INIT_FUNC_TRACE();
if (!rxq)
return;
@ -857,10 +854,21 @@ hn_dev_rx_queue_release(void *arg)
hn_vf_rx_queue_release(rxq->hv, rxq->queue_id);
/* Keep primary queue to allow for control operations */
if (rxq != rxq->hv->primary) {
rte_free(rxq->event_buf);
rte_free(rxq);
}
if (keep_primary && rxq == rxq->hv->primary)
return;
rte_free(rxq->event_buf);
rte_free(rxq);
}
void
hn_dev_rx_queue_release(void *arg)
{
struct hn_rx_queue *rxq = arg;
PMD_INIT_FUNC_TRACE();
hn_rx_queue_free(rxq, true);
}
int
@ -1440,3 +1448,23 @@ hn_recv_pkts(void *prxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
return nb_rcv;
}
void
hn_dev_free_queues(struct rte_eth_dev *dev)
{
unsigned int i;
for (i = 0; i < dev->data->nb_rx_queues; i++) {
struct hn_rx_queue *rxq = dev->data->rx_queues[i];
hn_rx_queue_free(rxq, false);
dev->data->rx_queues[i] = NULL;
}
dev->data->nb_rx_queues = 0;
for (i = 0; i < dev->data->nb_tx_queues; i++) {
hn_dev_tx_queue_release(dev->data->tx_queues[i]);
dev->data->tx_queues[i] = NULL;
}
dev->data->nb_tx_queues = 0;
}

View File

@ -173,6 +173,7 @@ int hn_dev_rx_queue_setup(struct rte_eth_dev *dev,
const struct rte_eth_rxconf *rx_conf,
struct rte_mempool *mp);
void hn_dev_rx_queue_release(void *arg);
void hn_dev_free_queues(struct rte_eth_dev *dev);
/* Check if VF is attached */
static inline bool

View File

@ -362,7 +362,16 @@ void hn_vf_reset(struct rte_eth_dev *dev)
void hn_vf_close(struct rte_eth_dev *dev)
{
VF_ETHDEV_FUNC(dev, rte_eth_dev_close);
struct hn_data *hv = dev->data->dev_private;
uint16_t vf_port;
rte_spinlock_lock(&hv->vf_lock);
vf_port = hv->vf_port;
if (vf_port != HN_INVALID_PORT)
rte_eth_dev_close(vf_port);
hv->vf_port = HN_INVALID_PORT;
rte_spinlock_unlock(&hv->vf_lock);
}
void hn_vf_stats_reset(struct rte_eth_dev *dev)