net/netvsc: detach external buffer on failure
[dpdk.git] / drivers / net / tap / rte_eth_tap.c
index 41ea548..339f24b 100644 (file)
@@ -18,6 +18,7 @@
 #include <rte_string_fns.h>
 #include <rte_ethdev.h>
 #include <rte_errno.h>
+#include <rte_cycles.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -1088,7 +1089,7 @@ tap_rx_queue_release(void *queue)
        if (!rxq)
                return;
        process_private = rte_eth_devices[rxq->in_port].process_private;
-       if (process_private->rxq_fds[rxq->queue_id] > 0) {
+       if (process_private->rxq_fds[rxq->queue_id] != -1) {
                close(process_private->rxq_fds[rxq->queue_id]);
                process_private->rxq_fds[rxq->queue_id] = -1;
                tap_rxq_pool_free(rxq->pool);
@@ -1108,7 +1109,7 @@ tap_tx_queue_release(void *queue)
                return;
        process_private = rte_eth_devices[txq->out_port].process_private;
 
-       if (process_private->txq_fds[txq->queue_id] > 0) {
+       if (process_private->txq_fds[txq->queue_id] != -1) {
                close(process_private->txq_fds[txq->queue_id]);
                process_private->txq_fds[txq->queue_id] = -1;
        }
@@ -1599,13 +1600,12 @@ static int
 tap_lsc_intr_handle_set(struct rte_eth_dev *dev, int set)
 {
        struct pmd_internals *pmd = dev->data->dev_private;
+       int ret;
 
        /* In any case, disable interrupt if the conf is no longer there. */
        if (!dev->data->dev_conf.intr_conf.lsc) {
                if (pmd->intr_handle.fd != -1) {
-                       tap_nl_final(pmd->intr_handle.fd);
-                       rte_intr_callback_unregister(&pmd->intr_handle,
-                               tap_dev_intr_handler, dev);
+                       goto clean;
                }
                return 0;
        }
@@ -1616,9 +1616,26 @@ tap_lsc_intr_handle_set(struct rte_eth_dev *dev, int set)
                return rte_intr_callback_register(
                        &pmd->intr_handle, tap_dev_intr_handler, dev);
        }
+
+clean:
+       do {
+               ret = rte_intr_callback_unregister(&pmd->intr_handle,
+                       tap_dev_intr_handler, dev);
+               if (ret >= 0) {
+                       break;
+               } else if (ret == -EAGAIN) {
+                       rte_delay_ms(100);
+               } else {
+                       TAP_LOG(ERR, "intr callback unregister failed: %d",
+                                    ret);
+                       break;
+               }
+       } while (true);
+
        tap_nl_final(pmd->intr_handle.fd);
-       return rte_intr_callback_unregister(&pmd->intr_handle,
-                                           tap_dev_intr_handler, dev);
+       pmd->intr_handle.fd = -1;
+
+       return 0;
 }
 
 static int
@@ -1823,6 +1840,8 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
        pmd->dev = dev;
        strlcpy(pmd->name, tap_name, sizeof(pmd->name));
        pmd->type = type;
+       pmd->ka_fd = -1;
+       pmd->nlsk_fd = -1;
 
        pmd->ioctl_sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (pmd->ioctl_sock == -1) {
@@ -1853,7 +1872,6 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
        dev->intr_handle = &pmd->intr_handle;
 
        /* Presetup the fds to -1 as being not valid */
-       pmd->ka_fd = -1;
        for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) {
                process_private->rxq_fds[i] = -1;
                process_private->txq_fds[i] = -1;
@@ -1993,7 +2011,11 @@ error_remote:
        tap_flow_implicit_flush(pmd, NULL);
 
 error_exit:
-       if (pmd->ioctl_sock > 0)
+       if (pmd->nlsk_fd != -1)
+               close(pmd->nlsk_fd);
+       if (pmd->ka_fd != -1)
+               close(pmd->ka_fd);
+       if (pmd->ioctl_sock != -1)
                close(pmd->ioctl_sock);
        /* mac_addrs must not be freed alone because part of dev_private */
        dev->data->mac_addrs = NULL;
@@ -2472,11 +2494,4 @@ RTE_PMD_REGISTER_PARAM_STRING(net_tap,
                              ETH_TAP_IFACE_ARG "=<string> "
                              ETH_TAP_MAC_ARG "=" ETH_TAP_MAC_ARG_FMT " "
                              ETH_TAP_REMOTE_ARG "=<string>");
-int tap_logtype;
-
-RTE_INIT(tap_init_log)
-{
-       tap_logtype = rte_log_register("pmd.net.tap");
-       if (tap_logtype >= 0)
-               rte_log_set_level(tap_logtype, RTE_LOG_NOTICE);
-}
+RTE_LOG_REGISTER(tap_logtype, pmd.net.tap, NOTICE);