eal: add synchronous interrupt unregister

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

Signed-off-by: Renata Saiakhova <renata.saiakhova@ekinops.com>
Acked-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Harman Kalra <hkalra@marvell.com>
This commit is contained in:
Renata Saiakhova 2021-04-06 16:46:14 +02:00 committed by David Marchand
parent edf20bd8a5
commit 2e761ce184
7 changed files with 60 additions and 1 deletions

View File

@ -409,7 +409,7 @@ pci_vfio_disable_notifier(struct rte_pci_device *dev)
return -1;
}
ret = rte_intr_callback_unregister(&dev->vfio_req_intr_handle,
ret = rte_intr_callback_unregister_sync(&dev->vfio_req_intr_handle,
pci_vfio_req_handler,
(void *)&dev->device);
if (ret < 0) {

View File

@ -345,6 +345,18 @@ rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
return ret;
}
int
rte_intr_callback_unregister_sync(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)
{

View File

@ -94,6 +94,31 @@ rte_intr_callback_unregister_pending(const struct rte_intr_handle *intr_handle,
rte_intr_callback_fn cb_fn, void *cb_arg,
rte_intr_unregister_callback_fn ucb_fn);
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice
*
* Loop until rte_intr_callback_unregister() succeeds.
* After a call to this function,
* the callback provided by the specified interrupt handle is unregistered.
*
* @param intr_handle
* pointer to the interrupt handle.
* @param cb
* callback address.
* @param cb_arg
* address of parameter for callback, (void *)-1 means to remove all
* registered which has the same callback address.
*
* @return
* - On success, return the number of callback entities removed.
* - On failure, a negative value.
*/
__rte_experimental
int
rte_intr_callback_unregister_sync(const struct rte_intr_handle *intr_handle,
rte_intr_callback_fn cb, void *cb_arg);
/**
* It enables the interrupt for the specified handle.
*

View File

@ -662,6 +662,18 @@ rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
return ret;
}
int
rte_intr_callback_unregister_sync(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)
{

View File

@ -325,6 +325,7 @@ EXPORTS
rte_vect_get_max_simd_bitwidth
rte_vect_set_max_simd_bitwidth
rte_intr_callback_unregister_sync
rte_thread_key_create
rte_thread_key_delete
rte_thread_value_get

View File

@ -411,6 +411,7 @@ EXPERIMENTAL {
rte_power_pause;
# added in 21.05
rte_intr_callback_unregister_sync;
rte_thread_key_create;
rte_thread_key_delete;
rte_thread_value_get;

View File

@ -131,6 +131,14 @@ rte_intr_callback_unregister(
return 0;
}
int
rte_intr_callback_unregister_sync(
__rte_unused const struct rte_intr_handle *intr_handle,
__rte_unused rte_intr_callback_fn cb_fn, __rte_unused void *cb_arg)
{
return 0;
}
int
rte_intr_enable(__rte_unused const struct rte_intr_handle *intr_handle)
{