vfio: fix build with Linux < 4.0
[dpdk.git] / lib / librte_eal / linuxapp / eal / eal_interrupts.c
index f86f22f..767b508 100644 (file)
@@ -30,7 +30,6 @@
 #include <rte_branch_prediction.h>
 #include <rte_debug.h>
 #include <rte_log.h>
-#include <rte_malloc.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
 #include <rte_pause.h>
@@ -309,6 +308,66 @@ vfio_disable_msix(const struct rte_intr_handle *intr_handle) {
 
        return ret;
 }
+
+#ifdef HAVE_VFIO_DEV_REQ_INTERFACE
+/* enable req notifier */
+static int
+vfio_enable_req(const struct rte_intr_handle *intr_handle)
+{
+       int len, ret;
+       char irq_set_buf[IRQ_SET_BUF_LEN];
+       struct vfio_irq_set *irq_set;
+       int *fd_ptr;
+
+       len = sizeof(irq_set_buf);
+
+       irq_set = (struct vfio_irq_set *) irq_set_buf;
+       irq_set->argsz = len;
+       irq_set->count = 1;
+       irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+                        VFIO_IRQ_SET_ACTION_TRIGGER;
+       irq_set->index = VFIO_PCI_REQ_IRQ_INDEX;
+       irq_set->start = 0;
+       fd_ptr = (int *) &irq_set->data;
+       *fd_ptr = intr_handle->fd;
+
+       ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
+
+       if (ret) {
+               RTE_LOG(ERR, EAL, "Error enabling req interrupts for fd %d\n",
+                                               intr_handle->fd);
+               return -1;
+       }
+
+       return 0;
+}
+
+/* disable req notifier */
+static int
+vfio_disable_req(const struct rte_intr_handle *intr_handle)
+{
+       struct vfio_irq_set *irq_set;
+       char irq_set_buf[IRQ_SET_BUF_LEN];
+       int len, ret;
+
+       len = sizeof(struct vfio_irq_set);
+
+       irq_set = (struct vfio_irq_set *) irq_set_buf;
+       irq_set->argsz = len;
+       irq_set->count = 0;
+       irq_set->flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;
+       irq_set->index = VFIO_PCI_REQ_IRQ_INDEX;
+       irq_set->start = 0;
+
+       ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
+
+       if (ret)
+               RTE_LOG(ERR, EAL, "Error disabling req interrupts for fd %d\n",
+                       intr_handle->fd);
+
+       return ret;
+}
+#endif
 #endif
 
 static int
@@ -405,8 +464,7 @@ rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
        }
 
        /* allocate a new interrupt callback entity */
