Implement rte_pmd_af_packet_devuninit() exposed through struct
rte_driver.uninit() and set dev_flags to RTE_ETH_DEV_DETACHABLE,
to allow af_packet device deinitialization with API function
rte_eth_dev_detach(). This fixes memory leak by freeing memory
allocated during initialization.
During device initialization copy device name to ethdev->data to make
it compatible with rte_eth_dev_allocated().

Signed-off-by: Wojciech Zmuda <woz at semihalf.com>
---
v2:
* Fixed typo and a comment.
* Added feature to the 2.3 release notes.
* Free memory allocated for rx and tx queues.

 doc/guides/rel_notes/release_2_3.rst      |  4 ++++
 drivers/net/af_packet/rte_eth_af_packet.c | 37 ++++++++++++++++++++++++++++++-
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_2_3.rst 
b/doc/guides/rel_notes/release_2_3.rst
index 7945694..4694646 100644
--- a/doc/guides/rel_notes/release_2_3.rst
+++ b/doc/guides/rel_notes/release_2_3.rst
@@ -39,6 +39,10 @@ This section should contain new features added in this 
release. Sample format:

   Enabled virtio 1.0 support for virtio pmd driver.

+* **Added af_packet driver deinitialization function.**
+
+  Implemented rte_pmd_af_packet_devuninit() exposed through struct
+  rte_driver.uninit() to allow af_packet device deinitialization with API 
function.

 Resolved Issues
 ---------------
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c 
b/drivers/net/af_packet/rte_eth_af_packet.c
index 767f36b..eaed916 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -667,11 +667,13 @@ rte_pmd_init_internals(const char *name,
        data->nb_tx_queues = (uint16_t)nb_queues;
        data->dev_link = pmd_link;
        data->mac_addrs = &(*internals)->eth_addr;
+       strncpy(data->name,
+               (*eth_dev)->data->name, strlen((*eth_dev)->data->name));

        (*eth_dev)->data = data;
        (*eth_dev)->dev_ops = &ops;
        (*eth_dev)->driver = NULL;
-       (*eth_dev)->data->dev_flags = 0;
+       (*eth_dev)->data->dev_flags = RTE_ETH_DEV_DETACHABLE;
        (*eth_dev)->data->drv_name = drivername;
        (*eth_dev)->data->kdrv = RTE_KDRV_NONE;
        (*eth_dev)->data->numa_node = numa_node;
@@ -836,10 +838,43 @@ exit:
        return ret;
 }

+static int
+rte_pmd_af_packet_devuninit(const char *name)
+{
+       struct rte_eth_dev *eth_dev = NULL;
+       struct pmd_internals *internals;
+       unsigned q;
+
+       RTE_LOG(INFO, PMD, "Closing AF_PACKET ethdev on numa socket %u\n",
+                       rte_socket_id());
+
+       if (name == NULL)
+               return -1;
+
+       /* find the ethdev entry */
+       eth_dev = rte_eth_dev_allocated(name);
+       if (eth_dev == NULL)
+               return -1;
+
+       internals = eth_dev->data->dev_private;
+       for (q = 0; q < internals->nb_queues; q++) {
+               rte_free(internals->rx_queue[q].rd);
+               rte_free(internals->tx_queue[q].rd);
+       }
+
+       rte_free(eth_dev->data->dev_private);
+       rte_free(eth_dev->data);
+
+       rte_eth_dev_release_port(eth_dev);
+
+       return 0;
+}
+
 static struct rte_driver pmd_af_packet_drv = {
        .name = "eth_af_packet",
        .type = PMD_VDEV,
        .init = rte_pmd_af_packet_devinit,
+       .uninit = rte_pmd_af_packet_devuninit,
 };

 PMD_REGISTER_DRIVER(pmd_af_packet_drv);
-- 
1.9.1

Reply via email to