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 81175C6B8 for ; Tue, 5 May 2015 07:40:20 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP; 04 May 2015 22:40:19 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,370,1427785200"; d="scan'208";a="690003193" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga001.jf.intel.com with ESMTP; 04 May 2015 22:40:18 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id t455eGK7019236; Tue, 5 May 2015 13:40:16 +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 t455eDB8029018; Tue, 5 May 2015 13:40:15 +0800 Received: (from cliang18@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t455eDvC029014; Tue, 5 May 2015 13:40:13 +0800 From: Cunming Liang To: dev@dpdk.org Date: Tue, 5 May 2015 13:39:39 +0800 Message-Id: <1430804386-28949-4-git-send-email-cunming.liang@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1430804386-28949-1-git-send-email-cunming.liang@intel.com> References: <1425012976-10173-1-git-send-email-cunming.liang@intel.com> <1430804386-28949-1-git-send-email-cunming.liang@intel.com> Cc: shemming@brocade.com Subject: [dpdk-dev] [PATCH v7 03/10] 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: Tue, 05 May 2015 05:40:21 -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 --- 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