Commit eb8571d4 authored by Ben Walker's avatar Ben Walker Committed by Daniel Verkamp
Browse files

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: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
parent 6447eb67
Loading
Loading
Loading
Loading
+38 −24
Original line number Diff line number Diff line
@@ -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);
	}

void
spdk_bdev_module_finish_done(void)
{
	if (spdk_get_thread() != g_fini_thread) {
		SPDK_ERRLOG("%s changed threads\n", g_bdev_module->name);
	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 (!g_bdev_module) {
		g_bdev_module = TAILQ_FIRST(&g_bdev_mgr.bdev_modules);
	} else {
		g_bdev_module = TAILQ_NEXT(g_bdev_module, tailq);
		if (bdev_module->module_fini) {
			bdev_module->module_fini();
		}

	if (!g_bdev_module) {
		spdk_bdev_module_finish_complete();
		if (bdev_module->async_fini) {
			return;
		}

	if (g_bdev_module->module_fini) {
		spdk_thread_send_msg(g_fini_thread, _call_next_module_fini, g_bdev_module);
		bdev_module = TAILQ_NEXT(bdev_module, tailq);
	}

	if (!g_bdev_module->async_fini) {
		spdk_bdev_module_finish_done();
	resume_bdev_module = NULL;
	spdk_bdev_module_finish_complete();
}

void
spdk_bdev_module_finish_done(void)
{
	if (spdk_get_thread() != g_fini_thread) {
		spdk_thread_send_msg(g_fini_thread, spdk_bdev_module_finish_iter, NULL);
	} else {
		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 *