From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 97B317F6D for ; Fri, 17 Jul 2015 08:16:34 +0200 (CEST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 16 Jul 2015 23:16:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,493,1432623600"; d="scan'208";a="764332552" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga002.fm.intel.com with ESMTP; 16 Jul 2015 23:16:32 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id t6H6GUDl014997; Fri, 17 Jul 2015 14:16:30 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id t6H6GRp6032271; Fri, 17 Jul 2015 14:16:29 +0800 Received: (from cliang18@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t6H6GQgT032267; Fri, 17 Jul 2015 14:16:26 +0800 From: Cunming Liang To: dev@dpdk.org, thomas.monjalon@6wind.com, david.marchand@6wind.com Date: Fri, 17 Jul 2015 14:16:05 +0800 Message-Id: <1437113775-32199-4-git-send-email-cunming.liang@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1437113775-32199-1-git-send-email-cunming.liang@intel.com> References: <1434686442-578-1-git-send-email-cunming.liang@intel.com> <1437113775-32199-1-git-send-email-cunming.liang@intel.com> Cc: shemming@brocade.com Subject: [dpdk-dev] [PATCH v14 03/13] eal/linux: add API to set rx interrupt event monitor X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Jul 2015 06:16:35 -0000 The patch adds 'rte_intr_rx_ctl' to add or delete interrupt vector events monitor on specified epoll instance. Signed-off-by: Cunming Liang --- v14 changes - per-patch basis ABI compatibility rework - remove unnecessary 'local: *' from version map v13 changes - version map cleanup for v2.1 v12 changes: - fix awkward line split in using RTE_LOG v10 changes: - add RTE_INTR_HANDLE_UIO_INTX for uio_pci_generic v8 changes - fix EWOULDBLOCK and EINTR processing - add event status check 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 | 105 +++++++++++++++++++++ .../linuxapp/eal/include/exec-env/rte_interrupts.h | 38 ++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 3 files changed, 144 insertions(+) diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c index 5fe5b99..4e34abc 100644 --- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c +++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c @@ -897,6 +897,51 @@ rte_eal_intr_init(void) return -ret; } +#ifdef RTE_NEXT_ABI +static void +eal_intr_proc_rxtx_intr(int fd, const struct rte_intr_handle *intr_handle) +{ + union rte_intr_read_buffer buf; + int bytes_read = 1; + + switch (intr_handle->type) { + case RTE_INTR_HANDLE_UIO: + case RTE_INTR_HANDLE_UIO_INTX: + bytes_read = sizeof(buf.uio_intr_count); + break; +#ifdef VFIO_PRESENT + case RTE_INTR_HANDLE_VFIO_MSIX: + case RTE_INTR_HANDLE_VFIO_MSI: + case RTE_INTR_HANDLE_VFIO_LEGACY: + bytes_read = sizeof(buf.vfio_intr_count); + break; +#endif + default: + bytes_read = 1; + RTE_LOG(INFO, EAL, "unexpected intr type\n"); + break; + } + + /** + * read out to clear the ready-to-be-read flag + * for epoll_wait. + */ + do { + bytes_read = read(fd, &buf, bytes_read); + if (bytes_read < 0) { + if (errno == EINTR || errno == EWOULDBLOCK || + errno == EAGAIN) + continue; + RTE_LOG(ERR, EAL, + "Error reading from fd %d: %s\n", + fd, strerror(errno)); + } else if (bytes_read == 0) + RTE_LOG(ERR, EAL, "Read nothing from fd %d\n", fd); + return; + } while (1); +} +#endif + static int eal_epoll_process_event(struct epoll_event *evs, unsigned int n, struct rte_epoll_event *events) @@ -1033,3 +1078,63 @@ rte_epoll_ctl(int epfd, int op, int fd, return 0; } + +#ifdef RTE_NEXT_ABI +int +rte_intr_rx_ctl(struct rte_intr_handle *intr_handle, int epfd, + int op, unsigned int vec, void *data) +{ + struct rte_epoll_event *rev; + struct rte_epoll_data *epdata; + int epfd_op; + int rc = 0; + + if (!intr_handle || intr_handle->nb_efd == 0 || + vec >= intr_handle->nb_efd) { + RTE_LOG(ERR, EAL, "Wrong intr vector number.\n"); + return -EPERM; + } + + switch (op) { + case RTE_INTR_EVENT_ADD: + epfd_op = EPOLL_CTL_ADD; + rev = &intr_handle->elist[vec]; + if (rev->status != RTE_EPOLL_INVALID) { + RTE_LOG(INFO, EAL, "Event already been added.\n"); + return -EEXIST; + } + + /* attach to intr vector fd */ + epdata = &rev->epdata; + epdata->event = EPOLLIN | EPOLLPRI | EPOLLET; + epdata->data = data; + epdata->cb_fun = (rte_intr_event_cb_t)eal_intr_proc_rxtx_intr; + epdata->cb_arg = (void *)intr_handle; + rc = rte_epoll_ctl(epfd, epfd_op, intr_handle->efds[vec], rev); + if (!rc) + RTE_LOG(DEBUG, EAL, + "efd %d associated with vec %d added on epfd %d" + "\n", rev->fd, vec, epfd); + else + rc = -EPERM; + break; + case RTE_INTR_EVENT_DEL: + epfd_op = EPOLL_CTL_DEL; + rev = &intr_handle->elist[vec]; + if (rev->status == RTE_EPOLL_INVALID) { + RTE_LOG(INFO, EAL, "Event does not exist.\n"); + return -EPERM; + } + + rc = rte_epoll_ctl(rev->epfd, epfd_op, rev->fd, rev); + if (rc) + rc = -EPERM; + break; + default: + RTE_LOG(ERR, EAL, "event op type mismatch\n"); + rc = -EPERM; + } + + return rc; +} +#endif 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 b55b4ee..918246f 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 @@ -38,6 +38,10 @@ #ifndef _RTE_LINUXAPP_INTERRUPTS_H_ #define _RTE_LINUXAPP_INTERRUPTS_H_ +#ifndef RTE_NEXT_ABI +#include +#endif + #define RTE_MAX_RXTX_INTR_VEC_ID 32 enum rte_intr_handle_type { @@ -153,4 +157,38 @@ 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. + * @return + * - On success, zero. + * - On failure, a negative value. + */ +#ifdef RTE_NEXT_ABI +extern int +rte_intr_rx_ctl(struct rte_intr_handle *intr_handle, + int epfd, int op, unsigned int vec, void *data); +#else +static inline int +rte_intr_rx_ctl(struct rte_intr_handle *intr_handle, + int epfd, int op, unsigned int vec, void *data) +{ + RTE_SET_USED(intr_handle); + RTE_SET_USED(epfd); + RTE_SET_USED(op); + RTE_SET_USED(vec); + RTE_SET_USED(data); + return -ENOTSUP; +} +#endif + #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 3c4c710..1cd4cc5 100644 --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map @@ -117,6 +117,7 @@ DPDK_2.1 { rte_epoll_ctl; rte_epoll_wait; + rte_intr_rx_ctl; rte_intr_tls_epfd; rte_memzone_free; } DPDK_2.0; -- 1.8.1.4