* [PATCH v1 1/1] eal/linux: fix eventfd leaks when enabling interrupts
@ 2026-10-23 9:36 Anatoly Burakov
2026-10-23 11:42 ` David Marchand
` (3 more replies)
0 siblings, 4 replies; 33+ messages in thread
From: Anatoly Burakov @ 2026-10-23 9:36 UTC (permalink / raw)
To: dev, Harman Kalra, Cunming Liang
When enabling MSI-X eventfds, a failure after creating some descriptors
leaves them open. The eventfd count is recorded only after all allocations
succeed, so disabling eventfds cannot clean up a partial allocation.
Calling enable again without disabling first also leaks descriptors by
overwriting the existing eventfd entries.
Reject repeated MSI-X enable calls with EBUSY before modifying the handle.
On failure, close all eventfds created by the call, clear their entries
and reset the eventfd count while preserving the original error.
Fixes: b9e0662a931d ("eal/linux: add interrupt API for drivers")
Cc: stable@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
lib/eal/linux/eal_interrupts.c | 39 +++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c
index 4cfaeba7fe0..ff05d649607 100644
--- a/lib/eal/linux/eal_interrupts.c
+++ b/lib/eal/linux/eal_interrupts.c
@@ -1570,30 +1570,43 @@ int
rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
{
uint32_t i;
- int fd;
+ int fd, ret;
uint32_t n = RTE_MIN(nb_efd, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID);
assert(nb_efd != 0);
if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VFIO_MSIX) {
+ if (rte_intr_nb_efd_get(intr_handle) != 0) {
+ EAL_LOG(ERR, "Interrupt eventfds are already enabled");
+ return -EBUSY;
+ }
+
for (i = 0; i < n; i++) {
fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
if (fd < 0) {
+ ret = -errno;
EAL_LOG(ERR,
"can't setup eventfd, error %i (%s)",
errno, strerror(errno));
- return -errno;
+ goto error;
}
- if (rte_intr_efds_index_set(intr_handle, i, fd))
- return -rte_errno;
+ if (rte_intr_efds_index_set(intr_handle, i, fd)) {
+ ret = -rte_errno;
+ close(fd);
+ goto error;
+ }
}
- if (rte_intr_nb_efd_set(intr_handle, n))
- return -rte_errno;
+ if (rte_intr_nb_efd_set(intr_handle, n)) {
+ ret = -rte_errno;
+ goto error;
+ }
- if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n))
- return -rte_errno;
+ if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n)) {
+ ret = -rte_errno;
+ goto error;
+ }
} else if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VDEV) {
/* only check, initialization would be done in vdev driver.*/
if ((uint64_t)rte_intr_efd_counter_size_get(intr_handle) >
@@ -1611,6 +1624,16 @@ rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
}
return 0;
+
+error:
+ while (i > 0) {
+ i--;
+ close(rte_intr_efds_index_get(intr_handle, i));
+ rte_intr_efds_index_set(intr_handle, i, -1);
+ }
+ rte_intr_nb_efd_set(intr_handle, 0);
+
+ return ret;
}
RTE_EXPORT_INTERNAL_SYMBOL(rte_intr_efd_disable)
--
2.52.0
^ permalink raw reply related [flat|nested] 33+ messages in thread* Re: [PATCH v1 1/1] eal/linux: fix eventfd leaks when enabling interrupts 2026-10-23 9:36 [PATCH v1 1/1] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov @ 2026-10-23 11:42 ` David Marchand 2026-10-23 12:25 ` Burakov, Anatoly 2026-10-23 13:07 ` [PATCH v2 1/3] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov ` (2 subsequent siblings) 3 siblings, 1 reply; 33+ messages in thread From: David Marchand @ 2026-10-23 11:42 UTC (permalink / raw) To: Anatoly Burakov; +Cc: dev, Harman Kalra, Cunming Liang Hello, On Fri, 23 Oct 2026 at 11:37, Anatoly Burakov <anatoly.burakov@intel.com> wrote: > > When enabling MSI-X eventfds, a failure after creating some descriptors > leaves them open. The eventfd count is recorded only after all allocations > succeed, so disabling eventfds cannot clean up a partial allocation. > > Calling enable again without disabling first also leaks descriptors by > overwriting the existing eventfd entries. > > Reject repeated MSI-X enable calls with EBUSY before modifying the handle. > On failure, close all eventfds created by the call, clear their entries > and reset the eventfd count while preserving the original error. > > Fixes: b9e0662a931d ("eal/linux: add interrupt API for drivers") > Cc: stable@dpdk.org > > Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> Good catch. How did you find this issue? I did not put warnings on the efd side, but maybe worth extending d770ee9caed0 ("interrupts: warn on leaked FDs"). One comment below. > --- > lib/eal/linux/eal_interrupts.c | 39 +++++++++++++++++++++++++++------- > 1 file changed, 31 insertions(+), 8 deletions(-) > > diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c > index 4cfaeba7fe0..ff05d649607 100644 > --- a/lib/eal/linux/eal_interrupts.c > +++ b/lib/eal/linux/eal_interrupts.c > @@ -1570,30 +1570,43 @@ int > rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd) > { > uint32_t i; > - int fd; > + int fd, ret; > uint32_t n = RTE_MIN(nb_efd, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID); > > assert(nb_efd != 0); > > if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VFIO_MSIX) { > + if (rte_intr_nb_efd_get(intr_handle) != 0) { > + EAL_LOG(ERR, "Interrupt eventfds are already enabled"); > + return -EBUSY; > + } > + > for (i = 0; i < n; i++) { > fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); > if (fd < 0) { > + ret = -errno; > EAL_LOG(ERR, > "can't setup eventfd, error %i (%s)", > errno, strerror(errno)); > - return -errno; > + goto error; > } > > - if (rte_intr_efds_index_set(intr_handle, i, fd)) > - return -rte_errno; > + if (rte_intr_efds_index_set(intr_handle, i, fd)) { > + ret = -rte_errno; > + close(fd); > + goto error; > + } > } > > - if (rte_intr_nb_efd_set(intr_handle, n)) > - return -rte_errno; > + if (rte_intr_nb_efd_set(intr_handle, n)) { > + ret = -rte_errno; > + goto error; > + } > > - if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n)) > - return -rte_errno; > + if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n)) { > + ret = -rte_errno; > + goto error; > + } > } else if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VDEV) { > /* only check, initialization would be done in vdev driver.*/ > if ((uint64_t)rte_intr_efd_counter_size_get(intr_handle) > > @@ -1611,6 +1624,16 @@ rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd) > } > > return 0; > + > +error: > + while (i > 0) { The i variable should have been declared only in the scope of VFIO type, in the first place. Using i here could blow up later when this error label is used for other interrupt types. As mentionned in the commitlog, could we accumulate the number of valid efds in the vfio setup loop? The cleanup code here could then loop on rte_intr_nb_efd_get. > + i--; > + close(rte_intr_efds_index_get(intr_handle, i)); > + rte_intr_efds_index_set(intr_handle, i, -1); > + } > + rte_intr_nb_efd_set(intr_handle, 0); > + > + return ret; > } > > RTE_EXPORT_INTERNAL_SYMBOL(rte_intr_efd_disable) > -- > 2.52.0 > -- David Marchand ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v1 1/1] eal/linux: fix eventfd leaks when enabling interrupts 2026-10-23 11:42 ` David Marchand @ 2026-10-23 12:25 ` Burakov, Anatoly 0 siblings, 0 replies; 33+ messages in thread From: Burakov, Anatoly @ 2026-10-23 12:25 UTC (permalink / raw) To: David Marchand; +Cc: dev, Harman Kalra, Cunming Liang On 10/23/2026 1:42 PM, David Marchand wrote: > Hello, > > On Fri, 23 Oct 2026 at 11:37, Anatoly Burakov <anatoly.burakov@intel.com> wrote: >> >> When enabling MSI-X eventfds, a failure after creating some descriptors >> leaves them open. The eventfd count is recorded only after all allocations >> succeed, so disabling eventfds cannot clean up a partial allocation. >> >> Calling enable again without disabling first also leaks descriptors by >> overwriting the existing eventfd entries. >> >> Reject repeated MSI-X enable calls with EBUSY before modifying the handle. >> On failure, close all eventfds created by the call, clear their entries >> and reset the eventfd count while preserving the original error. >> >> Fixes: b9e0662a931d ("eal/linux: add interrupt API for drivers") >> Cc: stable@dpdk.org >> >> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> > > Good catch. > How did you find this issue? I didn't :D Bruce's AI review [1] caught the (somewhat confusingly formulated) bug, and I went on investigating. [1] https://patches.dpdk.org/project/dpdk/patch/595c771fac2dda2d602c01ba171d56f3419db917.1792592724.git.anatoly.burakov@intel.com/#186792 > > I did not put warnings on the efd side, but maybe worth extending > d770ee9caed0 ("interrupts: warn on leaked FDs"). Probably, yes. > > One comment below. > > >> --- >> lib/eal/linux/eal_interrupts.c | 39 +++++++++++++++++++++++++++------- >> 1 file changed, 31 insertions(+), 8 deletions(-) >> >> diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c >> index 4cfaeba7fe0..ff05d649607 100644 >> --- a/lib/eal/linux/eal_interrupts.c >> +++ b/lib/eal/linux/eal_interrupts.c >> @@ -1570,30 +1570,43 @@ int >> rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd) >> { >> uint32_t i; >> - int fd; >> + int fd, ret; >> uint32_t n = RTE_MIN(nb_efd, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID); >> >> assert(nb_efd != 0); >> >> if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VFIO_MSIX) { >> + if (rte_intr_nb_efd_get(intr_handle) != 0) { >> + EAL_LOG(ERR, "Interrupt eventfds are already enabled"); >> + return -EBUSY; >> + } >> + >> for (i = 0; i < n; i++) { >> fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); >> if (fd < 0) { >> + ret = -errno; >> EAL_LOG(ERR, >> "can't setup eventfd, error %i (%s)", >> errno, strerror(errno)); >> - return -errno; >> + goto error; >> } >> >> - if (rte_intr_efds_index_set(intr_handle, i, fd)) >> - return -rte_errno; >> + if (rte_intr_efds_index_set(intr_handle, i, fd)) { >> + ret = -rte_errno; >> + close(fd); >> + goto error; >> + } >> } >> >> - if (rte_intr_nb_efd_set(intr_handle, n)) >> - return -rte_errno; >> + if (rte_intr_nb_efd_set(intr_handle, n)) { >> + ret = -rte_errno; >> + goto error; >> + } >> >> - if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n)) >> - return -rte_errno; >> + if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n)) { >> + ret = -rte_errno; >> + goto error; >> + } >> } else if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VDEV) { >> /* only check, initialization would be done in vdev driver.*/ >> if ((uint64_t)rte_intr_efd_counter_size_get(intr_handle) > >> @@ -1611,6 +1624,16 @@ rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd) >> } >> >> return 0; >> + >> +error: >> + while (i > 0) { > > The i variable should have been declared only in the scope of VFIO > type, in the first place. > Using i here could blow up later when this error label is used for > other interrupt types. > > As mentionned in the commitlog, could we accumulate the number of > valid efds in the vfio setup loop? > The cleanup code here could then loop on rte_intr_nb_efd_get. I'll see if this can be improved. Thanks for the review! > > >> + i--; >> + close(rte_intr_efds_index_get(intr_handle, i)); >> + rte_intr_efds_index_set(intr_handle, i, -1); >> + } >> + rte_intr_nb_efd_set(intr_handle, 0); >> + >> + return ret; >> } >> >> RTE_EXPORT_INTERNAL_SYMBOL(rte_intr_efd_disable) >> -- >> 2.52.0 >> > > -- Thanks, Anatoly ^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 1/3] eal/linux: fix closing of event FDs not owned by EAL 2026-10-23 9:36 [PATCH v1 1/1] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov 2026-10-23 11:42 ` David Marchand @ 2026-10-23 13:07 ` Anatoly Burakov 2026-10-23 13:07 ` [PATCH v2 2/3] interrupts: warn on leaked event FDs Anatoly Burakov 2026-10-23 13:07 ` [PATCH v2 3/3] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 1/8] interrupts: fix size of duplicated instance Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 1/8] interrupts: fix size of duplicated instance Anatoly Burakov 3 siblings, 2 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:07 UTC (permalink / raw) To: dev, Harman Kalra, Cunming Liang rte_intr_efd_disable() decides whether to close the event FDs based on max_intr being greater than nb_efd. This is a side effect of how rte_intr_efd_enable() fills the handle for VFIO MSI-X, where an extra slot is reserved for the misc interrupt, and only indirectly identifies the eventfds that EAL created itself. Any driver filling the event FD array for a VDEV or EXT handle and setting max_intr the same way gets its descriptors closed by EAL even though it owns them. The virtio-user driver does exactly this, so its callfds are closed by rte_intr_efd_disable() and then closed again by the driver on uninit. Check the interrupt handle type instead, so that only the eventfds created by rte_intr_efd_enable() for VFIO MSI-X are closed. Fixes: b9e0662a931d ("eal/linux: add interrupt API for drivers") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/linux/eal_interrupts.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c index 4cfaeba7fe0..bdee1dd9777 100644 --- a/lib/eal/linux/eal_interrupts.c +++ b/lib/eal/linux/eal_interrupts.c @@ -1620,7 +1620,11 @@ rte_intr_efd_disable(struct rte_intr_handle *intr_handle) uint32_t i; rte_intr_free_epoll_fd(intr_handle); - if (rte_intr_max_intr_get(intr_handle) > rte_intr_nb_efd_get(intr_handle)) { + /* Only eventfds created by rte_intr_efd_enable() for MSI-X are owned + * by the handle. In other modes the entries reference fds owned by + * the device or the driver and must not be closed here. + */ + if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VFIO_MSIX) { for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) close(rte_intr_efds_index_get(intr_handle, i)); } -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 2/3] interrupts: warn on leaked event FDs 2026-10-23 13:07 ` [PATCH v2 1/3] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov @ 2026-10-23 13:07 ` Anatoly Burakov 2026-10-23 13:07 ` [PATCH v2 3/3] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov 1 sibling, 0 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:07 UTC (permalink / raw) To: dev, Harman Kalra Extend the leak warning in rte_intr_instance_free() to the event FD array, in the same way as the handle FD and device FD. rte_intr_efd_disable() used to close the eventfds it owns but left the stale descriptors in the array, and never cleared the entry that merely references the handle FD in the non-MSI-X case. Reset all entries in use to -1 so a properly disabled handle is not reported. Drivers filling the event FD array themselves are expected to reset the entries once the descriptors are closed or no longer referenced. Suggested-by: David Marchand <david.marchand@redhat.com> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/common/eal_common_interrupts.c | 5 +++++ lib/eal/include/rte_interrupts.h | 7 ++++++- lib/eal/linux/eal_interrupts.c | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/eal/common/eal_common_interrupts.c b/lib/eal/common/eal_common_interrupts.c index 6368ef17714..41fe4286558 100644 --- a/lib/eal/common/eal_common_interrupts.c +++ b/lib/eal/common/eal_common_interrupts.c @@ -193,6 +193,11 @@ void rte_intr_instance_free(struct rte_intr_handle *intr_handle) if (rte_intr_dev_fd_get(intr_handle) >= 0) EAL_LOG(NOTICE, "Some interrupt handle is leaking a device FD: %d", rte_intr_dev_fd_get(intr_handle)); + for (int i = 0; i < intr_handle->nb_intr; i++) { + if (intr_handle->efds[i] >= 0) + EAL_LOG(NOTICE, "Some interrupt handle is leaking an event FD: %d (index %d)", + intr_handle->efds[i], i); + } if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags)) { rte_free(intr_handle->efds); rte_free(intr_handle->elist); diff --git a/lib/eal/include/rte_interrupts.h b/lib/eal/include/rte_interrupts.h index d04c0c7b15f..3aeac9092ae 100644 --- a/lib/eal/include/rte_interrupts.h +++ b/lib/eal/include/rte_interrupts.h @@ -389,6 +389,7 @@ rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd); * @internal * It disables the packet I/O interrupt event. * It deletes registered eventfds and closes the open fds. + * All event fd entries in use are reset to -1. * * @param intr_handle * Pointer to the interrupt handle. @@ -620,12 +621,16 @@ rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle); * @internal * Set the event fd array index with the given fd. * + * Entries still holding a valid fd when the instance is freed are reported + * as leaks, so callers managing the array themselves must reset entries + * to -1 once the fd is closed or no longer referenced. + * * @param intr_handle * pointer to the interrupt handle. * @param index * efds array index to be set * @param fd - * event fd + * event fd, or -1 to clear the entry * * @return * - On success, zero. diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c index bdee1dd9777..17fe443982b 100644 --- a/lib/eal/linux/eal_interrupts.c +++ b/lib/eal/linux/eal_interrupts.c @@ -1628,6 +1628,8 @@ rte_intr_efd_disable(struct rte_intr_handle *intr_handle) for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) close(rte_intr_efds_index_get(intr_handle, i)); } + for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) + rte_intr_efds_index_set(intr_handle, i, -1); rte_intr_nb_efd_set(intr_handle, 0); rte_intr_max_intr_set(intr_handle, 0); } -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 3/3] eal/linux: fix eventfd leaks when enabling interrupts 2026-10-23 13:07 ` [PATCH v2 1/3] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov 2026-10-23 13:07 ` [PATCH v2 2/3] interrupts: warn on leaked event FDs Anatoly Burakov @ 2026-10-23 13:07 ` Anatoly Burakov 1 sibling, 0 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:07 UTC (permalink / raw) To: dev, Harman Kalra, Cunming Liang When enabling MSI-X eventfds, a failure after creating some descriptors leaves them open. The eventfd count is recorded only after all allocations succeed, so disabling eventfds cannot clean up a partial allocation. Calling enable again without disabling first also leaks descriptors by overwriting the existing eventfd entries. Reject repeated MSI-X enable calls with EBUSY before modifying the handle. Update the eventfd count as each descriptor is created, so that on failure every eventfd created by the call can be closed, its entry cleared, and the count reset. Fixes: b9e0662a931d ("eal/linux: add interrupt API for drivers") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/linux/eal_interrupts.c | 43 ++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c index 17fe443982b..59ab0904696 100644 --- a/lib/eal/linux/eal_interrupts.c +++ b/lib/eal/linux/eal_interrupts.c @@ -1569,31 +1569,45 @@ RTE_EXPORT_INTERNAL_SYMBOL(rte_intr_efd_enable) int rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd) { - uint32_t i; - int fd; + int fd, ret; uint32_t n = RTE_MIN(nb_efd, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID); assert(nb_efd != 0); if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VFIO_MSIX) { + uint32_t i; + + if (rte_intr_nb_efd_get(intr_handle) != 0) { + EAL_LOG(ERR, "Interrupt eventfds are already enabled"); + return -EBUSY; + } + for (i = 0; i < n; i++) { fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); if (fd < 0) { + ret = -errno; EAL_LOG(ERR, "can't setup eventfd, error %i (%s)", errno, strerror(errno)); - return -errno; + goto error; } - if (rte_intr_efds_index_set(intr_handle, i, fd)) - return -rte_errno; + /* Record each eventfd as it is created so that the + * error path can close exactly those that exist. + */ + if (rte_intr_efds_index_set(intr_handle, i, fd) || + rte_intr_nb_efd_set(intr_handle, i + 1)) { + ret = -rte_errno; + close(fd); + rte_intr_efds_index_set(intr_handle, i, -1); + goto error; + } } - if (rte_intr_nb_efd_set(intr_handle, n)) - return -rte_errno; - - if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n)) - return -rte_errno; + if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n)) { + ret = -rte_errno; + goto error; + } } else if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VDEV) { /* only check, initialization would be done in vdev driver.*/ if ((uint64_t)rte_intr_efd_counter_size_get(intr_handle) > @@ -1611,6 +1625,15 @@ rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd) } return 0; + +error: + for (int i = 0; i < rte_intr_nb_efd_get(intr_handle); i++) { + close(rte_intr_efds_index_get(intr_handle, i)); + rte_intr_efds_index_set(intr_handle, i, -1); + } + rte_intr_nb_efd_set(intr_handle, 0); + + return ret; } RTE_EXPORT_INTERNAL_SYMBOL(rte_intr_efd_disable) -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v3 1/8] interrupts: fix size of duplicated instance 2026-10-23 9:36 [PATCH v1 1/1] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov 2026-10-23 11:42 ` David Marchand 2026-10-23 13:07 ` [PATCH v2 1/3] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov @ 2026-10-23 13:39 ` Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 2/8] interrupts: fix event arrays copy on instance duplication Anatoly Burakov ` (6 more replies) 2026-10-23 13:51 ` [PATCH v4 1/8] interrupts: fix size of duplicated instance Anatoly Burakov 3 siblings, 7 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:39 UTC (permalink / raw) To: dev, Harman Kalra, David Marchand, Dmitry Kozlyuk, Ray Kinsella A duplicated interrupt handle is allocated with the default event array size, but the source may have been grown with rte_intr_event_list_update() when the device has more vectors than the default. The duplicate then reports the default nb_intr and its arrays are too small for the source contents. Grow the duplicate to the size of the source before copying. Fixes: b7c984291611 ("interrupts: add allocator and accessors") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/common/eal_common_interrupts.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/eal/common/eal_common_interrupts.c b/lib/eal/common/eal_common_interrupts.c index 6368ef17714..4520ff59bd7 100644 --- a/lib/eal/common/eal_common_interrupts.c +++ b/lib/eal/common/eal_common_interrupts.c @@ -115,17 +115,25 @@ struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src) } intr_handle = rte_intr_instance_alloc(src->alloc_flags); - if (intr_handle != NULL) { - intr_handle->fd = src->fd; - intr_handle->dev_fd = src->dev_fd; - intr_handle->type = src->type; - intr_handle->max_intr = src->max_intr; - intr_handle->nb_efd = src->nb_efd; - intr_handle->efd_counter_size = src->efd_counter_size; - memcpy(intr_handle->efds, src->efds, src->nb_intr); - memcpy(intr_handle->elist, src->elist, src->nb_intr); + if (intr_handle == NULL) + return NULL; + + /* The source may have been grown beyond the default array size. */ + if (src->nb_intr > intr_handle->nb_intr && + rte_intr_event_list_update(intr_handle, src->nb_intr) != 0) { + rte_intr_instance_free(intr_handle); + return NULL; } + intr_handle->fd = src->fd; + intr_handle->dev_fd = src->dev_fd; + intr_handle->type = src->type; + intr_handle->max_intr = src->max_intr; + intr_handle->nb_efd = src->nb_efd; + intr_handle->efd_counter_size = src->efd_counter_size; + memcpy(intr_handle->efds, src->efds, src->nb_intr); + memcpy(intr_handle->elist, src->elist, src->nb_intr); + return intr_handle; } -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v3 2/8] interrupts: fix event arrays copy on instance duplication 2026-10-23 13:39 ` [PATCH v3 1/8] interrupts: fix size of duplicated instance Anatoly Burakov @ 2026-10-23 13:39 ` Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 3/8] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov ` (5 subsequent siblings) 6 siblings, 0 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:39 UTC (permalink / raw) To: dev, Harman Kalra, Ray Kinsella, David Marchand, Dmitry Kozlyuk The event FD and epoll event arrays are copied using the number of entries as a byte count, so only a fraction of the entries make it into the duplicate. Copy the arrays by element size. Fixes: b7c984291611 ("interrupts: add allocator and accessors") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/common/eal_common_interrupts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/eal/common/eal_common_interrupts.c b/lib/eal/common/eal_common_interrupts.c index 4520ff59bd7..cf56f967218 100644 --- a/lib/eal/common/eal_common_interrupts.c +++ b/lib/eal/common/eal_common_interrupts.c @@ -131,8 +131,8 @@ struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src) intr_handle->max_intr = src->max_intr; intr_handle->nb_efd = src->nb_efd; intr_handle->efd_counter_size = src->efd_counter_size; - memcpy(intr_handle->efds, src->efds, src->nb_intr); - memcpy(intr_handle->elist, src->elist, src->nb_intr); + memcpy(intr_handle->efds, src->efds, src->nb_intr * sizeof(*src->efds)); + memcpy(intr_handle->elist, src->elist, src->nb_intr * sizeof(*src->elist)); return intr_handle; } -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v3 3/8] eal/linux: fix closing of event FDs not owned by EAL 2026-10-23 13:39 ` [PATCH v3 1/8] interrupts: fix size of duplicated instance Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 2/8] interrupts: fix event arrays copy on instance duplication Anatoly Burakov @ 2026-10-23 13:39 ` Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 4/8] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov ` (4 subsequent siblings) 6 siblings, 0 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:39 UTC (permalink / raw) To: dev, Harman Kalra, Cunming Liang rte_intr_efd_disable() decides whether to close the event FDs based on max_intr being greater than nb_efd. This is a side effect of how rte_intr_efd_enable() fills the handle for VFIO MSI-X, where an extra slot is reserved for the misc interrupt, and only indirectly identifies the eventfds that EAL created itself. Any driver filling the event FD array for a VDEV or EXT handle and setting max_intr the same way gets its descriptors closed by EAL even though it owns them. The virtio-user driver does exactly this, so its callfds are closed by rte_intr_efd_disable() and then closed again by the driver on uninit. Check the interrupt handle type instead, so that only the eventfds created by rte_intr_efd_enable() for VFIO MSI-X are closed. Fixes: b9e0662a931d ("eal/linux: add interrupt API for drivers") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/linux/eal_interrupts.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c index 4cfaeba7fe0..bdee1dd9777 100644 --- a/lib/eal/linux/eal_interrupts.c +++ b/lib/eal/linux/eal_interrupts.c @@ -1620,7 +1620,11 @@ rte_intr_efd_disable(struct rte_intr_handle *intr_handle) uint32_t i; rte_intr_free_epoll_fd(intr_handle); - if (rte_intr_max_intr_get(intr_handle) > rte_intr_nb_efd_get(intr_handle)) { + /* Only eventfds created by rte_intr_efd_enable() for MSI-X are owned + * by the handle. In other modes the entries reference fds owned by + * the device or the driver and must not be closed here. + */ + if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VFIO_MSIX) { for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) close(rte_intr_efds_index_get(intr_handle, i)); } -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v3 4/8] eal/linux: fix eventfd leaks when enabling interrupts 2026-10-23 13:39 ` [PATCH v3 1/8] interrupts: fix size of duplicated instance Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 2/8] interrupts: fix event arrays copy on instance duplication Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 3/8] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov @ 2026-10-23 13:39 ` Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 5/8] eal/linux: fix leaked FD warnings for interrupt sources Anatoly Burakov ` (3 subsequent siblings) 6 siblings, 0 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:39 UTC (permalink / raw) To: dev, Harman Kalra, Cunming Liang When enabling MSI-X eventfds, a failure after creating some descriptors leaves them open. The eventfd count is recorded only after all allocations succeed, so disabling eventfds cannot clean up a partial allocation. Calling enable again without disabling first also leaks descriptors by overwriting the existing eventfd entries. Reject repeated MSI-X enable calls with EBUSY before modifying the handle. Update the eventfd count as each descriptor is created, so that on failure every eventfd created by the call can be closed, its entry cleared, and the count reset. Fixes: b9e0662a931d ("eal/linux: add interrupt API for drivers") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/linux/eal_interrupts.c | 43 ++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c index bdee1dd9777..410b6d66c45 100644 --- a/lib/eal/linux/eal_interrupts.c +++ b/lib/eal/linux/eal_interrupts.c @@ -1569,31 +1569,45 @@ RTE_EXPORT_INTERNAL_SYMBOL(rte_intr_efd_enable) int rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd) { - uint32_t i; - int fd; + int fd, ret; uint32_t n = RTE_MIN(nb_efd, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID); assert(nb_efd != 0); if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VFIO_MSIX) { + uint32_t i; + + if (rte_intr_nb_efd_get(intr_handle) != 0) { + EAL_LOG(ERR, "Interrupt eventfds are already enabled"); + return -EBUSY; + } + for (i = 0; i < n; i++) { fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); if (fd < 0) { + ret = -errno; EAL_LOG(ERR, "can't setup eventfd, error %i (%s)", errno, strerror(errno)); - return -errno; + goto error; } - if (rte_intr_efds_index_set(intr_handle, i, fd)) - return -rte_errno; + /* Record each eventfd as it is created so that the + * error path can close exactly those that exist. + */ + if (rte_intr_efds_index_set(intr_handle, i, fd) || + rte_intr_nb_efd_set(intr_handle, i + 1)) { + ret = -rte_errno; + close(fd); + rte_intr_efds_index_set(intr_handle, i, -1); + goto error; + } } - if (rte_intr_nb_efd_set(intr_handle, n)) - return -rte_errno; - - if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n)) - return -rte_errno; + if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n)) { + ret = -rte_errno; + goto error; + } } else if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VDEV) { /* only check, initialization would be done in vdev driver.*/ if ((uint64_t)rte_intr_efd_counter_size_get(intr_handle) > @@ -1611,6 +1625,15 @@ rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd) } return 0; + +error: + for (int i = 0; i < rte_intr_nb_efd_get(intr_handle); i++) { + close(rte_intr_efds_index_get(intr_handle, i)); + rte_intr_efds_index_set(intr_handle, i, -1); + } + rte_intr_nb_efd_set(intr_handle, 0); + + return ret; } RTE_EXPORT_INTERNAL_SYMBOL(rte_intr_efd_disable) -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v3 5/8] eal/linux: fix leaked FD warnings for interrupt sources 2026-10-23 13:39 ` [PATCH v3 1/8] interrupts: fix size of duplicated instance Anatoly Burakov ` (2 preceding siblings ...) 2026-10-23 13:39 ` [PATCH v3 4/8] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov @ 2026-10-23 13:39 ` Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 6/8] eal/freebsd: fix interrupt source handle leak Anatoly Burakov ` (2 subsequent siblings) 6 siblings, 0 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:39 UTC (permalink / raw) To: dev, Harman Kalra, David Marchand, Thomas Monjalon An interrupt source keeps a private copy of the interrupt handle it was registered with. The copy inherits the handle FD, the device FD and the event FDs but owns none of them: they are closed by whoever set up the original handle. Since the leaked FD warning was added, freeing a source after its last callback is unregistered reports the handle FD and device FD as leaked, for every device on close and again for every VFIO device at EAL cleanup. Clear all FD references in the copy before freeing it. Fixes: d770ee9caed0 ("interrupts: warn on leaked FDs") Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/linux/eal_interrupts.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c index 410b6d66c45..aadb7b84a22 100644 --- a/lib/eal/linux/eal_interrupts.c +++ b/lib/eal/linux/eal_interrupts.c @@ -95,6 +95,25 @@ static struct rte_intr_source_list intr_sources; /* interrupt handling thread */ static rte_thread_t intr_thread; +/* + * An interrupt source holds a copy of the handle it was registered with + * and owns none of the file descriptors. Clear the references before + * freeing the copy so they are not reported as leaks. + */ +static void +eal_intr_source_free(struct rte_intr_source *src) +{ + struct rte_intr_handle *intr_handle = src->intr_handle; + int i; + + rte_intr_fd_set(intr_handle, -1); + rte_intr_dev_fd_set(intr_handle, -1); + for (i = 0; i < rte_intr_nb_intr_get(intr_handle); i++) + rte_intr_efds_index_set(intr_handle, i, -1); + rte_intr_instance_free(intr_handle); + free(src); +} + /* VFIO interrupts */ #define IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + sizeof(int)) /* irq set buffer length for queue interrupts and LSC interrupt */ @@ -666,8 +685,7 @@ rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle, /* all callbacks for that source are removed. */ if (TAILQ_EMPTY(&src->callbacks)) { TAILQ_REMOVE(&intr_sources, src, next); - rte_intr_instance_free(src->intr_handle); - free(src); + eal_intr_source_free(src); } } @@ -922,8 +940,7 @@ eal_intr_source_remove_and_free(struct rte_intr_source *src) } /* Free the interrupt source */ - rte_intr_instance_free(src->intr_handle); - free(src); + eal_intr_source_free(src); } static int @@ -1067,8 +1084,7 @@ eal_intr_process_interrupts(struct epoll_event *events, int nfds) /* all callbacks for that source are removed. */ if (TAILQ_EMPTY(&src->callbacks)) { TAILQ_REMOVE(&intr_sources, src, next); - rte_intr_instance_free(src->intr_handle); - free(src); + eal_intr_source_free(src); } /* notify the pipe fd waited by epoll_wait to rebuild the wait list */ -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v3 6/8] eal/freebsd: fix interrupt source handle leak 2026-10-23 13:39 ` [PATCH v3 1/8] interrupts: fix size of duplicated instance Anatoly Burakov ` (3 preceding siblings ...) 2026-10-23 13:39 ` [PATCH v3 5/8] eal/linux: fix leaked FD warnings for interrupt sources Anatoly Burakov @ 2026-10-23 13:39 ` Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 7/8] bus/pci: fix leaked device FD warning on VFIO unmap Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 8/8] interrupts: warn on leaked event FDs Anatoly Burakov 6 siblings, 0 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:39 UTC (permalink / raw) To: dev, Harman Kalra, Bruce Richardson, David Marchand Each interrupt source keeps a private copy of the interrupt handle it was registered with, but the copy is never freed when the source is removed, leaking the handle and its event arrays. Free the copy with the source. The copy owns none of the file descriptors it references, so clear them first. Fixes: bbbac4cd6ed2 ("interrupts: remove direct access to interrupt handle") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/freebsd/eal_interrupts.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/eal/freebsd/eal_interrupts.c b/lib/eal/freebsd/eal_interrupts.c index bb2bc529f2e..09ba76b378f 100644 --- a/lib/eal/freebsd/eal_interrupts.c +++ b/lib/eal/freebsd/eal_interrupts.c @@ -57,6 +57,25 @@ static rte_thread_t intr_thread; static volatile int kq = -1; +/* + * An interrupt source holds a copy of the handle it was registered with + * and owns none of the file descriptors. Clear the references before + * freeing the copy so they are not reported as leaks. + */ +static void +eal_intr_source_free(struct rte_intr_source *src) +{ + struct rte_intr_handle *intr_handle = src->intr_handle; + int i; + + rte_intr_fd_set(intr_handle, -1); + rte_intr_dev_fd_set(intr_handle, -1); + for (i = 0; i < rte_intr_nb_intr_get(intr_handle); i++) + rte_intr_efds_index_set(intr_handle, i, -1); + rte_intr_instance_free(intr_handle); + free(src); +} + static int intr_source_to_kevent(const struct rte_intr_handle *ih, struct kevent *ke) { @@ -204,7 +223,7 @@ rte_intr_callback_register(const struct rte_intr_handle *intr_handle, TAILQ_REMOVE(&(src->callbacks), callback, next); if (TAILQ_EMPTY(&(src->callbacks))) { TAILQ_REMOVE(&intr_sources, src, next); - free(src); + eal_intr_source_free(src); } } free(callback); @@ -347,7 +366,7 @@ rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle, /* all callbacks for that source are removed. */ if (TAILQ_EMPTY(&src->callbacks)) { TAILQ_REMOVE(&intr_sources, src, next); - free(src); + eal_intr_source_free(src); } } out: @@ -592,7 +611,7 @@ eal_intr_process_interrupts(struct kevent *events, int nfds) /* all callbacks for that source are removed. */ if (TAILQ_EMPTY(&src->callbacks)) { TAILQ_REMOVE(&intr_sources, src, next); - free(src); + eal_intr_source_free(src); } rte_spinlock_unlock(&intr_lock); -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v3 7/8] bus/pci: fix leaked device FD warning on VFIO unmap 2026-10-23 13:39 ` [PATCH v3 1/8] interrupts: fix size of duplicated instance Anatoly Burakov ` (4 preceding siblings ...) 2026-10-23 13:39 ` [PATCH v3 6/8] eal/freebsd: fix interrupt source handle leak Anatoly Burakov @ 2026-10-23 13:39 ` Anatoly Burakov 2026-10-23 13:49 ` Burakov, Anatoly 2026-10-23 13:39 ` [PATCH v3 8/8] interrupts: warn on leaked event FDs Anatoly Burakov 6 siblings, 1 reply; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:39 UTC (permalink / raw) To: dev, Chenbo Xia, Nipun Gupta, David Marchand, Thomas Monjalon When unmapping a VFIO device, the interrupt handle FD is closed but the reference to the VFIO device FD is left in the handle. The device FD is owned by the VFIO layer and released separately, so freeing the handle later reports it as leaked. Clear the reference once the device FD has been retrieved, as is already done for the request notifier handle. Fixes: d770ee9caed0 ("interrupts: warn on leaked FDs") Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- drivers/bus/pci/linux/pci_vfio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c index fb35bc1d491..1116603f43f 100644 --- a/drivers/bus/pci/linux/pci_vfio.c +++ b/drivers/bus/pci/linux/pci_vfio.c @@ -1091,6 +1091,8 @@ pci_vfio_unmap_resource_primary(struct rte_pci_device *dev) vfio_dev_fd = rte_intr_dev_fd_get(dev->intr_handle); if (vfio_dev_fd < 0) return -1; + /* vfio_dev_fd is managed by VFIO layer, only clear reference here. */ + rte_intr_dev_fd_set(dev->intr_handle, -1); if (rte_pci_set_bus_master(dev, false)) { PCI_LOG(ERR, "%s cannot unset bus mastering for PCI device!", pci_addr); @@ -1135,6 +1137,8 @@ pci_vfio_unmap_resource_secondary(struct rte_pci_device *dev) vfio_dev_fd = rte_intr_dev_fd_get(dev->intr_handle); if (vfio_dev_fd < 0) return -1; + /* vfio_dev_fd is managed by VFIO layer, only clear reference here. */ + rte_intr_dev_fd_set(dev->intr_handle, -1); ret = dev_vfio_release_device(rte_pci_get_sysfs_path(), pci_addr, vfio_dev_fd); -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: [PATCH v3 7/8] bus/pci: fix leaked device FD warning on VFIO unmap 2026-10-23 13:39 ` [PATCH v3 7/8] bus/pci: fix leaked device FD warning on VFIO unmap Anatoly Burakov @ 2026-10-23 13:49 ` Burakov, Anatoly 0 siblings, 0 replies; 33+ messages in thread From: Burakov, Anatoly @ 2026-10-23 13:49 UTC (permalink / raw) To: dev, Chenbo Xia, Nipun Gupta, David Marchand, Thomas Monjalon On 10/23/2026 3:39 PM, Anatoly Burakov wrote: > When unmapping a VFIO device, the interrupt handle FD is closed but the > reference to the VFIO device FD is left in the handle. The device FD is > owned by the VFIO layer and released separately, so freeing the handle > later reports it as leaked. > > Clear the reference once the device FD has been retrieved, as is already > done for the request notifier handle. > > Fixes: d770ee9caed0 ("interrupts: warn on leaked FDs") > > Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> > --- > drivers/bus/pci/linux/pci_vfio.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c > index fb35bc1d491..1116603f43f 100644 > --- a/drivers/bus/pci/linux/pci_vfio.c > +++ b/drivers/bus/pci/linux/pci_vfio.c > @@ -1091,6 +1091,8 @@ pci_vfio_unmap_resource_primary(struct rte_pci_device *dev) > vfio_dev_fd = rte_intr_dev_fd_get(dev->intr_handle); > if (vfio_dev_fd < 0) > return -1; > + /* vfio_dev_fd is managed by VFIO layer, only clear reference here. */ > + rte_intr_dev_fd_set(dev->intr_handle, -1); > > if (rte_pci_set_bus_master(dev, false)) { > PCI_LOG(ERR, "%s cannot unset bus mastering for PCI device!", pci_addr); > @@ -1135,6 +1137,8 @@ pci_vfio_unmap_resource_secondary(struct rte_pci_device *dev) > vfio_dev_fd = rte_intr_dev_fd_get(dev->intr_handle); > if (vfio_dev_fd < 0) > return -1; > + /* vfio_dev_fd is managed by VFIO layer, only clear reference here. */ > + rte_intr_dev_fd_set(dev->intr_handle, -1); > > ret = dev_vfio_release_device(rte_pci_get_sysfs_path(), pci_addr, > vfio_dev_fd); Those intr_dev_fd_set's should've been put after the dev_vfio_device_release. I'll send a v4 fixing that. -- Thanks, Anatoly ^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 8/8] interrupts: warn on leaked event FDs 2026-10-23 13:39 ` [PATCH v3 1/8] interrupts: fix size of duplicated instance Anatoly Burakov ` (5 preceding siblings ...) 2026-10-23 13:39 ` [PATCH v3 7/8] bus/pci: fix leaked device FD warning on VFIO unmap Anatoly Burakov @ 2026-10-23 13:39 ` Anatoly Burakov 6 siblings, 0 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:39 UTC (permalink / raw) To: dev, Harman Kalra Extend the leak warning in rte_intr_instance_free() to the event FD array, in the same way as the handle FD and device FD. rte_intr_efd_disable() used to close the eventfds it owns but left the stale descriptors in the array, and never cleared the entry that merely references the handle FD in the non-MSI-X case. Reset all entries in use to -1 so a properly disabled handle is not reported. Drivers filling the event FD array themselves are expected to reset the entries once the descriptors are closed or no longer referenced. Suggested-by: David Marchand <david.marchand@redhat.com> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/common/eal_common_interrupts.c | 5 +++++ lib/eal/include/rte_interrupts.h | 7 ++++++- lib/eal/linux/eal_interrupts.c | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/eal/common/eal_common_interrupts.c b/lib/eal/common/eal_common_interrupts.c index cf56f967218..fa0e0ab961d 100644 --- a/lib/eal/common/eal_common_interrupts.c +++ b/lib/eal/common/eal_common_interrupts.c @@ -201,6 +201,11 @@ void rte_intr_instance_free(struct rte_intr_handle *intr_handle) if (rte_intr_dev_fd_get(intr_handle) >= 0) EAL_LOG(NOTICE, "Some interrupt handle is leaking a device FD: %d", rte_intr_dev_fd_get(intr_handle)); + for (int i = 0; i < intr_handle->nb_intr; i++) { + if (intr_handle->efds[i] >= 0) + EAL_LOG(NOTICE, "Some interrupt handle is leaking an event FD: %d (index %d)", + intr_handle->efds[i], i); + } if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags)) { rte_free(intr_handle->efds); rte_free(intr_handle->elist); diff --git a/lib/eal/include/rte_interrupts.h b/lib/eal/include/rte_interrupts.h index d04c0c7b15f..3aeac9092ae 100644 --- a/lib/eal/include/rte_interrupts.h +++ b/lib/eal/include/rte_interrupts.h @@ -389,6 +389,7 @@ rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd); * @internal * It disables the packet I/O interrupt event. * It deletes registered eventfds and closes the open fds. + * All event fd entries in use are reset to -1. * * @param intr_handle * Pointer to the interrupt handle. @@ -620,12 +621,16 @@ rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle); * @internal * Set the event fd array index with the given fd. * + * Entries still holding a valid fd when the instance is freed are reported + * as leaks, so callers managing the array themselves must reset entries + * to -1 once the fd is closed or no longer referenced. + * * @param intr_handle * pointer to the interrupt handle. * @param index * efds array index to be set * @param fd - * event fd + * event fd, or -1 to clear the entry * * @return * - On success, zero. diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c index aadb7b84a22..f6f51ba53c0 100644 --- a/lib/eal/linux/eal_interrupts.c +++ b/lib/eal/linux/eal_interrupts.c @@ -1667,6 +1667,8 @@ rte_intr_efd_disable(struct rte_intr_handle *intr_handle) for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) close(rte_intr_efds_index_get(intr_handle, i)); } + for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) + rte_intr_efds_index_set(intr_handle, i, -1); rte_intr_nb_efd_set(intr_handle, 0); rte_intr_max_intr_set(intr_handle, 0); } -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v4 1/8] interrupts: fix size of duplicated instance 2026-10-23 9:36 [PATCH v1 1/1] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov ` (2 preceding siblings ...) 2026-10-23 13:39 ` [PATCH v3 1/8] interrupts: fix size of duplicated instance Anatoly Burakov @ 2026-10-23 13:51 ` Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 2/8] interrupts: fix event arrays copy on instance duplication Anatoly Burakov ` (6 more replies) 3 siblings, 7 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:51 UTC (permalink / raw) To: dev, Harman Kalra, Ray Kinsella, David Marchand, Dmitry Kozlyuk A duplicated interrupt handle is allocated with the default event array size, but the source may have been grown with rte_intr_event_list_update() when the device has more vectors than the default. The duplicate then reports the default nb_intr and its arrays are too small for the source contents. Grow the duplicate to the size of the source before copying. Fixes: b7c984291611 ("interrupts: add allocator and accessors") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/common/eal_common_interrupts.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/eal/common/eal_common_interrupts.c b/lib/eal/common/eal_common_interrupts.c index 6368ef17714..4520ff59bd7 100644 --- a/lib/eal/common/eal_common_interrupts.c +++ b/lib/eal/common/eal_common_interrupts.c @@ -115,17 +115,25 @@ struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src) } intr_handle = rte_intr_instance_alloc(src->alloc_flags); - if (intr_handle != NULL) { - intr_handle->fd = src->fd; - intr_handle->dev_fd = src->dev_fd; - intr_handle->type = src->type; - intr_handle->max_intr = src->max_intr; - intr_handle->nb_efd = src->nb_efd; - intr_handle->efd_counter_size = src->efd_counter_size; - memcpy(intr_handle->efds, src->efds, src->nb_intr); - memcpy(intr_handle->elist, src->elist, src->nb_intr); + if (intr_handle == NULL) + return NULL; + + /* The source may have been grown beyond the default array size. */ + if (src->nb_intr > intr_handle->nb_intr && + rte_intr_event_list_update(intr_handle, src->nb_intr) != 0) { + rte_intr_instance_free(intr_handle); + return NULL; } + intr_handle->fd = src->fd; + intr_handle->dev_fd = src->dev_fd; + intr_handle->type = src->type; + intr_handle->max_intr = src->max_intr; + intr_handle->nb_efd = src->nb_efd; + intr_handle->efd_counter_size = src->efd_counter_size; + memcpy(intr_handle->efds, src->efds, src->nb_intr); + memcpy(intr_handle->elist, src->elist, src->nb_intr); + return intr_handle; } -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v4 2/8] interrupts: fix event arrays copy on instance duplication 2026-10-23 13:51 ` [PATCH v4 1/8] interrupts: fix size of duplicated instance Anatoly Burakov @ 2026-10-23 13:51 ` Anatoly Burakov 2026-10-23 14:15 ` David Marchand 2026-10-23 13:51 ` [PATCH v4 3/8] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov ` (5 subsequent siblings) 6 siblings, 1 reply; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:51 UTC (permalink / raw) To: dev, Harman Kalra, Ray Kinsella, Dmitry Kozlyuk, David Marchand The event FD and epoll event arrays are copied using the number of entries as a byte count, so only a fraction of the entries make it into the duplicate. Copy the arrays by element size. Fixes: b7c984291611 ("interrupts: add allocator and accessors") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/common/eal_common_interrupts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/eal/common/eal_common_interrupts.c b/lib/eal/common/eal_common_interrupts.c index 4520ff59bd7..cf56f967218 100644 --- a/lib/eal/common/eal_common_interrupts.c +++ b/lib/eal/common/eal_common_interrupts.c @@ -131,8 +131,8 @@ struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src) intr_handle->max_intr = src->max_intr; intr_handle->nb_efd = src->nb_efd; intr_handle->efd_counter_size = src->efd_counter_size; - memcpy(intr_handle->efds, src->efds, src->nb_intr); - memcpy(intr_handle->elist, src->elist, src->nb_intr); + memcpy(intr_handle->efds, src->efds, src->nb_intr * sizeof(*src->efds)); + memcpy(intr_handle->elist, src->elist, src->nb_intr * sizeof(*src->elist)); return intr_handle; } -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: [PATCH v4 2/8] interrupts: fix event arrays copy on instance duplication 2026-10-23 13:51 ` [PATCH v4 2/8] interrupts: fix event arrays copy on instance duplication Anatoly Burakov @ 2026-10-23 14:15 ` David Marchand 2026-10-23 14:36 ` Burakov, Anatoly 0 siblings, 1 reply; 33+ messages in thread From: David Marchand @ 2026-10-23 14:15 UTC (permalink / raw) To: Anatoly Burakov; +Cc: dev, Harman Kalra, Ray Kinsella, Dmitry Kozlyuk On Fri, 23 Oct 2026 at 15:51, Anatoly Burakov <anatoly.burakov@intel.com> wrote: > > The event FD and epoll event arrays are copied using the number of > entries as a byte count, so only a fraction of the entries make it > into the duplicate. > > Copy the arrays by element size. > > Fixes: b7c984291611 ("interrupts: add allocator and accessors") > Cc: stable@dpdk.org > > Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> Thanks for working on those issues on such short notice. I already put a series for fixing a number of issues with interrupts. As part of it, I would remove the whole duplication principle. Could you perhaps test your series on top of mine? https://patchwork.dpdk.org/project/dpdk/list/?series=39749 -- David Marchand ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v4 2/8] interrupts: fix event arrays copy on instance duplication 2026-10-23 14:15 ` David Marchand @ 2026-10-23 14:36 ` Burakov, Anatoly 2026-10-23 14:44 ` David Marchand 0 siblings, 1 reply; 33+ messages in thread From: Burakov, Anatoly @ 2026-10-23 14:36 UTC (permalink / raw) To: David Marchand; +Cc: dev, Harman Kalra, Ray Kinsella, Dmitry Kozlyuk On 10/23/2026 4:15 PM, David Marchand wrote: > On Fri, 23 Oct 2026 at 15:51, Anatoly Burakov <anatoly.burakov@intel.com> wrote: >> >> The event FD and epoll event arrays are copied using the number of >> entries as a byte count, so only a fraction of the entries make it >> into the duplicate. >> >> Copy the arrays by element size. >> >> Fixes: b7c984291611 ("interrupts: add allocator and accessors") >> Cc: stable@dpdk.org >> >> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> > > Thanks for working on those issues on such short notice. > > I already put a series for fixing a number of issues with interrupts. > As part of it, I would remove the whole duplication principle. > > Could you perhaps test your series on top of mine? > > https://patchwork.dpdk.org/project/dpdk/list/?series=39749 > > It seems that your patchset makes most of mine obsolete, as only 3 commits survived the rebase (incidentally, the ones I had in v2), and the conflicts were trivial enough to resolve on apply IMO. If you like I can rebase my patchset on top of yours so that you may include it in yours and take over? -- Thanks, Anatoly ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v4 2/8] interrupts: fix event arrays copy on instance duplication 2026-10-23 14:36 ` Burakov, Anatoly @ 2026-10-23 14:44 ` David Marchand 2026-10-23 14:55 ` Burakov, Anatoly 0 siblings, 1 reply; 33+ messages in thread From: David Marchand @ 2026-10-23 14:44 UTC (permalink / raw) To: Burakov, Anatoly; +Cc: dev, Harman Kalra, Ray Kinsella, Dmitry Kozlyuk On Fri, 23 Oct 2026 at 16:37, Burakov, Anatoly <anatoly.burakov@intel.com> wrote: > > On 10/23/2026 4:15 PM, David Marchand wrote: > > On Fri, 23 Oct 2026 at 15:51, Anatoly Burakov <anatoly.burakov@intel.com> wrote: > >> > >> The event FD and epoll event arrays are copied using the number of > >> entries as a byte count, so only a fraction of the entries make it > >> into the duplicate. > >> > >> Copy the arrays by element size. > >> > >> Fixes: b7c984291611 ("interrupts: add allocator and accessors") > >> Cc: stable@dpdk.org > >> > >> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> > > > > Thanks for working on those issues on such short notice. > > > > I already put a series for fixing a number of issues with interrupts. > > As part of it, I would remove the whole duplication principle. > > > > Could you perhaps test your series on top of mine? > > > > https://patchwork.dpdk.org/project/dpdk/list/?series=39749 > > > > > > It seems that your patchset makes most of mine obsolete, as only 3 > commits survived the rebase (incidentally, the ones I had in v2), and > the conflicts were trivial enough to resolve on apply IMO. If you like I Indeed. > can rebase my patchset on top of yours so that you may include it in > yours and take over? I don't mind taking over. We just need to agree on my comment on the last patch. The other two fixes lgtm. -- David Marchand ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v4 2/8] interrupts: fix event arrays copy on instance duplication 2026-10-23 14:44 ` David Marchand @ 2026-10-23 14:55 ` Burakov, Anatoly 0 siblings, 0 replies; 33+ messages in thread From: Burakov, Anatoly @ 2026-10-23 14:55 UTC (permalink / raw) To: David Marchand; +Cc: dev, Harman Kalra, Ray Kinsella, Dmitry Kozlyuk On 10/23/2026 4:44 PM, David Marchand wrote: > On Fri, 23 Oct 2026 at 16:37, Burakov, Anatoly > <anatoly.burakov@intel.com> wrote: >> >> On 10/23/2026 4:15 PM, David Marchand wrote: >>> On Fri, 23 Oct 2026 at 15:51, Anatoly Burakov <anatoly.burakov@intel.com> wrote: >>>> >>>> The event FD and epoll event arrays are copied using the number of >>>> entries as a byte count, so only a fraction of the entries make it >>>> into the duplicate. >>>> >>>> Copy the arrays by element size. >>>> >>>> Fixes: b7c984291611 ("interrupts: add allocator and accessors") >>>> Cc: stable@dpdk.org >>>> >>>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> >>> >>> Thanks for working on those issues on such short notice. >>> >>> I already put a series for fixing a number of issues with interrupts. >>> As part of it, I would remove the whole duplication principle. >>> >>> Could you perhaps test your series on top of mine? >>> >>> https://patchwork.dpdk.org/project/dpdk/list/?series=39749 >>> >>> >> >> It seems that your patchset makes most of mine obsolete, as only 3 >> commits survived the rebase (incidentally, the ones I had in v2), and >> the conflicts were trivial enough to resolve on apply IMO. If you like I > > Indeed. > >> can rebase my patchset on top of yours so that you may include it in >> yours and take over? > > I don't mind taking over. > We just need to agree on my comment on the last patch. > > The other two fixes lgtm. > I added my comment to the last patch, so feel free to take over the patches! -- Thanks, Anatoly ^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v4 3/8] eal/linux: fix closing of event FDs not owned by EAL 2026-10-23 13:51 ` [PATCH v4 1/8] interrupts: fix size of duplicated instance Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 2/8] interrupts: fix event arrays copy on instance duplication Anatoly Burakov @ 2026-10-23 13:51 ` Anatoly Burakov 2026-10-23 14:17 ` David Marchand 2026-10-23 13:51 ` [PATCH v4 4/8] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov ` (4 subsequent siblings) 6 siblings, 1 reply; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:51 UTC (permalink / raw) To: dev, Harman Kalra, Cunming Liang rte_intr_efd_disable() decides whether to close the event FDs based on max_intr being greater than nb_efd. This is a side effect of how rte_intr_efd_enable() fills the handle for VFIO MSI-X, where an extra slot is reserved for the misc interrupt, and only indirectly identifies the eventfds that EAL created itself. Any driver filling the event FD array for a VDEV or EXT handle and setting max_intr the same way gets its descriptors closed by EAL even though it owns them. The virtio-user driver does exactly this, so its callfds are closed by rte_intr_efd_disable() and then closed again by the driver on uninit. Check the interrupt handle type instead, so that only the eventfds created by rte_intr_efd_enable() for VFIO MSI-X are closed. Fixes: b9e0662a931d ("eal/linux: add interrupt API for drivers") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/linux/eal_interrupts.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c index 4cfaeba7fe0..bdee1dd9777 100644 --- a/lib/eal/linux/eal_interrupts.c +++ b/lib/eal/linux/eal_interrupts.c @@ -1620,7 +1620,11 @@ rte_intr_efd_disable(struct rte_intr_handle *intr_handle) uint32_t i; rte_intr_free_epoll_fd(intr_handle); - if (rte_intr_max_intr_get(intr_handle) > rte_intr_nb_efd_get(intr_handle)) { + /* Only eventfds created by rte_intr_efd_enable() for MSI-X are owned + * by the handle. In other modes the entries reference fds owned by + * the device or the driver and must not be closed here. + */ + if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VFIO_MSIX) { for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) close(rte_intr_efds_index_get(intr_handle, i)); } -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: [PATCH v4 3/8] eal/linux: fix closing of event FDs not owned by EAL 2026-10-23 13:51 ` [PATCH v4 3/8] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov @ 2026-10-23 14:17 ` David Marchand 0 siblings, 0 replies; 33+ messages in thread From: David Marchand @ 2026-10-23 14:17 UTC (permalink / raw) To: Anatoly Burakov; +Cc: dev, Harman Kalra, Cunming Liang On Fri, 23 Oct 2026 at 15:52, Anatoly Burakov <anatoly.burakov@intel.com> wrote: > > rte_intr_efd_disable() decides whether to close the event FDs based on > max_intr being greater than nb_efd. This is a side effect of how > rte_intr_efd_enable() fills the handle for VFIO MSI-X, where an extra > slot is reserved for the misc interrupt, and only indirectly identifies > the eventfds that EAL created itself. > > Any driver filling the event FD array for a VDEV or EXT handle and > setting max_intr the same way gets its descriptors closed by EAL even > though it owns them. The virtio-user driver does exactly this, so its > callfds are closed by rte_intr_efd_disable() and then closed again by > the driver on uninit. > > Check the interrupt handle type instead, so that only the eventfds > created by rte_intr_efd_enable() for VFIO MSI-X are closed. > > Fixes: b9e0662a931d ("eal/linux: add interrupt API for drivers") > Cc: stable@dpdk.org > > Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> LGTM. Acked-by: David Marchand <david.marchand@redhat.com> -- David Marchand ^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v4 4/8] eal/linux: fix eventfd leaks when enabling interrupts 2026-10-23 13:51 ` [PATCH v4 1/8] interrupts: fix size of duplicated instance Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 2/8] interrupts: fix event arrays copy on instance duplication Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 3/8] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov @ 2026-10-23 13:51 ` Anatoly Burakov 2026-10-23 14:37 ` David Marchand 2026-10-23 13:51 ` [PATCH v4 5/8] eal/linux: fix leaked FD warnings for interrupt sources Anatoly Burakov ` (3 subsequent siblings) 6 siblings, 1 reply; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:51 UTC (permalink / raw) To: dev, Harman Kalra, Cunming Liang When enabling MSI-X eventfds, a failure after creating some descriptors leaves them open. The eventfd count is recorded only after all allocations succeed, so disabling eventfds cannot clean up a partial allocation. Calling enable again without disabling first also leaks descriptors by overwriting the existing eventfd entries. Reject repeated MSI-X enable calls with EBUSY before modifying the handle. Update the eventfd count as each descriptor is created, so that on failure every eventfd created by the call can be closed, its entry cleared, and the count reset. Fixes: b9e0662a931d ("eal/linux: add interrupt API for drivers") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/linux/eal_interrupts.c | 43 ++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c index bdee1dd9777..410b6d66c45 100644 --- a/lib/eal/linux/eal_interrupts.c +++ b/lib/eal/linux/eal_interrupts.c @@ -1569,31 +1569,45 @@ RTE_EXPORT_INTERNAL_SYMBOL(rte_intr_efd_enable) int rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd) { - uint32_t i; - int fd; + int fd, ret; uint32_t n = RTE_MIN(nb_efd, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID); assert(nb_efd != 0); if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VFIO_MSIX) { + uint32_t i; + + if (rte_intr_nb_efd_get(intr_handle) != 0) { + EAL_LOG(ERR, "Interrupt eventfds are already enabled"); + return -EBUSY; + } + for (i = 0; i < n; i++) { fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); if (fd < 0) { + ret = -errno; EAL_LOG(ERR, "can't setup eventfd, error %i (%s)", errno, strerror(errno)); - return -errno; + goto error; } - if (rte_intr_efds_index_set(intr_handle, i, fd)) - return -rte_errno; + /* Record each eventfd as it is created so that the + * error path can close exactly those that exist. + */ + if (rte_intr_efds_index_set(intr_handle, i, fd) || + rte_intr_nb_efd_set(intr_handle, i + 1)) { + ret = -rte_errno; + close(fd); + rte_intr_efds_index_set(intr_handle, i, -1); + goto error; + } } - if (rte_intr_nb_efd_set(intr_handle, n)) - return -rte_errno; - - if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n)) - return -rte_errno; + if (rte_intr_max_intr_set(intr_handle, NB_OTHER_INTR + n)) { + ret = -rte_errno; + goto error; + } } else if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VDEV) { /* only check, initialization would be done in vdev driver.*/ if ((uint64_t)rte_intr_efd_counter_size_get(intr_handle) > @@ -1611,6 +1625,15 @@ rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd) } return 0; + +error: + for (int i = 0; i < rte_intr_nb_efd_get(intr_handle); i++) { + close(rte_intr_efds_index_get(intr_handle, i)); + rte_intr_efds_index_set(intr_handle, i, -1); + } + rte_intr_nb_efd_set(intr_handle, 0); + + return ret; } RTE_EXPORT_INTERNAL_SYMBOL(rte_intr_efd_disable) -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: [PATCH v4 4/8] eal/linux: fix eventfd leaks when enabling interrupts 2026-10-23 13:51 ` [PATCH v4 4/8] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov @ 2026-10-23 14:37 ` David Marchand 0 siblings, 0 replies; 33+ messages in thread From: David Marchand @ 2026-10-23 14:37 UTC (permalink / raw) To: Anatoly Burakov; +Cc: dev, Harman Kalra, Cunming Liang On Fri, 23 Oct 2026 at 15:52, Anatoly Burakov <anatoly.burakov@intel.com> wrote: > > When enabling MSI-X eventfds, a failure after creating some descriptors > leaves them open. The eventfd count is recorded only after all allocations > succeed, so disabling eventfds cannot clean up a partial allocation. > > Calling enable again without disabling first also leaks descriptors by > overwriting the existing eventfd entries. > > Reject repeated MSI-X enable calls with EBUSY before modifying the handle. > Update the eventfd count as each descriptor is created, so that on failure > every eventfd created by the call can be closed, its entry cleared, and the > count reset. > > Fixes: b9e0662a931d ("eal/linux: add interrupt API for drivers") > Cc: stable@dpdk.org > > Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> There is a type change between the two loops, but that's harmless. Acked-by: David Marchand <david.marchand@redhat.com> -- David Marchand ^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v4 5/8] eal/linux: fix leaked FD warnings for interrupt sources 2026-10-23 13:51 ` [PATCH v4 1/8] interrupts: fix size of duplicated instance Anatoly Burakov ` (2 preceding siblings ...) 2026-10-23 13:51 ` [PATCH v4 4/8] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov @ 2026-10-23 13:51 ` Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 6/8] eal/freebsd: fix interrupt source handle leak Anatoly Burakov ` (2 subsequent siblings) 6 siblings, 0 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:51 UTC (permalink / raw) To: dev, Harman Kalra, Thomas Monjalon, David Marchand An interrupt source keeps a private copy of the interrupt handle it was registered with. The copy inherits the handle FD, the device FD and the event FDs but owns none of them: they are closed by whoever set up the original handle. Since the leaked FD warning was added, freeing a source after its last callback is unregistered reports the handle FD and device FD as leaked, for every device on close and again for every VFIO device at EAL cleanup. Clear all FD references in the copy before freeing it. Fixes: d770ee9caed0 ("interrupts: warn on leaked FDs") Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/linux/eal_interrupts.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c index 410b6d66c45..aadb7b84a22 100644 --- a/lib/eal/linux/eal_interrupts.c +++ b/lib/eal/linux/eal_interrupts.c @@ -95,6 +95,25 @@ static struct rte_intr_source_list intr_sources; /* interrupt handling thread */ static rte_thread_t intr_thread; +/* + * An interrupt source holds a copy of the handle it was registered with + * and owns none of the file descriptors. Clear the references before + * freeing the copy so they are not reported as leaks. + */ +static void +eal_intr_source_free(struct rte_intr_source *src) +{ + struct rte_intr_handle *intr_handle = src->intr_handle; + int i; + + rte_intr_fd_set(intr_handle, -1); + rte_intr_dev_fd_set(intr_handle, -1); + for (i = 0; i < rte_intr_nb_intr_get(intr_handle); i++) + rte_intr_efds_index_set(intr_handle, i, -1); + rte_intr_instance_free(intr_handle); + free(src); +} + /* VFIO interrupts */ #define IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + sizeof(int)) /* irq set buffer length for queue interrupts and LSC interrupt */ @@ -666,8 +685,7 @@ rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle, /* all callbacks for that source are removed. */ if (TAILQ_EMPTY(&src->callbacks)) { TAILQ_REMOVE(&intr_sources, src, next); - rte_intr_instance_free(src->intr_handle); - free(src); + eal_intr_source_free(src); } } @@ -922,8 +940,7 @@ eal_intr_source_remove_and_free(struct rte_intr_source *src) } /* Free the interrupt source */ - rte_intr_instance_free(src->intr_handle); - free(src); + eal_intr_source_free(src); } static int @@ -1067,8 +1084,7 @@ eal_intr_process_interrupts(struct epoll_event *events, int nfds) /* all callbacks for that source are removed. */ if (TAILQ_EMPTY(&src->callbacks)) { TAILQ_REMOVE(&intr_sources, src, next); - rte_intr_instance_free(src->intr_handle); - free(src); + eal_intr_source_free(src); } /* notify the pipe fd waited by epoll_wait to rebuild the wait list */ -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v4 6/8] eal/freebsd: fix interrupt source handle leak 2026-10-23 13:51 ` [PATCH v4 1/8] interrupts: fix size of duplicated instance Anatoly Burakov ` (3 preceding siblings ...) 2026-10-23 13:51 ` [PATCH v4 5/8] eal/linux: fix leaked FD warnings for interrupt sources Anatoly Burakov @ 2026-10-23 13:51 ` Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 7/8] bus/pci: fix leaked device FD warning on VFIO unmap Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 8/8] interrupts: warn on leaked event FDs Anatoly Burakov 6 siblings, 0 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:51 UTC (permalink / raw) To: dev, Harman Kalra, Bruce Richardson, David Marchand Each interrupt source keeps a private copy of the interrupt handle it was registered with, but the copy is never freed when the source is removed, leaking the handle and its event arrays. Free the copy with the source. The copy owns none of the file descriptors it references, so clear them first. Fixes: bbbac4cd6ed2 ("interrupts: remove direct access to interrupt handle") Cc: stable@dpdk.org Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/freebsd/eal_interrupts.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/eal/freebsd/eal_interrupts.c b/lib/eal/freebsd/eal_interrupts.c index bb2bc529f2e..09ba76b378f 100644 --- a/lib/eal/freebsd/eal_interrupts.c +++ b/lib/eal/freebsd/eal_interrupts.c @@ -57,6 +57,25 @@ static rte_thread_t intr_thread; static volatile int kq = -1; +/* + * An interrupt source holds a copy of the handle it was registered with + * and owns none of the file descriptors. Clear the references before + * freeing the copy so they are not reported as leaks. + */ +static void +eal_intr_source_free(struct rte_intr_source *src) +{ + struct rte_intr_handle *intr_handle = src->intr_handle; + int i; + + rte_intr_fd_set(intr_handle, -1); + rte_intr_dev_fd_set(intr_handle, -1); + for (i = 0; i < rte_intr_nb_intr_get(intr_handle); i++) + rte_intr_efds_index_set(intr_handle, i, -1); + rte_intr_instance_free(intr_handle); + free(src); +} + static int intr_source_to_kevent(const struct rte_intr_handle *ih, struct kevent *ke) { @@ -204,7 +223,7 @@ rte_intr_callback_register(const struct rte_intr_handle *intr_handle, TAILQ_REMOVE(&(src->callbacks), callback, next); if (TAILQ_EMPTY(&(src->callbacks))) { TAILQ_REMOVE(&intr_sources, src, next); - free(src); + eal_intr_source_free(src); } } free(callback); @@ -347,7 +366,7 @@ rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle, /* all callbacks for that source are removed. */ if (TAILQ_EMPTY(&src->callbacks)) { TAILQ_REMOVE(&intr_sources, src, next); - free(src); + eal_intr_source_free(src); } } out: @@ -592,7 +611,7 @@ eal_intr_process_interrupts(struct kevent *events, int nfds) /* all callbacks for that source are removed. */ if (TAILQ_EMPTY(&src->callbacks)) { TAILQ_REMOVE(&intr_sources, src, next); - free(src); + eal_intr_source_free(src); } rte_spinlock_unlock(&intr_lock); -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v4 7/8] bus/pci: fix leaked device FD warning on VFIO unmap 2026-10-23 13:51 ` [PATCH v4 1/8] interrupts: fix size of duplicated instance Anatoly Burakov ` (4 preceding siblings ...) 2026-10-23 13:51 ` [PATCH v4 6/8] eal/freebsd: fix interrupt source handle leak Anatoly Burakov @ 2026-10-23 13:51 ` Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 8/8] interrupts: warn on leaked event FDs Anatoly Burakov 6 siblings, 0 replies; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:51 UTC (permalink / raw) To: dev, Chenbo Xia, Nipun Gupta, David Marchand, Thomas Monjalon When unmapping a VFIO device, the interrupt handle FD is closed but the reference to the VFIO device FD is left in the handle. The device FD is owned by the VFIO layer and released separately, so freeing the handle later reports it as leaked. Clear the reference once the device FD has been retrieved, as is already done for the request notifier handle. Fixes: d770ee9caed0 ("interrupts: warn on leaked FDs") Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- drivers/bus/pci/linux/pci_vfio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c index fb35bc1d491..62a7a85f6ed 100644 --- a/drivers/bus/pci/linux/pci_vfio.c +++ b/drivers/bus/pci/linux/pci_vfio.c @@ -1103,6 +1103,8 @@ pci_vfio_unmap_resource_primary(struct rte_pci_device *dev) PCI_LOG(ERR, "Cannot release VFIO device"); return ret; } + /* vfio_dev_fd is managed by VFIO layer, only clear reference here. */ + rte_intr_dev_fd_set(dev->intr_handle, -1); vfio_res_list = RTE_TAILQ_CAST(dev_vfio_tailq.head, mapped_pci_res_list); @@ -1142,6 +1144,8 @@ pci_vfio_unmap_resource_secondary(struct rte_pci_device *dev) PCI_LOG(ERR, "Cannot release VFIO device"); return ret; } + /* vfio_dev_fd is managed by VFIO layer, only clear reference here. */ + rte_intr_dev_fd_set(dev->intr_handle, -1); vfio_res_list = RTE_TAILQ_CAST(dev_vfio_tailq.head, mapped_pci_res_list); -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v4 8/8] interrupts: warn on leaked event FDs 2026-10-23 13:51 ` [PATCH v4 1/8] interrupts: fix size of duplicated instance Anatoly Burakov ` (5 preceding siblings ...) 2026-10-23 13:51 ` [PATCH v4 7/8] bus/pci: fix leaked device FD warning on VFIO unmap Anatoly Burakov @ 2026-10-23 13:51 ` Anatoly Burakov 2026-10-23 14:41 ` David Marchand 6 siblings, 1 reply; 33+ messages in thread From: Anatoly Burakov @ 2026-10-23 13:51 UTC (permalink / raw) To: dev, Harman Kalra Extend the leak warning in rte_intr_instance_free() to the event FD array, in the same way as the handle FD and device FD. rte_intr_efd_disable() used to close the eventfds it owns but left the stale descriptors in the array, and never cleared the entry that merely references the handle FD in the non-MSI-X case. Reset all entries in use to -1 so a properly disabled handle is not reported. Drivers filling the event FD array themselves are expected to reset the entries once the descriptors are closed or no longer referenced. Suggested-by: David Marchand <david.marchand@redhat.com> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> --- lib/eal/common/eal_common_interrupts.c | 5 +++++ lib/eal/include/rte_interrupts.h | 7 ++++++- lib/eal/linux/eal_interrupts.c | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/eal/common/eal_common_interrupts.c b/lib/eal/common/eal_common_interrupts.c index cf56f967218..fa0e0ab961d 100644 --- a/lib/eal/common/eal_common_interrupts.c +++ b/lib/eal/common/eal_common_interrupts.c @@ -201,6 +201,11 @@ void rte_intr_instance_free(struct rte_intr_handle *intr_handle) if (rte_intr_dev_fd_get(intr_handle) >= 0) EAL_LOG(NOTICE, "Some interrupt handle is leaking a device FD: %d", rte_intr_dev_fd_get(intr_handle)); + for (int i = 0; i < intr_handle->nb_intr; i++) { + if (intr_handle->efds[i] >= 0) + EAL_LOG(NOTICE, "Some interrupt handle is leaking an event FD: %d (index %d)", + intr_handle->efds[i], i); + } if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags)) { rte_free(intr_handle->efds); rte_free(intr_handle->elist); diff --git a/lib/eal/include/rte_interrupts.h b/lib/eal/include/rte_interrupts.h index d04c0c7b15f..3aeac9092ae 100644 --- a/lib/eal/include/rte_interrupts.h +++ b/lib/eal/include/rte_interrupts.h @@ -389,6 +389,7 @@ rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd); * @internal * It disables the packet I/O interrupt event. * It deletes registered eventfds and closes the open fds. + * All event fd entries in use are reset to -1. * * @param intr_handle * Pointer to the interrupt handle. @@ -620,12 +621,16 @@ rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle); * @internal * Set the event fd array index with the given fd. * + * Entries still holding a valid fd when the instance is freed are reported + * as leaks, so callers managing the array themselves must reset entries + * to -1 once the fd is closed or no longer referenced. + * * @param intr_handle * pointer to the interrupt handle. * @param index * efds array index to be set * @param fd - * event fd + * event fd, or -1 to clear the entry * * @return * - On success, zero. diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c index aadb7b84a22..f6f51ba53c0 100644 --- a/lib/eal/linux/eal_interrupts.c +++ b/lib/eal/linux/eal_interrupts.c @@ -1667,6 +1667,8 @@ rte_intr_efd_disable(struct rte_intr_handle *intr_handle) for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) close(rte_intr_efds_index_get(intr_handle, i)); } + for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) + rte_intr_efds_index_set(intr_handle, i, -1); rte_intr_nb_efd_set(intr_handle, 0); rte_intr_max_intr_set(intr_handle, 0); } -- 2.52.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: [PATCH v4 8/8] interrupts: warn on leaked event FDs 2026-10-23 13:51 ` [PATCH v4 8/8] interrupts: warn on leaked event FDs Anatoly Burakov @ 2026-10-23 14:41 ` David Marchand 2026-10-23 14:48 ` Burakov, Anatoly 0 siblings, 1 reply; 33+ messages in thread From: David Marchand @ 2026-10-23 14:41 UTC (permalink / raw) To: Anatoly Burakov; +Cc: dev, Harman Kalra On Fri, 23 Oct 2026 at 15:52, Anatoly Burakov <anatoly.burakov@intel.com> wrote: > diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c > index aadb7b84a22..f6f51ba53c0 100644 > --- a/lib/eal/linux/eal_interrupts.c > +++ b/lib/eal/linux/eal_interrupts.c > @@ -1667,6 +1667,8 @@ rte_intr_efd_disable(struct rte_intr_handle *intr_handle) > for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) > close(rte_intr_efds_index_get(intr_handle, i)); > } > + for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) > + rte_intr_efds_index_set(intr_handle, i, -1); We don't want to waive for types != VFIO_MSIX, do we? > rte_intr_nb_efd_set(intr_handle, 0); > rte_intr_max_intr_set(intr_handle, 0); > } The rest lgtm. -- David Marchand ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v4 8/8] interrupts: warn on leaked event FDs 2026-10-23 14:41 ` David Marchand @ 2026-10-23 14:48 ` Burakov, Anatoly 2026-10-24 8:56 ` David Marchand 0 siblings, 1 reply; 33+ messages in thread From: Burakov, Anatoly @ 2026-10-23 14:48 UTC (permalink / raw) To: David Marchand; +Cc: dev, Harman Kalra On 10/23/2026 4:41 PM, David Marchand wrote: > On Fri, 23 Oct 2026 at 15:52, Anatoly Burakov <anatoly.burakov@intel.com> wrote: >> diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c >> index aadb7b84a22..f6f51ba53c0 100644 >> --- a/lib/eal/linux/eal_interrupts.c >> +++ b/lib/eal/linux/eal_interrupts.c >> @@ -1667,6 +1667,8 @@ rte_intr_efd_disable(struct rte_intr_handle *intr_handle) >> for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) >> close(rte_intr_efds_index_get(intr_handle, i)); >> } >> + for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) >> + rte_intr_efds_index_set(intr_handle, i, -1); > > We don't want to waive for types != VFIO_MSIX, do we? > Looking into this further, I suspectwe want to check for != VDEV instead. All handle types except VDEV will write into the handle. > >> rte_intr_nb_efd_set(intr_handle, 0); >> rte_intr_max_intr_set(intr_handle, 0); >> } > > The rest lgtm. > > -- Thanks, Anatoly ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v4 8/8] interrupts: warn on leaked event FDs 2026-10-23 14:48 ` Burakov, Anatoly @ 2026-10-24 8:56 ` David Marchand 2026-10-24 9:57 ` Burakov, Anatoly 0 siblings, 1 reply; 33+ messages in thread From: David Marchand @ 2026-10-24 8:56 UTC (permalink / raw) To: Burakov, Anatoly; +Cc: dev, Harman Kalra On Fri, 23 Oct 2026 at 16:48, Burakov, Anatoly <anatoly.burakov@intel.com> wrote: > > On 10/23/2026 4:41 PM, David Marchand wrote: > > On Fri, 23 Oct 2026 at 15:52, Anatoly Burakov <anatoly.burakov@intel.com> wrote: > >> diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c > >> index aadb7b84a22..f6f51ba53c0 100644 > >> --- a/lib/eal/linux/eal_interrupts.c > >> +++ b/lib/eal/linux/eal_interrupts.c > >> @@ -1667,6 +1667,8 @@ rte_intr_efd_disable(struct rte_intr_handle *intr_handle) > >> for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) > >> close(rte_intr_efds_index_get(intr_handle, i)); > >> } > >> + for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) > >> + rte_intr_efds_index_set(intr_handle, i, -1); > > > > We don't want to waive for types != VFIO_MSIX, do we? > > > > Looking into this further, I suspectwe want to check for != VDEV > instead. All handle types except VDEV will write into the handle. Indeed, I had misunderstood rte_intr_efd_enable... Ok, I'll respin those patches as part of my series and let the whole set of changes go through CI. -- David Marchand ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v4 8/8] interrupts: warn on leaked event FDs 2026-10-24 8:56 ` David Marchand @ 2026-10-24 9:57 ` Burakov, Anatoly 0 siblings, 0 replies; 33+ messages in thread From: Burakov, Anatoly @ 2026-10-24 9:57 UTC (permalink / raw) To: David Marchand; +Cc: dev, Harman Kalra On 10/24/2026 10:56 AM, David Marchand wrote: > On Fri, 23 Oct 2026 at 16:48, Burakov, Anatoly > <anatoly.burakov@intel.com> wrote: >> >> On 10/23/2026 4:41 PM, David Marchand wrote: >>> On Fri, 23 Oct 2026 at 15:52, Anatoly Burakov <anatoly.burakov@intel.com> wrote: >>>> diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c >>>> index aadb7b84a22..f6f51ba53c0 100644 >>>> --- a/lib/eal/linux/eal_interrupts.c >>>> +++ b/lib/eal/linux/eal_interrupts.c >>>> @@ -1667,6 +1667,8 @@ rte_intr_efd_disable(struct rte_intr_handle *intr_handle) >>>> for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) >>>> close(rte_intr_efds_index_get(intr_handle, i)); >>>> } >>>> + for (i = 0; i < (uint32_t)rte_intr_nb_efd_get(intr_handle); i++) >>>> + rte_intr_efds_index_set(intr_handle, i, -1); >>> >>> We don't want to waive for types != VFIO_MSIX, do we? >>> >> >> Looking into this further, I suspectwe want to check for != VDEV >> instead. All handle types except VDEV will write into the handle. > > Indeed, I had misunderstood rte_intr_efd_enable... > Ok, I'll respin those patches as part of my series and let the whole > set of changes go through CI. > > Yes, the efd name is confusing because not all handles created by our interrupt subsystem are efd -- Thanks, Anatoly ^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2026-10-24 9:58 UTC | newest] Thread overview: 33+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-23 9:36 [PATCH v1 1/1] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov 2026-10-23 11:42 ` David Marchand 2026-10-23 12:25 ` Burakov, Anatoly 2026-10-23 13:07 ` [PATCH v2 1/3] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov 2026-10-23 13:07 ` [PATCH v2 2/3] interrupts: warn on leaked event FDs Anatoly Burakov 2026-10-23 13:07 ` [PATCH v2 3/3] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 1/8] interrupts: fix size of duplicated instance Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 2/8] interrupts: fix event arrays copy on instance duplication Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 3/8] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 4/8] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 5/8] eal/linux: fix leaked FD warnings for interrupt sources Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 6/8] eal/freebsd: fix interrupt source handle leak Anatoly Burakov 2026-10-23 13:39 ` [PATCH v3 7/8] bus/pci: fix leaked device FD warning on VFIO unmap Anatoly Burakov 2026-10-23 13:49 ` Burakov, Anatoly 2026-10-23 13:39 ` [PATCH v3 8/8] interrupts: warn on leaked event FDs Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 1/8] interrupts: fix size of duplicated instance Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 2/8] interrupts: fix event arrays copy on instance duplication Anatoly Burakov 2026-10-23 14:15 ` David Marchand 2026-10-23 14:36 ` Burakov, Anatoly 2026-10-23 14:44 ` David Marchand 2026-10-23 14:55 ` Burakov, Anatoly 2026-10-23 13:51 ` [PATCH v4 3/8] eal/linux: fix closing of event FDs not owned by EAL Anatoly Burakov 2026-10-23 14:17 ` David Marchand 2026-10-23 13:51 ` [PATCH v4 4/8] eal/linux: fix eventfd leaks when enabling interrupts Anatoly Burakov 2026-10-23 14:37 ` David Marchand 2026-10-23 13:51 ` [PATCH v4 5/8] eal/linux: fix leaked FD warnings for interrupt sources Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 6/8] eal/freebsd: fix interrupt source handle leak Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 7/8] bus/pci: fix leaked device FD warning on VFIO unmap Anatoly Burakov 2026-10-23 13:51 ` [PATCH v4 8/8] interrupts: warn on leaked event FDs Anatoly Burakov 2026-10-23 14:41 ` David Marchand 2026-10-23 14:48 ` Burakov, Anatoly 2026-10-24 8:56 ` David Marchand 2026-10-24 9:57 ` Burakov, Anatoly
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox