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:
parent
edf20bd8a5
commit
2e761ce184
@ -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) {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user