-       callback = rte_zmalloc("interrupt callback list",
-                               sizeof(*callback), 0);
+       callback = calloc(1, sizeof(*callback));
        if (callback == NULL) {
                RTE_LOG(ERR, EAL, "Can not allocate memory\n");
                return -ENOMEM;
@@ -420,7 +478,7 @@ rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
        TAILQ_FOREACH(src, &intr_sources, next) {
                if (src->intr_handle.fd == intr_handle->fd) {
                        /* we had no interrupts for this */
-                       if TAILQ_EMPTY(&src->callbacks)
+                       if (TAILQ_EMPTY(&src->callbacks))
                                wake_thread = 1;
 
                        TAILQ_INSERT_TAIL(&(src->callbacks), callback, next);
@@ -431,10 +489,10 @@ rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
 
        /* no existing callbacks for this - add new source */
        if (src == NULL) {
-               if ((src = rte_zmalloc("interrupt source list",
-                               sizeof(*src), 0)) == NULL) {
+               src = calloc(1, sizeof(*src));
+               if (src == NULL) {
                        RTE_LOG(ERR, EAL, "Can not allocate memory\n");
-                       rte_free(callback);
+                       free(callback);
                        ret = -ENOMEM;
                } else {
                        src->intr_handle = *intr_handle;
@@ -501,7 +559,7 @@ rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
                        if (cb->cb_fn == cb_fn && (cb_arg == (void *)-1 ||
                                        cb->cb_arg == cb_arg)) {
                                TAILQ_REMOVE(&src->callbacks, cb, next);
-                               rte_free(cb);
+                               free(cb);
                                ret++;
                        }
                }
@@ -509,7 +567,7 @@ rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
                /* all callbacks for that source are removed. */
                if (TAILQ_EMPTY(&src->callbacks)) {
                        TAILQ_REMOVE(&intr_sources, src, next);
-                       rte_free(src);
+                       free(src);
                }
        }
 
@@ -558,7 +616,16 @@ rte_intr_enable(const struct rte_intr_handle *intr_handle)
                if (vfio_enable_intx(intr_handle))
                        return -1;
                break;
+#ifdef HAVE_VFIO_DEV_REQ_INTERFACE
+       case RTE_INTR_HANDLE_VFIO_REQ:
+               if (vfio_enable_req(intr_handle))
+                       return -1;
+               break;
 #endif
+#endif
+       /* not used at this moment */
+       case RTE_INTR_HANDLE_DEV_EVENT:
+               return -1;
        /* unknown handle type */
        default:
                RTE_LOG(ERR, EAL,
@@ -605,7 +672,16 @@ rte_intr_disable(const struct rte_intr_handle *intr_handle)
                if (vfio_disable_intx(intr_handle))
                        return -1;
                break;
+#ifdef HAVE_VFIO_DEV_REQ_INTERFACE
+       case RTE_INTR_HANDLE_VFIO_REQ:
+               if (vfio_disable_req(intr_handle))
+                       return -1;
+               break;
 #endif
+#endif
+       /* not used at this moment */
+       case RTE_INTR_HANDLE_DEV_EVENT:
+               return -1;
        /* unknown handle type */
        default:
                RTE_LOG(ERR, EAL,
@@ -668,13 +744,22 @@ eal_intr_process_interrupts(struct epoll_event *events, int nfds)
                case RTE_INTR_HANDLE_VFIO_LEGACY:
                        bytes_read = sizeof(buf.vfio_intr_count);
                        break;
+#ifdef HAVE_VFIO_DEV_REQ_INTERFACE
+               case RTE_INTR_HANDLE_VFIO_REQ:
+                       bytes_read = 0;
+                       call = true;
+                       break;
+#endif
 #endif
                case RTE_INTR_HANDLE_VDEV:
                case RTE_INTR_HANDLE_EXT:
                        bytes_read = 0;
                        call = true;
                        break;
-
+               case RTE_INTR_HANDLE_DEV_EVENT:
+                       bytes_read = 0;
+                       call = true;
+                       break;
                default:
                        bytes_read = 1;
                        break;
@@ -844,8 +929,7 @@ eal_intr_thread_main(__rte_unused void *arg)
 int
 rte_eal_intr_init(void)
 {
-       int ret = 0, ret_1 = 0;
-       char thread_name[RTE_MAX_THREAD_NAME_LEN];
+       int ret = 0;
 
        /* init the global interrupt source head */
        TAILQ_INIT(&intr_sources);
@@ -860,23 +944,15 @@ rte_eal_intr_init(void)
        }
 
        /* create the host thread to wait/handle the interrupt */
-       ret = pthread_create(&intr_thread, NULL,
+       ret = rte_ctrl_thread_create(&intr_thread, "eal-intr-thread", NULL,
                        eal_intr_thread_main, NULL);
        if (ret != 0) {
-               rte_errno = ret;
+               rte_errno = -ret;
                RTE_LOG(ERR, EAL,
                        "Failed to create thread for interrupt handling\n");
-       } else {
-               /* Set thread_name for aid in debugging. */
-               snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
-                       "eal-intr-thread");
-               ret_1 = rte_thread_setname(intr_thread, thread_name);
-               if (ret_1 != 0)
-                       RTE_LOG(DEBUG, EAL,
-                       "Failed to set thread name for interrupt handling\n");
        }
 
-       return -ret;
+       return ret;
 }
 
 static void