From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 19E96C316 for ; Fri, 17 Jul 2015 08:16:42 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 16 Jul 2015 23:16:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,493,1432623600"; d="scan'208";a="730568477" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga001.jf.intel.com with ESMTP; 16 Jul 2015 23:16:40 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id t6H6Gcfg015008; Fri, 17 Jul 2015 14:16:38 +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 t6H6GYg2032293; Fri, 17 Jul 2015 14:16:36 +0800 Received: (from cliang18@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t6H6GYSF032289; Fri, 17 Jul 2015 14:16:34 +0800 From: Cunming Liang To: dev@dpdk.org, thomas.monjalon@6wind.com, david.marchand@6wind.com Date: Fri, 17 Jul 2015 14:16:08 +0800 Message-Id: <1437113775-32199-7-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 06/13] eal/linux: standalone intr event fd create support 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:43 -0000 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 --- v14 changes - per-patch basis ABI compatibility rework - minor changes on API decription comments v13 changes - version map cleanup for v2.1 v11 changes - typo cleanup lib/librte_eal/linuxapp/eal/eal_interrupts.c | 57 ++++++++++++++ .../linuxapp/eal/include/exec-env/rte_interrupts.h | 87 ++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 4 + 3 files changed, 148 insertions(+) diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c index b18ab86..0266d98 100644 --- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c +++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -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 */ @@ -1121,4 +1123,59 @@ 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, + "cannot 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; +} #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 918246f..3f17f29 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 @@ -191,4 +191,91 @@ rte_intr_rx_ctl(struct rte_intr_handle *intr_handle, } #endif +/** + * 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. + */ +#ifdef RTE_NEXT_ABI +extern int +rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd); +#else +static inline 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; +} +#endif + +/** + * 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. + */ +#ifdef RTE_NEXT_ABI +extern void +rte_intr_efd_disable(struct rte_intr_handle *intr_handle); +#else +static inline void +rte_intr_efd_disable(struct rte_intr_handle *intr_handle) +{ + RTE_SET_USED(intr_handle); +} +#endif + +/** + * The packet I/O interrupt on datapath is enabled or not. + * + * @param intr_handle + * Pointer to the interrupt handle. + */ +#ifdef RTE_NEXT_ABI +static inline int +rte_intr_dp_is_en(struct rte_intr_handle *intr_handle) +{ + return !(!intr_handle->nb_efd); +} +#else +static inline int +rte_intr_dp_is_en(struct rte_intr_handle *intr_handle) +{ + RTE_SET_USED(intr_handle); + return 0; +} +#endif + +/** + * 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. + */ +#ifdef RTE_NEXT_ABI +static inline int +rte_intr_allow_others(struct rte_intr_handle *intr_handle) +{ + return !!(intr_handle->max_intr - intr_handle->nb_efd); +} +#else +static inline int +rte_intr_allow_others(struct rte_intr_handle *intr_handle) +{ + RTE_SET_USED(intr_handle); + return 1; +} +#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 1cd4cc5..a0d9cb2 100644 --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map @@ -117,6 +117,10 @@ DPDK_2.1 { rte_epoll_ctl; rte_epoll_wait; + rte_intr_allow_others; + rte_intr_dp_is_en; + rte_intr_efd_enable; + rte_intr_efd_disable; rte_intr_rx_ctl; rte_intr_tls_epfd; rte_memzone_free; -- 1.8.1.4