[dpdk-stable] patch 'eal/linux: handle UIO read failure in interrupt handler' has been queued to LTS release 16.11.9

Luca Boccassi bluca at debian.org
Thu Nov 8 19:00:58 CET 2018


Hi,

FYI, your patch has been queued to LTS release 16.11.9

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 11/10/18. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the patch applied
to the branch. If the code is different (ie: not only metadata diffs), due for example to
a change in context or macro names, please double check it.

Thanks.

Luca Boccassi

---
>From e8861c76c1613cb7eb785ff9b23e80f617f6994b Mon Sep 17 00:00:00 2001
From: Luca Boccassi <bluca at debian.org>
Date: Wed, 31 Oct 2018 18:39:45 +0000
Subject: [PATCH] eal/linux: handle UIO read failure in interrupt handler

[ upstream commit 349ac52bbc5264d774c7e28c62c4e3941055b9c4 ]

If a device is unplugged while an interrupt is pending, the
read call to the uio device to remove it from the poll wait list
can fail resulting in it being continually polled forever. This
change checks for the read failing and if so, unregisters the device
as an interrupt source and causes the wait list to be rebuilt.

This race has been reported and observed in production.

Fixes: 0a45657a6794 ("pci: rework interrupt handling")

Signed-off-by: Brian Russell <brussell at brocade.com>
Signed-off-by: Luca Boccassi <bluca at debian.org>
---
 lib/librte_eal/linuxapp/eal/eal_interrupts.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 7f739140a..cce69285b 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);
-- 
2.19.1

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2018-11-08 17:59:30.105047182 +0000
+++ 0002-eal-linux-handle-UIO-read-failure-in-interrupt-handl.patch	2018-11-08 17:59:30.044751011 +0000
@@ -1,8 +1,10 @@
-From 349ac52bbc5264d774c7e28c62c4e3941055b9c4 Mon Sep 17 00:00:00 2001
+From e8861c76c1613cb7eb785ff9b23e80f617f6994b Mon Sep 17 00:00:00 2001
 From: Luca Boccassi <bluca at debian.org>
 Date: Wed, 31 Oct 2018 18:39:45 +0000
 Subject: [PATCH] eal/linux: handle UIO read failure in interrupt handler
 
+[ upstream commit 349ac52bbc5264d774c7e28c62c4e3941055b9c4 ]
+
 If a device is unplugged while an interrupt is pending, the
 read call to the uio device to remove it from the poll wait list
 can fail resulting in it being continually polled forever. This
@@ -12,7 +14,6 @@
 This race has been reported and observed in production.
 
 Fixes: 0a45657a6794 ("pci: rework interrupt handling")
-Cc: stable at dpdk.org
 
 Signed-off-by: Brian Russell <brussell at brocade.com>
 Signed-off-by: Luca Boccassi <bluca at debian.org>
@@ -21,11 +22,11 @@
  1 file changed, 18 insertions(+), 1 deletion(-)
 
 diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
-index 39252a887..cbac451e1 100644
+index 7f739140a..cce69285b 100644
 --- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
 +++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
-@@ -700,7 +700,7 @@ eal_intr_process_interrupts(struct epoll_event *events, int nfds)
- 	bool call = false;
+@@ -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;
@@ -33,7 +34,7 @@
  	union rte_intr_read_buffer buf;
  	struct rte_intr_callback active_cb;
  
-@@ -780,6 +780,23 @@ eal_intr_process_interrupts(struct epoll_event *events, int nfds)
+@@ -713,6 +713,23 @@ eal_intr_process_interrupts(struct epoll_event *events, int nfds)
  					"descriptor %d: %s\n",
  					events[n].data.fd,
  					strerror(errno));


More information about the stable mailing list