[PATCH v4-S3 46/65] bus/fslmc: use EAL API for DPIO interrupt

Prashant Gupta prashant.gupta_3 at nxp.com
Fri Oct 23 15:43:26 CEST 2026


From: Jun Yang <jun.yang at nxp.com>

The DPIO interrupt path created a private epoll instance with the raw
epoll_create/epoll_ctl/epoll_wait syscalls and cached its fd in
dpaa2_dpio_dev::epoll_fd. This duplicated the epoll bookkeeping already
provided by the EAL interrupt handle and split the interrupt state
across two owners.

Switch to the EAL rte_epoll wrappers. dpaa2_dpio_intr_init() now arms
the interrupt handle's epoll event via rte_epoll_ctl(),
dpaa2_dpio_intr_deinit() removes it, and the event PMD dequeue wait
uses rte_epoll_wait() on the handle's epoll fd. The now redundant
epoll_fd field is removed from struct dpaa2_dpio_dev.

While converting, tidy the init/deinit error handling to use goto
labels so the interrupt is disabled and the epoll fd closed on every
failure path.

Signed-off-by: Jun Yang <jun.yang at nxp.com>
---
 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 58 ++++++++++++++++--------
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h  |  1 -
 drivers/event/dpaa2/dpaa2_eventdev.c     |  7 ++-
 3 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index 4affd4e0b4..e95345627d 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
