From: Stephen Hemminger Date: Tue, 30 Apr 2019 18:12:17 +0000 (-0700) Subject: net/netvsc: free all queues on close X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=8428da72855a112180f4d2d48afe0d443037ea3d;p=dpdk.git 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 --- diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c index 407ee48493..553cb06f6e 100644 --- a/drivers/net/netvsc/hn_ethdev.c +++ b/drivers/net/netvsc/hn_ethdev.c @@ -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 = { diff --git a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c index 7856f7e6ec..7d7b557785 100644 --- a/drivers/net/netvsc/hn_rxtx.c +++ b/drivers/net/netvsc/hn_rxtx.c @@ -840,12 +840,9 @@ fail: 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; +} diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h index 8383f3246c..de885d898e 100644 --- a/drivers/net/netvsc/hn_var.h +++ b/drivers/net/netvsc/hn_var.h @@ -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 diff --git a/drivers/net/netvsc/hn_vf.c b/drivers/net/netvsc/hn_vf.c index 883272ff49..b980bb8a4d 100644 --- a/drivers/net/netvsc/hn_vf.c +++ b/drivers/net/netvsc/hn_vf.c @@ -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)