eal/linux: allow multiple starts of event monitor
In some cases, a device or infrastructure may want to enable hotplug but application may also try and start hotplug as well. Therefore change the monitor_started from a boolean into a reference count. Signed-off-by: Long Li <longli@microsoft.com>
This commit is contained in:
parent
acdabc450e
commit
1fef6ced07
@ -23,8 +23,12 @@
|
|||||||
|
|
||||||
#include "eal_private.h"
|
#include "eal_private.h"
|
||||||
|
|
||||||
static struct rte_intr_handle intr_handle = {.fd = -1 };
|
static struct rte_intr_handle intr_handle = {
|
||||||
static bool monitor_started;
|
.type = RTE_INTR_HANDLE_DEV_EVENT,
|
||||||
|
.fd = -1,
|
||||||
|
};
|
||||||
|
static rte_rwlock_t monitor_lock = RTE_RWLOCK_INITIALIZER;
|
||||||
|
static uint32_t monitor_refcount;
|
||||||
static bool hotplug_handle;
|
static bool hotplug_handle;
|
||||||
|
|
||||||
#define EAL_UEV_MSG_LEN 4096
|
#define EAL_UEV_MSG_LEN 4096
|
||||||
@ -298,50 +302,70 @@ failure_handle_err:
|
|||||||
int
|
int
|
||||||
rte_dev_event_monitor_start(void)
|
rte_dev_event_monitor_start(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
if (monitor_started)
|
rte_rwlock_write_lock(&monitor_lock);
|
||||||
return 0;
|
|
||||||
|
if (monitor_refcount) {
|
||||||
|
monitor_refcount++;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
ret = dev_uev_socket_fd_create();
|
ret = dev_uev_socket_fd_create();
|
||||||
if (ret) {
|
if (ret) {
|
||||||
RTE_LOG(ERR, EAL, "error create device event fd.\n");
|
RTE_LOG(ERR, EAL, "error create device event fd.\n");
|
||||||
return -1;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
intr_handle.type = RTE_INTR_HANDLE_DEV_EVENT;
|
|
||||||
ret = rte_intr_callback_register(&intr_handle, dev_uev_handler, NULL);
|
ret = rte_intr_callback_register(&intr_handle, dev_uev_handler, NULL);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
RTE_LOG(ERR, EAL, "fail to register uevent callback.\n");
|
RTE_LOG(ERR, EAL, "fail to register uevent callback.\n");
|
||||||
return -1;
|
close(intr_handle.fd);
|
||||||
|
intr_handle.fd = -1;
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor_started = true;
|
monitor_refcount++;
|
||||||
|
|
||||||
return 0;
|
exit:
|
||||||
|
rte_rwlock_write_unlock(&monitor_lock);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rte_dev_event_monitor_stop(void)
|
rte_dev_event_monitor_stop(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
if (!monitor_started)
|
rte_rwlock_write_lock(&monitor_lock);
|
||||||
return 0;
|
|
||||||
|
if (!monitor_refcount) {
|
||||||
|
RTE_LOG(ERR, EAL, "device event monitor already stopped\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitor_refcount > 1) {
|
||||||
|
monitor_refcount--;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
ret = rte_intr_callback_unregister(&intr_handle, dev_uev_handler,
|
ret = rte_intr_callback_unregister(&intr_handle, dev_uev_handler,
|
||||||
(void *)-1);
|
(void *)-1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
RTE_LOG(ERR, EAL, "fail to unregister uevent callback.\n");
|
RTE_LOG(ERR, EAL, "fail to unregister uevent callback.\n");
|
||||||
return ret;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(intr_handle.fd);
|
close(intr_handle.fd);
|
||||||
intr_handle.fd = -1;
|
intr_handle.fd = -1;
|
||||||
monitor_started = false;
|
|
||||||
|
|
||||||
return 0;
|
monitor_refcount--;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
rte_rwlock_write_unlock(&monitor_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user