Commit 2c83a481 authored by Jim Harris's avatar Jim Harris
Browse files

bdev: defer spdk_bdev_init_complete for async registration



Add additional fields to the g_bdev_mgr to enable
deferring spdk_bdev_init_complete when modules have
finished initialization, but vbdevs are still processing
examination callbacks due to asynchronous I/O.

Signed-off-by: default avatarJim Harris <james.r.harris@intel.com>
Change-Id: I12dc7cb08e44e022b5bad75ba9a946571eb65957

Reviewed-on: https://review.gerrithub.io/368832


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: default avatarZiye Yang <optimistyzy@gmail.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent e075a3dc
Loading
Loading
Loading
Loading
+56 −4
Original line number Diff line number Diff line
@@ -71,6 +71,10 @@ struct spdk_bdev_mgr {
	spdk_bdev_poller_start_cb start_poller_fn;
	spdk_bdev_poller_stop_cb stop_poller_fn;

	bool init_complete;
	bool module_init_complete;
	int module_init_rc;

#ifdef SPDK_CONFIG_VTUNE
	__itt_domain	*domain;
#endif
@@ -81,7 +85,10 @@ static struct spdk_bdev_mgr g_bdev_mgr = {
	.vbdev_modules = TAILQ_HEAD_INITIALIZER(g_bdev_mgr.vbdev_modules),
	.bdevs = TAILQ_HEAD_INITIALIZER(g_bdev_mgr.bdevs),
	.start_poller_fn = NULL,
	.stop_poller_fn = NULL
	.stop_poller_fn = NULL,
	.init_complete = false,
	.module_init_complete = false,
	.module_init_rc = 0,
};

static struct spdk_bdev_module_if *g_next_bdev_module;
@@ -361,19 +368,42 @@ spdk_bdev_init_complete(int rc)
	spdk_bdev_init_cb cb_fn = g_cb_fn;
	void *cb_arg = g_cb_arg;

	g_bdev_mgr.init_complete = true;
	g_cb_fn = NULL;
	g_cb_arg = NULL;

	cb_fn(cb_arg, rc);
}

static void
spdk_bdev_module_init_complete(int rc)
{
	struct spdk_bdev_module_if *m;

	g_bdev_mgr.module_init_complete = true;
	g_bdev_mgr.module_init_rc = rc;

	/*
	 * Check all vbdev modules for an examinations in progress.  If any
	 * exist, return immediately since we cannot finish bdev subsystem
	 * initialization until all are completed.
	 */
	TAILQ_FOREACH(m, &g_bdev_mgr.vbdev_modules, tailq) {
		if (m->examine_in_progress > 0) {
			return;
		}
	}

	spdk_bdev_init_complete(rc);
}

void
spdk_bdev_module_init_next(int rc)
{
	if (rc) {
		assert(g_next_bdev_module != NULL);
		SPDK_ERRLOG("Failed to init bdev module: %s\n", g_next_bdev_module->name);
		spdk_bdev_init_complete(rc);
		spdk_bdev_module_init_complete(rc);
		return;
	}

@@ -396,7 +426,7 @@ spdk_vbdev_module_init_next(int rc)
	if (rc) {
		assert(g_next_vbdev_module != NULL);
		SPDK_ERRLOG("Failed to init vbdev module: %s\n", g_next_vbdev_module->name);
		spdk_bdev_init_complete(rc);
		spdk_bdev_module_init_complete(rc);
		return;
	}

@@ -409,7 +439,7 @@ spdk_vbdev_module_init_next(int rc)
	if (g_next_vbdev_module) {
		g_next_vbdev_module->module_init();
	} else {
		spdk_bdev_init_complete(rc);;
		spdk_bdev_module_init_complete(rc);;
	}
}

@@ -1460,8 +1490,30 @@ spdk_vbdev_unregister(struct spdk_bdev *vbdev)
void
spdk_vbdev_module_examine_done(struct spdk_bdev_module_if *module)
{
	struct spdk_bdev_module_if *m;

	assert(module->examine_in_progress > 0);
	module->examine_in_progress--;

	/*
	 * Check all vbdev modules for an examinations in progress.  If any
	 * exist, return immediately since we cannot finish bdev subsystem
	 * initialization until all are completed.
	 */
	TAILQ_FOREACH(m, &g_bdev_mgr.vbdev_modules, tailq) {
		if (m->examine_in_progress > 0) {
			return;
		}
	}

	if (g_bdev_mgr.module_init_complete && !g_bdev_mgr.init_complete) {
		/*
		 * Modules already finished initialization - now that all
		 * the vbdevs have finished their asynchronous I/O processing,
		 * the entire bdev layer can be marked as complete.
		 */
		spdk_bdev_init_complete(g_bdev_mgr.module_init_rc);
	}
}

static bool