]> git.droids-corp.org - dpdk.git/commitdiff
eal/linux: add interrupt API for drivers
authorCunming Liang <cunming.liang@intel.com>
Mon, 20 Jul 2015 03:02:22 +0000 (11:02 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Mon, 27 Jul 2015 21:13:57 +0000 (23:13 +0200)
The patch exposes intr event fd create and release for PMD.
The device driver can assign the number of event associated with interrupt vector.
It also provides misc functions to check 1) allows other slowpath intr(e.g. lsc);
2) intr event on fastpath is enabled or not.

Signed-off-by: Cunming Liang <cunming.liang@intel.com>
lib/librte_eal/bsdapp/eal/eal_interrupts.c
lib/librte_eal/bsdapp/eal/include/exec-env/rte_interrupts.h
lib/librte_eal/bsdapp/eal/rte_eal_version.map
lib/librte_eal/linuxapp/eal/eal_interrupts.c
lib/librte_eal/linuxapp/eal/include/exec-env/rte_interrupts.h
lib/librte_eal/linuxapp/eal/rte_eal_version.map

index d5ae6829e037c818b4d6c9081affff6b65d53f4c..51a13fa264ff9fb12edcd95550584164bd852a1a 100644 (file)
@@ -81,3 +81,32 @@ rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,
 
        return -ENOTSUP;
 }
+
+int
+rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
+{
+       RTE_SET_USED(intr_handle);
+       RTE_SET_USED(nb_efd);
+
+       return 0;
+}
+
+void
+rte_intr_efd_disable(struct rte_intr_handle *intr_handle)
+{
+       RTE_SET_USED(intr_handle);
+}
+
+int
+rte_intr_dp_is_en(struct rte_intr_handle *intr_handle)
+{
+       RTE_SET_USED(intr_handle);
+       return 0;
+}
+
+int
+rte_intr_allow_others(struct rte_intr_handle *intr_handle)
+{
+       RTE_SET_USED(intr_handle);
+       return 1;
+}
index 67cb0c9a2d215135046dbb043c617ddfd9305232..bffa90247405962445dd3710878282bae30b106e 100644 (file)
@@ -77,4 +77,47 @@ int
 rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,
                int epfd, int op, unsigned int vec, void *data);
 
+/**
+ * It enables the fastpath event fds if it's necessary.
+ * It creates event fds when multi-vectors allowed,
+ * otherwise it multiplexes the single event fds.
+ *
+ * @param intr_handle
+ *   Pointer to the interrupt handle.
+ * @param nb_vec
+ *   Number of interrupt vector trying to enable.
+ * @return
+ *   - On success, zero.
+ *   - On failure, a negative value.
+ */
+int
+rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd);
+
+/**
+ * It disable the fastpath event fds.
+ * It deletes registered eventfds and closes the open fds.
+ *
+ * @param intr_handle
+ *   Pointer to the interrupt handle.
+ */
+void
+rte_intr_efd_disable(struct rte_intr_handle *intr_handle);
+
+/**
+ * The fastpath interrupt is enabled or not.
+ *
+ * @param intr_handle
+ *   Pointer to the interrupt handle.
+ */
+int rte_intr_dp_is_en(struct rte_intr_handle *intr_handle);
+
+/**
+ * The interrupt handle instance allows other cause or not.
+ * Other cause stands for none fastpath interrupt.
+ *
+ * @param intr_handle
+ *   Pointer to the interrupt handle.
+ */
+int rte_intr_allow_others(struct rte_intr_handle *intr_handle);
+
 #endif /* _RTE_BSDAPP_INTERRUPTS_H_ */
