The patch adds 'rte_intr_rx_ctl' to add or delete interrupt vector events monitor on specified epoll instance.
Signed-off-by: Cunming Liang <cunming.liang at intel.com> --- v7 changes - rename rte_intr_rx_set to rte_intr_rx_ctl. - rte_intr_rx_ctl uses rte_epoll_ctl to register epoll event instance. - the intr rx event instance includes a intr process callback. v6 changes - split rte_intr_wait_rx_pkt into two function, wait and set. - rewrite rte_intr_rx_wait/rte_intr_rx_set to remove queue visibility on eal. - rte_intr_rx_wait to support multiplexing. - allow epfd as input to support flexible event fd combination. lib/librte_eal/linuxapp/eal/eal_interrupts.c | 95 ++++++++++++++++++++++ .../linuxapp/eal/include/exec-env/rte_interrupts.h | 23 ++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 3 files changed, 119 insertions(+) diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c index b641745..1090d7b 100644 --- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c +++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c @@ -862,6 +862,35 @@ rte_eal_intr_init(void) } static void +eal_intr_proc_rxtx_intr(int fd, struct rte_intr_handle *intr_handle) +{ + union rte_intr_read_buffer buf; + int bytes_read = 1; + + if (intr_handle->type != RTE_INTR_HANDLE_VFIO_MSIX) { + RTE_LOG(ERR, EAL, "intr type should be VFIO_MSIX\n"); + return; + } + +#ifdef VFIO_PRESENT + bytes_read = sizeof(buf.vfio_intr_count); +#endif + + /** + * read out to clear the ready-to-be-read flag + * for epoll_wait. + */ + bytes_read = read(fd, &buf, bytes_read); + if (bytes_read < 0) + RTE_LOG(ERR, EAL, "Error reading from file " + "descriptor %d: %s\n", fd, + strerror(errno)); + else if (bytes_read == 0) + RTE_LOG(ERR, EAL, "Read nothing from file " + "descriptor %d\n", fd); +} + +static void eal_epoll_process_event(struct epoll_event *evs, int n, struct rte_epoll_event *events) { @@ -956,3 +985,69 @@ rte_epoll_ctl(int epfd, int op, int fd, return 0; } + +int +rte_intr_rx_ctl(struct rte_intr_handle *intr_handle, int epfd, + int op, unsigned int vec, void *data, int socket) +{ + struct rte_epoll_event *rev; + int epfd_op; + int rc = 0; + + if (!intr_handle || vec >= RTE_MAX_RXTX_INTR_VEC_ID || + !intr_handle->vec_en) { + RTE_LOG(ERR, EAL, "Wrong intr vector number.\n"); + return -1; + } + + if (socket == SOCKET_ID_ANY) + socket = rte_socket_id(); + + switch (op) { + case RTE_INTR_EVENT_ADD: + epfd_op = EPOLL_CTL_ADD; + if (intr_handle->eptrs[vec] != NULL) { + RTE_LOG(ERR, EAL, "Event already been added.\n"); + return -1; + } + + /* new event */ + rev = rte_zmalloc_socket("eptrs", sizeof(*rev), + RTE_CACHE_LINE_SIZE, socket); + if (rev == NULL) { + RTE_LOG(ERR, EAL, "event obj alloc fail\n"); + return -1; + } + + /* attach to intr vector fd */ + rev->fd = intr_handle->efds[vec]; + rev->event = EPOLLIN | EPOLLPRI | EPOLLET; + rev->data = data; + rev->cb_fun = (rte_intr_event_cb_t)eal_intr_proc_rxtx_intr; + rev->cb_arg = (void *)intr_handle; + + rc = rte_epoll_ctl(epfd, epfd_op, rev->fd, rev); + if (!rc) + intr_handle->eptrs[vec] = rev; + else + rte_free(rev); + + break; + case RTE_INTR_EVENT_DEL: + epfd_op = EPOLL_CTL_DEL; + if (intr_handle->eptrs[vec] != NULL) { + rev = intr_handle->eptrs[vec]; + rc = rte_epoll_ctl(epfd, epfd_op, rev->fd, rev); + if (!rc) { + rte_free(rev); + intr_handle->eptrs[vec] = NULL; + } + } + break; + default: + RTE_LOG(ERR, EAL, "event op type mismatch\n"); + rc = -1; + } + + return rc; +} diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_interrupts.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_interrupts.h index af405cf..3d9f6d7 100644 --- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_interrupts.h +++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_interrupts.h @@ -133,4 +133,27 @@ rte_epoll_ctl(int epfd, int op, int fd, int rte_intr_tls_epfd(void); +/** + * @param intr_handle + * Pointer to the interrupt handle. + * @param epfd + * Epoll instance fd which the intr vector associated to. + * @param op + * The operation be performed for the vector. + * Operation type of {ADD, DEL}. + * @param vec + * RX intr vector number added to the epoll instance wait list. + * @param data + * User raw data. + * @param socket + * Specifying the socket id. + * @return + * - On success, zero. + * - On failure, a negative value. + */ +int +rte_intr_rx_ctl(struct rte_intr_handle *intr_handle, + int epfd, int op, unsigned int vec, + void *data, int socket); + #endif /* _RTE_LINUXAPP_INTERRUPTS_H_ */ diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map index 840002e..65b5ed2 100644 --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map @@ -63,6 +63,7 @@ DPDK_2.0 { rte_intr_callback_unregister; rte_intr_disable; rte_intr_enable; + rte_intr_rx_ctl; rte_intr_tls_epfd; rte_log; rte_log_add_in_history; -- 1.8.1.4