Hello Kevin, On Fri, 6 Feb 2026 at 18:21, Kevin Traynor <[email protected]> wrote: > > Add handling for epoll error and disconnect conditions EPOLLERR, > EPOLLHUP and EPOLLRDHUP. > > These events indicate that the interrupt file descriptor is in > an error state or there has been a hangup. > > Only do this for interrupts that are read in eal. Interrupts that > are read outside eal should deal with different interrupt scenarios > appropriate to their functionality. e.g. virtio interrupt handling > has reconnect mechanisms for some cases. > > Also, treat no bytes read as an error condition. > > Bugzilla ID: 1873 > Fixes: af75078fece3 ("first public release") > Cc: [email protected]
Cc: Harman. > > Signed-off-by: Kevin Traynor <[email protected]> > --- > lib/eal/linux/eal_interrupts.c | 67 ++++++++++++++++++++++------------ > 1 file changed, 44 insertions(+), 23 deletions(-) > > diff --git a/lib/eal/linux/eal_interrupts.c b/lib/eal/linux/eal_interrupts.c > index 9db978923a..68ca0f929e 100644 > --- a/lib/eal/linux/eal_interrupts.c > +++ b/lib/eal/linux/eal_interrupts.c > @@ -887,4 +887,26 @@ rte_intr_disable(const struct rte_intr_handle > *intr_handle) > } > > +static void > +eal_intr_source_remove_and_free(struct rte_intr_source *src) > +{ > + struct rte_intr_callback *cb, *next; > + > + /* Remove the interrupt source */ > + rte_spinlock_lock(&intr_lock); > + TAILQ_REMOVE(&intr_sources, src, next); > + rte_spinlock_unlock(&intr_lock); > + > + /* Free callbacks */ > + for (cb = TAILQ_FIRST(&src->callbacks); cb; cb = next) { > + next = TAILQ_NEXT(cb, next); > + TAILQ_REMOVE(&src->callbacks, cb, next); > + free(cb); > + } > + > + /* Free the interrupt source */ > + rte_intr_instance_free(src->intr_handle); > + free(src); > +} > + > static int > eal_intr_process_interrupts(struct epoll_event *events, int nfds) > @@ -952,4 +974,16 @@ eal_intr_process_interrupts(struct epoll_event *events, > int nfds) > > if (bytes_read > 0) { > + /** > + * Check for epoll error or disconnect events for > + * interrupts that are read directly in eal. > + */ > + if (events[n].events & (EPOLLERR | EPOLLHUP | > EPOLLRDHUP)) { > + EAL_LOG(INFO, "Disconnect condition on fd %d " This is an anormal situation, I would make this log level the same as other logs below. The fact that the interrupt fd gets into this state should be something to report and investigate. > + "(events=0x%x), removing from epoll", > + events[n].data.fd, events[n].events); > + eal_intr_source_remove_and_free(src); > + return -1; > + } > + > /** > * read out to clear the ready-to-be-read flag > @@ -957,5 +991,7 @@ eal_intr_process_interrupts(struct epoll_event *events, > int nfds) > */ > bytes_read = read(events[n].data.fd, &buf, > bytes_read); > - if (bytes_read < 0) { > + if (bytes_read > 0) { > + call = true; > + } else if (bytes_read < 0) { > if (errno == EINTR || errno == EWOULDBLOCK) > continue; > @@ -965,27 +1001,12 @@ eal_intr_process_interrupts(struct epoll_event > *events, int nfds) > events[n].data.fd, > strerror(errno)); > - /* > - * The device is unplugged or buggy, remove > - * it as an interrupt source and return to > - * force the wait list to be rebuilt. > - */ > - rte_spinlock_lock(&intr_lock); > - TAILQ_REMOVE(&intr_sources, src, next); > - rte_spinlock_unlock(&intr_lock); > - > - for (cb = TAILQ_FIRST(&src->callbacks); cb; > - cb = next) { > - next = TAILQ_NEXT(cb, next); > - TAILQ_REMOVE(&src->callbacks, cb, > next); > - free(cb); > - } > - rte_intr_instance_free(src->intr_handle); > - free(src); > - return -1; > - } else if (bytes_read == 0) > - EAL_LOG(ERR, "Read nothing from file " > + } else { /* bytes == 0 */ "bytes_read == 0", or remove this comment as the code is quite compact and leaves little space for wondering what this else block is about. > + EAL_LOG(WARNING, "Read nothing from file " I would keep this log at the same level than the < 0 condition. It seems the same type of error. > "descriptor %d", events[n].data.fd); And avoid splitting the format string. > - else > - call = true; > + } > + if (bytes_read <= 0) { > + eal_intr_source_remove_and_free(src); > + return -1; > + } > } > > -- > 2.52.0 > Except those nits, the fix looks correct. Acked-by: David Marchand <[email protected]> -- David Marchand

