net/mlx5: share Rx queue indirection table code
[dpdk.git] / drivers / net / tap / rte_eth_tap.c
index fea464c..b19e26b 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>
@@ -133,7 +134,7 @@ tun_alloc(struct pmd_internals *pmd, int is_keepalive)
 #ifdef IFF_MULTI_QUEUE
        unsigned int features;
 #endif
-       int fd;
+       int fd, signo, flags;
 
        memset(&ifr, 0, sizeof(struct ifreq));
 
@@ -198,52 +199,87 @@ tun_alloc(struct pmd_internals *pmd, int is_keepalive)
                }
        }
 
+       flags = fcntl(fd, F_GETFL);
+       if (flags == -1) {
+               TAP_LOG(WARNING,
+                       "Unable to get %s current flags\n",
+                       ifr.ifr_name);
+               goto error;
+       }
+
        /* Always set the file descriptor to non-blocking */
-       if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+       flags |= O_NONBLOCK;
+       if (fcntl(fd, F_SETFL, flags) < 0) {
                TAP_LOG(WARNING,
                        "Unable to set %s to nonblocking: %s",
                        ifr.ifr_name, strerror(errno));
                goto error;
        }
 
-       /* Set up trigger to optimize empty Rx bursts */
-       errno = 0;
-       do {
+       /* Find a free realtime signal */
+       for (signo = SIGRTMIN + 1; signo < SIGRTMAX; signo++) {
                struct sigaction sa;
-               int flags = fcntl(fd, F_GETFL);
 
-               if (flags == -1 || sigaction(SIGIO, NULL, &sa) == -1)
+               if (sigaction(signo, NULL, &sa) == -1) {
+                       TAP_LOG(WARNING,
+                               "Unable to get current rt-signal %d handler",
+                               signo);
+                       goto error;
+               }
+
+               /* Already have the handler we want on this signal  */
+               if (sa.sa_handler == tap_trigger_cb)
                        break;
-               if (sa.sa_handler != tap_trigger_cb) {
-                       /*
-                        * Make sure SIGIO is not already taken. This is done
-                        * as late as possible to leave the application a
-                        * chance to set up its own signal handler first.
-                        */
-                       if (sa.sa_handler != SIG_IGN &&
-                           sa.sa_handler != SIG_DFL) {
-                               errno = EBUSY;
-                               break;
-                       }
-                       sa = (struct sigaction){
-                               .sa_flags = SA_RESTART,
-                               .sa_handler = tap_trigger_cb,
-                       };
-                       if (sigaction(SIGIO, &sa, NULL) == -1)
-                               break;
+
+               /* Is handler in use by application */
+               if (sa.sa_handler != SIG_DFL) {
+                       TAP_LOG(DEBUG,
+                               "Skipping used rt-signal %d", signo);
+                       continue;
+               }
+
+               sa = (struct sigaction) {
+                       .sa_flags = SA_RESTART,
+                       .sa_handler = tap_trigger_cb,
+               };
+
+               if (sigaction(signo, &sa, NULL) == -1) {
+                       TAP_LOG(WARNING,
+                               "Unable to set rt-signal %d handler\n", signo);
+                       goto error;
                }
-               /* Enable SIGIO on file descriptor */
-               fcntl(fd, F_SETFL, flags | O_ASYNC);
-               fcntl(fd, F_SETOWN, getpid());
-       } while (0);
 
-       if (errno) {
+               /* Found a good signal to use */
+               TAP_LOG(DEBUG,
+                       "Using rt-signal %d", signo);
+               break;
+       }
+
+       if (signo == SIGRTMAX) {
+               TAP_LOG(WARNING, "All rt-signals are in use\n");
+
                /* Disable trigger globally in case of error */
                tap_trigger = 0;
-               TAP_LOG(WARNING, "Rx trigger disabled: %s",
-                       strerror(errno));
-       }
+               TAP_LOG(NOTICE, "No Rx trigger signal available\n");
+       } else {
+               /* Enable signal on file descriptor */
+               if (fcntl(fd, F_SETSIG, signo) < 0) {
+                       TAP_LOG(WARNING, "Unable to set signo %d for fd %d: %s",
+                               signo, fd, strerror(errno));
+                       goto error;
+               }
+               if (fcntl(fd, F_SETFL, flags | O_ASYNC) < 0) {
+                       TAP_LOG(WARNING, "Unable to set fcntl flags: %s",
+                               strerror(errno));
+                       goto error;
+               }
 
+               if (fcntl(fd, F_SETOWN, getpid()) < 0) {
+                       TAP_LOG(WARNING, "Unable to set fcntl owner: %s",
+                               strerror(errno));
+                       goto error;
+               }
+       }
        return fd;
 
 error:
@@ -1088,7 +1124,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 +1144,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 +1635,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 +1651,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
@@ -2477,11 +2529,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);