@@ -184,7 +184,7 @@ int dpaa2_dpio_intr_init(struct dpaa2_dpio_dev *dpio_dev, int threshold,
 	int timeout, bool build_epoll)
 {
 	int eventfd, dpio_epoll_fd, ret;
-	struct epoll_event epoll_ev;
+	struct rte_epoll_event *epoll_ev;
 
 	if (dpio_dev->intr_enabled)
 		return 0;
@@ -201,8 +201,6 @@ int dpaa2_dpio_intr_init(struct dpaa2_dpio_dev *dpio_dev, int threshold,
 	qbman_swp_dqrr_thrshld_write(dpio_dev->sw_portal, threshold);
 	qbman_swp_intr_timeout_write(dpio_dev->sw_portal, timeout);
 
-	dpio_dev->epoll_fd = -1;
-
 	/* The event PMD dequeues by sleeping on a private epoll instance owned
 	 * by the portal, so build it here. The net rx-queue-interrupt path
 	 * exposes the raw eventfd through the generic ethdev API and waits on
@@ -212,45 +210,65 @@ int dpaa2_dpio_intr_init(struct dpaa2_dpio_dev *dpio_dev, int threshold,
 		dpio_epoll_fd = epoll_create1(EPOLL_CLOEXEC);
 		if (dpio_epoll_fd < 0) {
 			DPAA2_BUS_ERR("epoll_create failed");
-			rte_dpaa2_intr_disable(dpio_dev->intr_handle, 0);
-			return -errno;
+			ret = -errno;
+			goto int_disable_err;
 		}
 
 		eventfd = rte_intr_fd_get(dpio_dev->intr_handle);
-		epoll_ev.events = EPOLLIN | EPOLLPRI | EPOLLET;
-		epoll_ev.data.fd = eventfd;
-
-		ret = epoll_ctl(dpio_epoll_fd, EPOLL_CTL_ADD, eventfd, &epoll_ev);
+		if (eventfd < 0) {
+			ret = eventfd;
+			goto epoll_close_err;
+		}
+		epoll_ev = rte_intr_elist_index_get(dpio_dev->intr_handle, 0);
+		if (rte_atomic_load_explicit(&epoll_ev->status,
+			rte_memory_order_relaxed) != RTE_EPOLL_INVALID) {
+			DPAA2_BUS_ERR("Event already been added.");
+			ret = -EEXIST;
+			goto epoll_close_err;
+		}
+		epoll_ev->epdata.event = EPOLLIN | EPOLLPRI | EPOLLET;
+		ret = rte_epoll_ctl(dpio_epoll_fd, EPOLL_CTL_ADD, eventfd, epoll_ev);
 		if (ret < 0) {
-			DPAA2_BUS_ERR("epoll_ctl failed");
-			rte_dpaa2_intr_disable(dpio_dev->intr_handle, 0);
-			close(dpio_epoll_fd);
-			return -1;
+			DPAA2_BUS_ERR("Epoll control add failed(%d)", ret);
+			goto epoll_close_err;
 		}
-		dpio_dev->epoll_fd = dpio_epoll_fd;
 	}
 
 	dpio_dev->intr_enabled = 1;
 
 	return 0;
+
+epoll_close_err:
+	close(dpio_epoll_fd);
+int_disable_err:
+	rte_dpaa2_intr_disable(dpio_dev->intr_handle, 0);
+	return ret;
 }
 
 RTE_EXPORT_INTERNAL_SYMBOL(dpaa2_dpio_intr_deinit)
 void dpaa2_dpio_intr_deinit(struct dpaa2_dpio_dev *dpio_dev)
 {
-	int ret;
+	int ret, epfd;
+	struct rte_epoll_event *epoll_ev;
 
 	if (!dpio_dev->intr_enabled)
 		return;
 
+	epoll_ev = rte_intr_elist_index_get(dpio_dev->intr_handle, 0);
+	if (rte_atomic_load_explicit(&epoll_ev->status,
+		rte_memory_order_relaxed) != RTE_EPOLL_INVALID) {
+		epoll_ev->epdata.event = EPOLLIN | EPOLLPRI | EPOLLET;
+		epfd = epoll_ev->epfd;
+		ret = rte_epoll_ctl(epfd, EPOLL_CTL_DEL, epoll_ev->fd, epoll_ev);
+		if (ret < 0)
+			DPAA2_BUS_ERR("Epoll control delete failed(%d)", ret);
+		close(epfd);
+	}
+
 	ret = rte_dpaa2_intr_disable(dpio_dev->intr_handle, 0);
 	if (ret)
-		DPAA2_BUS_ERR("DPIO interrupt disable failed");
+		DPAA2_BUS_ERR("DPIO interrupt disable failed(%d)", ret);
 
-	if (dpio_dev->epoll_fd >= 0) {
-		close(dpio_dev->epoll_fd);
-		dpio_dev->epoll_fd = -1;
-	}
 	dpio_dev->intr_enabled = 0;
 }
 
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index f67f2283db..52ec660fb9 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -133,7 +133,6 @@ struct dpaa2_dpio_dev {
 		/**< Physical address of Cache Inhibit Area */
 	uintptr_t ci_size; /**< Size of the CI region */
 	struct rte_intr_handle *intr_handle; /* Interrupt related info */
-	int32_t	epoll_fd; /**< File descriptor created for interrupt polling */
 	int32_t hw_id; /**< An unique ID of this DPIO device instance */
 	uint8_t intr_enabled; /**< DQRI portal interrupt already set up */
 	int32_t cpu_affine;
diff --git a/drivers/event/dpaa2/dpaa2_eventdev.c b/drivers/event/dpaa2/dpaa2_eventdev.c
index 592b3bf4a4..f4dbf47b18 100644
--- a/drivers/event/dpaa2/dpaa2_eventdev.c
+++ b/drivers/event/dpaa2/dpaa2_eventdev.c
@@ -233,10 +233,13 @@ dpaa2_eventdev_enqueue_burst(void *port, const struct rte_event ev[],
 static void dpaa2_eventdev_dequeue_wait(struct dpaa2_dpio_dev *dpio_dev,
 	uint32_t timeout_ms)
 {
-	struct epoll_event epoll_ev;
+	int ret;
+	struct rte_epoll_event *epoll_event;
 
 	qbman_swp_interrupt_clear_status(dpio_dev->sw_portal, QBMAN_SWP_INTERRUPT_DQRI);
-	epoll_wait(dpio_dev->epoll_fd, &epoll_ev, 1, timeout_ms);
+	epoll_event = rte_intr_elist_index_get(dpio_dev->intr_handle, 0);
+	ret = rte_epoll_wait(epoll_event->epfd, epoll_event, 1, timeout_ms);
+	DPAA2_PMD_DP_DEBUG("%s: poll return(%d)", __func__, ret);
 }
 
 static void dpaa2_eventdev_process_parallel(struct dpaa2_dpio_dev *dpio_dev,
-- 
2.43.0



More information about the dev mailing list