[PATCH v1 1/1] eal/linux: fix eventfd leaks when enabling interrupts
Burakov, Anatoly
anatoly.burakov at intel.com
Fri Oct 23 14:25:46 CEST 2026
On 10/23/2026 1:42 PM, David Marchand wrote:
> Hello,
>
> On Fri, 23 Oct 2026 at 11:37, Anatoly Burakov <anatoly.burakov at 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 at dpdk.org
>>
>> Signed-off-by: Anatoly Burakov <anatoly.burakov at 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
More information about the dev
mailing list