bdev: Fix bug where cpl on finish is called early

The process of spdk_bdev_finish will always result in an
early call to the user's completion notification - prior
to the actual shutdown events happening.

Change-Id: Ib53393deb794b616d2b7ec94cb41502305bd99b7
Reviewed-on: https://review.gerrithub.io/386707
Reviewed-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Ben Walker 2017-11-10 11:16:51 -07:00 committed by Daniel Verkamp
parent 6447eb670a
commit eb8571d463

View File

@ -100,7 +100,6 @@ static void *g_init_cb_arg = NULL;
static spdk_bdev_fini_cb g_fini_cb_fn = NULL;
static void *g_fini_cb_arg = NULL;
struct spdk_bdev_module_if *g_bdev_module = NULL;
struct spdk_thread *g_fini_thread = NULL;
@ -606,37 +605,52 @@ spdk_bdev_module_finish_complete(void)
}
static void
_call_next_module_fini(void *arg)
spdk_bdev_module_finish_iter(void *arg)
{
struct spdk_bdev_module_if *module = arg;
/* Notice that this variable is static. It is saved between calls to
* this function. */
static struct spdk_bdev_module_if *resume_bdev_module = NULL;
struct spdk_bdev_module_if *bdev_module;
module->module_fini();
/* Start iterating from the last touched module */
if (!resume_bdev_module) {
bdev_module = TAILQ_FIRST(&g_bdev_mgr.bdev_modules);
} else {
bdev_module = TAILQ_NEXT(resume_bdev_module, tailq);
}
while (bdev_module) {
if (bdev_module->async_fini) {
/* Save our place so we can resume later. We must
* save the variable here, before calling module_fini()
* below, because in some cases the module may immediately
* call spdk_bdev_module_finish_done() and re-enter
* this function to continue iterating. */
resume_bdev_module = bdev_module;
}
if (bdev_module->module_fini) {
bdev_module->module_fini();
}
if (bdev_module->async_fini) {
return;
}
bdev_module = TAILQ_NEXT(bdev_module, tailq);
}
resume_bdev_module = NULL;
spdk_bdev_module_finish_complete();
}
void
spdk_bdev_module_finish_done(void)
{
if (spdk_get_thread() != g_fini_thread) {
SPDK_ERRLOG("%s changed threads\n", g_bdev_module->name);
}
if (!g_bdev_module) {
g_bdev_module = TAILQ_FIRST(&g_bdev_mgr.bdev_modules);
spdk_thread_send_msg(g_fini_thread, spdk_bdev_module_finish_iter, NULL);
} else {
g_bdev_module = TAILQ_NEXT(g_bdev_module, tailq);
}
if (!g_bdev_module) {
spdk_bdev_module_finish_complete();
return;
}
if (g_bdev_module->module_fini) {
spdk_thread_send_msg(g_fini_thread, _call_next_module_fini, g_bdev_module);
}
if (!g_bdev_module->async_fini) {
spdk_bdev_module_finish_done();
spdk_bdev_module_finish_iter(NULL);
}
}
@ -650,7 +664,7 @@ spdk_bdev_finish(spdk_bdev_fini_cb cb_fn, void *cb_arg)
g_fini_cb_fn = cb_fn;
g_fini_cb_arg = cb_arg;
spdk_bdev_module_finish_done();
spdk_bdev_module_finish_iter(NULL);
}
struct spdk_bdev_io *