summaryrefslogtreecommitdiffstats
path: root/lib/librte_eal/linuxapp/eal/eal_interrupts.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/librte_eal/linuxapp/eal/eal_interrupts.c')
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_interrupts.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 7f739140..cce69285 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -647,7 +647,7 @@ eal_intr_process_interrupts(struct epoll_event *events, int nfds)
{
int n, bytes_read;
struct rte_intr_source *src;
- struct rte_intr_callback *cb;
+ struct rte_intr_callback *cb, *next;
union rte_intr_read_buffer buf;
struct rte_intr_callback active_cb;
@@ -713,6 +713,23 @@ eal_intr_process_interrupts(struct epoll_event *events, int nfds)
"descriptor %d: %s\n",
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);
+ }
+ free(src);
+ return -1;
} else if (bytes_read == 0)
RTE_LOG(ERR, EAL, "Read nothing from file "
"descriptor %d\n", events[n].data.fd);