[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