Avoid race with unregister interrupt hanlder if interrupt
source has some active callbacks at the moment, use wrapper
around rte_intr_callback_unregister() to check for -EAGAIN
return value.

Signed-off-by: Renata Saiakhova <[email protected]>
---
 lib/librte_eal/freebsd/eal_interrupts.c | 16 ++++++++++++++--
 lib/librte_eal/linux/eal_interrupts.c   | 16 ++++++++++++++--
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/lib/librte_eal/freebsd/eal_interrupts.c 
b/lib/librte_eal/freebsd/eal_interrupts.c
index 6d53d33c8..a92a7a025 100644
--- a/lib/librte_eal/freebsd/eal_interrupts.c
+++ b/lib/librte_eal/freebsd/eal_interrupts.c
@@ -259,8 +259,8 @@ rte_intr_callback_unregister_pending(const struct 
rte_intr_handle *intr_handle,
        return ret;
 }
 
-int
-rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
+static int
+__rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
                rte_intr_callback_fn cb_fn, void *cb_arg)
 {
        int ret;
@@ -345,6 +345,18 @@ rte_intr_callback_unregister(const struct rte_intr_handle 
*intr_handle,
        return ret;
 }
 
+int
+rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
+               rte_intr_callback_fn cb_fn, void *cb_arg)
+{
+       int ret = 0;
+
+       while ((ret = __rte_intr_callback_unregister(intr_handle, cb_fn, 
cb_arg)) == -EAGAIN)
+               rte_pause();
+
+       return ret;
+}
+
 int
 rte_intr_enable(const struct rte_intr_handle *intr_handle)
 {
diff --git a/lib/librte_eal/linux/eal_interrupts.c 
b/lib/librte_eal/linux/eal_interrupts.c
index 13db5c4e8..d5dcfc36b 100644
--- a/lib/librte_eal/linux/eal_interrupts.c
+++ b/lib/librte_eal/linux/eal_interrupts.c
@@ -596,8 +596,8 @@ rte_intr_callback_unregister_pending(const struct 
rte_intr_handle *intr_handle,
        return ret;
 }
 
-int
-rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
+static int
+__rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
                        rte_intr_callback_fn cb_fn, void *cb_arg)
 {
        int ret;
@@ -662,6 +662,18 @@ rte_intr_callback_unregister(const struct rte_intr_handle 
*intr_handle,
        return ret;
 }
 
+int
+rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
+                       rte_intr_callback_fn cb_fn, void *cb_arg)
+{
+       int ret = 0;
+
+       while ((ret = __rte_intr_callback_unregister(intr_handle, cb_fn, 
cb_arg)) == -EAGAIN)
+               rte_pause();
+
+       return ret;
+}
+
 int
 rte_intr_enable(const struct rte_intr_handle *intr_handle)
 {
-- 
2.17.2

Reply via email to