index 412ba1e42a7725bd05f03640a4b367c09b0627c9..2758848e2fcf5ea4f56c5096d8fcfeb9c64c8d5c 100644 (file)
@@ -118,6 +118,10 @@ DPDK_2.1 {
        rte_eal_pci_detach;
        rte_eal_pci_read_config;
        rte_eal_pci_write_config;
+       rte_intr_allow_others;
+       rte_intr_dp_is_en;
+       rte_intr_efd_disable;
+       rte_intr_efd_enable;
        rte_intr_rx_ctl;
        rte_memzone_free;
 
index e919fb07058ab224de846054b4a787a4f2e1ee16..3f87875aa8abcc4bf1cc451c067c014311b68400 100644 (file)
@@ -44,6 +44,7 @@
 #include <sys/epoll.h>
 #include <sys/signalfd.h>
 #include <sys/ioctl.h>
+#include <sys/eventfd.h>
 
 #include <rte_common.h>
 #include <rte_interrupts.h>
@@ -68,6 +69,7 @@
 #include "eal_vfio.h"
 
 #define EAL_INTR_EPOLL_WAIT_FOREVER (-1)
+#define NB_OTHER_INTR               1
 
 static RTE_DEFINE_PER_LCORE(int, _epfd) = -1; /**< epoll fd per thread */
 
@@ -1124,6 +1126,73 @@ rte_intr_rx_ctl(struct rte_intr_handle *intr_handle, int epfd,
 
        return rc;
 }
+
+int
+rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
+{
+       uint32_t i;
+       int fd;
+       uint32_t n = RTE_MIN(nb_efd, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID);
+
+       if (intr_handle->type == RTE_INTR_HANDLE_VFIO_MSIX) {
+               for (i = 0; i < n; i++) {
+                       fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+                       if (fd < 0) {
+                               RTE_LOG(ERR, EAL,
+                                       "can't setup eventfd, error %i (%s)\n",
+                                       errno, strerror(errno));
+                               return -1;
+                       }
+                       intr_handle->efds[i] = fd;
+               }
+               intr_handle->nb_efd   = n;
+               intr_handle->max_intr = NB_OTHER_INTR + n;
+       } else {
+               intr_handle->efds[0]  = intr_handle->fd;
+               intr_handle->nb_efd   = RTE_MIN(nb_efd, 1U);
+               intr_handle->max_intr = NB_OTHER_INTR;
+       }
+
+       return 0;
+}
+
+void
+rte_intr_efd_disable(struct rte_intr_handle *intr_handle)
+{
+       uint32_t i;
+       struct rte_epoll_event *rev;
+
+       for (i = 0; i < intr_handle->nb_efd; i++) {
+               rev = &intr_handle->elist[i];
+               if (rev->status == RTE_EPOLL_INVALID)
+                       continue;
+               if (rte_epoll_ctl(rev->epfd, EPOLL_CTL_DEL, rev->fd, rev)) {
+                       /* force free if the entry valid */
+                       eal_epoll_data_safe_free(rev);
+                       rev->status = RTE_EPOLL_INVALID;
+               }
+       }
+
+       if (intr_handle->max_intr > intr_handle->nb_efd) {
+               for (i = 0; i < intr_handle->nb_efd; i++)
+                       close(intr_handle->efds[i]);
+       }
+       intr_handle->nb_efd = 0;
+       intr_handle->max_intr = 0;
+}
+
+int
+rte_intr_dp_is_en(struct rte_intr_handle *intr_handle)
+{
+       return !(!intr_handle->nb_efd);
+}
+
+int
+rte_intr_allow_others(struct rte_intr_handle *intr_handle)
+{
+       return !!(intr_handle->max_intr - intr_handle->nb_efd);
+}
+
 #else
 int
 rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,
@@ -1136,4 +1205,32 @@ rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,
        RTE_SET_USED(data);
        return -ENOTSUP;
 }
+
+int
+rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
+{
+       RTE_SET_USED(intr_handle);
+       RTE_SET_USED(nb_efd);
+       return 0;
+}
+
+void
+rte_intr_efd_disable(struct rte_intr_handle *intr_handle)
+{
+       RTE_SET_USED(intr_handle);
+}
+
+int
+rte_intr_dp_is_en(struct rte_intr_handle *intr_handle)
+{
+       RTE_SET_USED(intr_handle);
+       return 0;
+}
+
+int
+rte_intr_allow_others(struct rte_intr_handle *intr_handle)
+{
+       RTE_SET_USED(intr_handle);
+       return 1;
+}
 #endif
index acf4be9d8b5c052903c1f0f3550e93888cb54726..b05f4c87e737a910694945bd48eac6bfbf6d108e 100644 (file)
@@ -168,4 +168,49 @@ int
 rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,
                int epfd, int op, unsigned int vec, void *data);
 
+/**
+ * It enables the packet I/O interrupt event if it's necessary.
+ * It creates event fd for each interrupt vector when MSIX is used,
+ * otherwise it multiplexes a single event fd.
+ *
+ * @param intr_handle
+ *   Pointer to the interrupt handle.
+ * @param nb_vec
+ *   Number of interrupt vector trying to enable.
+ * @return
+ *   - On success, zero.
+ *   - On failure, a negative value.
+ */
+int
+rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd);
+
+/**
+ * It disables the packet I/O interrupt event.
+ * It deletes registered eventfds and closes the open fds.
+ *
+ * @param intr_handle
+ *   Pointer to the interrupt handle.
+ */
+void
+rte_intr_efd_disable(struct rte_intr_handle *intr_handle);
+
+/**
+ * The packet I/O interrupt on datapath is enabled or not.
+ *
+ * @param intr_handle
+ *   Pointer to the interrupt handle.
+ */
+int
+rte_intr_dp_is_en(struct rte_intr_handle *intr_handle);
+
+/**
+ * The interrupt handle instance allows other causes or not.
+ * Other causes stand for any none packet I/O interrupts.
+ *
+ * @param intr_handle
+ *   Pointer to the interrupt handle.
+ */
+int
+rte_intr_allow_others(struct rte_intr_handle *intr_handle);
+
 #endif /* _RTE_LINUXAPP_INTERRUPTS_H_ */
index 7e20d7a06d1052b7202825f999bc8e89f98307aa..59b1717940a16d79f5c9e7403b20db6d85382f1c 100644 (file)
@@ -120,6 +120,10 @@ DPDK_2.1 {
        rte_eal_pci_write_config;
        rte_epoll_ctl;
        rte_epoll_wait;
+       rte_intr_allow_others;
+       rte_intr_dp_is_en;
+       rte_intr_efd_disable;
+       rte_intr_efd_enable;
        rte_intr_rx_ctl;
        rte_intr_tls_epfd;
        rte_memzone_free;