net/tap: fix file close on remove
[dpdk.git] / drivers / net / tap / rte_eth_tap.c
index 6d54c25..41ea548 100644 (file)
@@ -338,6 +338,23 @@ tap_rx_offload_get_queue_capa(void)
               DEV_RX_OFFLOAD_TCP_CKSUM;
 }
 
+static void
+tap_rxq_pool_free(struct rte_mbuf *pool)
+{
+       struct rte_mbuf *mbuf = pool;
+       uint16_t nb_segs = 1;
+
+       if (mbuf == NULL)
+               return;
+
+       while (mbuf->next) {
+               mbuf = mbuf->next;
+               nb_segs++;
+       }
+       pool->nb_segs = nb_segs;
+       rte_pktmbuf_free(pool);
+}
+
 /* Callback to handle the rx burst of packets to the correct interface and
  * file descriptor(s) in a multi-queue setup.
  */
@@ -388,7 +405,7 @@ pmd_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
                                        goto end;
 
                                seg->next = NULL;
-                               rte_pktmbuf_free(mbuf);
+                               tap_rxq_pool_free(mbuf);
 
                                goto end;
                        }
@@ -1020,15 +1037,25 @@ tap_dev_close(struct rte_eth_dev *dev)
        int i;
        struct pmd_internals *internals = dev->data->dev_private;
        struct pmd_process_private *process_private = dev->process_private;
+       struct rx_queue *rxq;
 
        tap_link_set_down(dev);
-       tap_flow_flush(dev, NULL);
-       tap_flow_implicit_flush(internals, NULL);
+       if (internals->nlsk_fd != -1) {
+               tap_flow_flush(dev, NULL);
+               tap_flow_implicit_flush(internals, NULL);
+               tap_nl_final(internals->nlsk_fd);
+               internals->nlsk_fd = -1;
+       }
 
        for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) {
                if (process_private->rxq_fds[i] != -1) {
+                       rxq = &internals->rxq[i];
                        close(process_private->rxq_fds[i]);
                        process_private->rxq_fds[i] = -1;
+                       tap_rxq_pool_free(rxq->pool);
+                       rte_free(rxq->iovecs);
+                       rxq->pool = NULL;
+                       rxq->iovecs = NULL;
                }
                if (process_private->txq_fds[i] != -1) {
                        close(process_private->txq_fds[i]);
@@ -1064,7 +1091,7 @@ tap_rx_queue_release(void *queue)
        if (process_private->rxq_fds[rxq->queue_id] > 0) {
                close(process_private->rxq_fds[rxq->queue_id]);
                process_private->rxq_fds[rxq->queue_id] = -1;
-               rte_pktmbuf_free(rxq->pool);
+               tap_rxq_pool_free(rxq->pool);
                rte_free(rxq->iovecs);
                rxq->pool = NULL;
                rxq->iovecs = NULL;
@@ -1474,7 +1501,7 @@ tap_rx_queue_setup(struct rte_eth_dev *dev,
        return 0;
 
 error:
-       rte_pktmbuf_free(rxq->pool);
+       tap_rxq_pool_free(rxq->pool);
        rxq->pool = NULL;
        rte_free(rxq->iovecs);
        rxq->iovecs = NULL;
@@ -2398,8 +2425,6 @@ rte_pmd_tap_remove(struct rte_vdev_device *dev)
 {
        struct rte_eth_dev *eth_dev = NULL;
        struct pmd_internals *internals;
-       struct pmd_process_private *process_private;
-       int i;
 
        /* find the ethdev entry */
        eth_dev = rte_eth_dev_allocated(rte_vdev_device_name(dev));
@@ -2412,28 +2437,12 @@ rte_pmd_tap_remove(struct rte_vdev_device *dev)
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return rte_eth_dev_release_port(eth_dev);
 
-       internals = eth_dev->data->dev_private;
-       process_private = eth_dev->process_private;
+       tap_dev_close(eth_dev);
 
+       internals = eth_dev->data->dev_private;
        TAP_LOG(DEBUG, "Closing %s Ethernet device on numa %u",
                tuntap_types[internals->type], rte_socket_id());
 
-       if (internals->nlsk_fd) {
-               tap_flow_flush(eth_dev, NULL);
-               tap_flow_implicit_flush(internals, NULL);
-               tap_nl_final(internals->nlsk_fd);
-       }
-       for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) {
-               if (process_private->rxq_fds[i] != -1) {
-                       close(process_private->rxq_fds[i]);
-                       process_private->rxq_fds[i] = -1;
-               }
-               if (process_private->txq_fds[i] != -1) {
-                       close(process_private->txq_fds[i]);
-                       process_private->txq_fds[i] = -1;
-               }
-       }
-
        close(internals->ioctl_sock);
        rte_free(eth_dev->process_private);
        if (tap_devices_count == 1)
@@ -2441,10 +2450,6 @@ rte_pmd_tap_remove(struct rte_vdev_device *dev)
        tap_devices_count--;
        rte_eth_dev_release_port(eth_dev);
 
-       if (internals->ka_fd != -1) {
-               close(internals->ka_fd);
-               internals->ka_fd = -1;
-       }
        return 0;
 }