event: wait to shut down subsystems if scheduling in progress

We want to avoid an active for_each_reactor operation
while the reactors are being shut down.

Fixes issue #1766

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I30bc258c5b22545320080d269a1ed8cb0b4e12f2
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6104
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Maciej Szwed <maciej.szwed@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Jim Harris 2021-01-26 14:01:13 +00:00 committed by Tomasz Zawadzki
parent 8b203d1994
commit 7665710cd4
4 changed files with 36 additions and 2 deletions

View File

@ -125,6 +125,8 @@ void spdk_reactors_stop(void *arg1);
struct spdk_reactor *spdk_reactor_get(uint32_t lcore);
struct spdk_reactor *_spdk_get_scheduling_reactor(void);
/**
* Allocate and pass an event to each reactor, serially.
*
@ -378,6 +380,11 @@ struct spdk_scheduler *_spdk_scheduler_get(void);
*/
void _spdk_scheduler_period_set(uint64_t period);
/**
* Disable the scheduler.
*/
void _spdk_scheduler_disable(void);
/**
* Get period of currently set scheduler.
*/

View File

@ -593,6 +593,17 @@ spdk_app_fini(void)
spdk_log_close();
}
static void
_start_subsystem_fini(void *arg1)
{
if (_spdk_get_scheduling_reactor()->flags.is_scheduling) {
spdk_thread_send_msg(g_app_thread, _start_subsystem_fini, NULL);
return;
}
spdk_subsystem_fini(spdk_reactors_stop, NULL);
}
static void
app_stop(void *arg1)
{
@ -606,8 +617,9 @@ app_stop(void *arg1)
}
spdk_rpc_finish();
spdk_subsystem_fini(spdk_reactors_stop, NULL);
g_spdk_app.stopped = true;
_spdk_scheduler_disable();
_start_subsystem_fini(NULL);
}
void

View File

@ -153,6 +153,12 @@ _spdk_scheduler_period_set(uint64_t period)
g_scheduler_period = period * spdk_get_ticks_hz() / SPDK_SEC_TO_USEC;
}
void
_spdk_scheduler_disable(void)
{
g_scheduler_period = 0;
}
void
_spdk_scheduler_list_add(struct spdk_scheduler *scheduler)
{
@ -227,6 +233,12 @@ spdk_reactor_get(uint32_t lcore)
return reactor;
}
struct spdk_reactor *
_spdk_get_scheduling_reactor(void)
{
return g_scheduling_reactor;
}
static int reactor_thread_op(struct spdk_thread *thread, enum spdk_thread_op op);
static bool reactor_thread_op_supported(enum spdk_thread_op op);
@ -918,7 +930,8 @@ reactor_run(void *arg)
_reactor_run(reactor);
}
if (spdk_unlikely((reactor->tsc_last - last_sched) > g_scheduler_period &&
if (spdk_unlikely(g_scheduler_period > 0 &&
(reactor->tsc_last - last_sched) > g_scheduler_period &&
reactor == g_scheduling_reactor &&
!reactor->flags.is_scheduling)) {
if (spdk_unlikely(g_scheduler != g_new_scheduler)) {

View File

@ -57,6 +57,8 @@ DEFINE_STUB_V(spdk_reactors_start, (void));
DEFINE_STUB_V(spdk_reactors_stop, (void *arg1));
DEFINE_STUB(spdk_reactors_init, int, (void), 0);
DEFINE_STUB_V(spdk_reactors_fini, (void));
DEFINE_STUB_V(_spdk_scheduler_disable, (void));
DEFINE_STUB(_spdk_get_scheduling_reactor, struct spdk_reactor *, (void), NULL);
static void
unittest_usage(void)