Merge tag 'upstream/16.11.9' into 16.11.x
[deb_dpdk.git] / lib / librte_eal / linuxapp / eal / eal_interrupts.c
index 7f73914..cce6928 100644 (file)
@@ -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);