[dpdk-dev,v13,06/14] eal/linux: standalone intr event fd create support

Message ID 1434686442-578-7-git-send-email-cunming.liang@intel.com (mailing list archive)
State Changes Requested, archived
Headers

Commit Message

Cunming Liang June 19, 2015, 4 a.m. UTC
  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>
---
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 | 51 +++++++++++++++++++
 lib/librte_eal/linuxapp/eal/rte_eal_version.map    |  4 ++
 3 files changed, 112 insertions(+)
  

Comments

Thomas Monjalon July 13, 2015, 5:01 p.m. UTC | #1
2015-06-19 12:00, Cunming Liang:
> +/**
> + * It enables the fastpath event fds if it's necessary.

What means fastpath here?

> + * It creates event fds when multi-vectors allowed,
> + * otherwise it multiplexes the single event fds.

Maybe a reference to allow multi-vectors is needed.

> + *
> + * @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);
>
  
Cunming Liang July 17, 2015, 5:49 a.m. UTC | #2
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Tuesday, July 14, 2015 1:02 AM
> To: Liang, Cunming
> Cc: dev@dpdk.org; shemming@brocade.com; david.marchand@6wind.com;
> Zhou, Danny; Wang, Liang-min; Richardson, Bruce; Liu, Yong;
> nhorman@tuxdriver.com
> Subject: Re: [PATCH v13 06/14] eal/linux: standalone intr event fd create support
> 
> 2015-06-19 12:00, Cunming Liang:
> > +/**
> > + * It enables the fastpath event fds if it's necessary.
> 
> What means fastpath here?
Here means RX/TX packet I/O interrupt, to distinguish link status interrupt which is processed in a standalone thread.
Will reword the description.
> 
> > + * It creates event fds when multi-vectors allowed,
> > + * otherwise it multiplexes the single event fds.
> 
> Maybe a reference to allow multi-vectors is needed.
Will rework it, thanks.
> 
> > + *
> > + * @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);
> >
>
  

Patch

diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index d35c874..5519e7c 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -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 */
 
@@ -1110,3 +1112,58 @@  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;
+}
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 3e93a27..912cc50 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
@@ -166,4 +166,55 @@  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.
+ */
+static inline int
+rte_intr_dp_is_en(struct rte_intr_handle *intr_handle)
+{
+	return !(!intr_handle->nb_efd);
+}
+
+/**
+ * The interrupt handle instance allows other cause or not.
+ * Other cause stands for none fastpath interrupt.
+ *
+ * @param intr_handle
+ *   Pointer to the interrupt handle.
+ */
+static inline int
+rte_intr_allow_others(struct rte_intr_handle *intr_handle)
+{
+	return !!(intr_handle->max_intr - intr_handle->nb_efd);
+}
+
 #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 5fb33fa..96d68bd 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -104,6 +104,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;