Commit 1d982081 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Jim Harris
Browse files

bdev/ftl: defer bdev initialization



Defer the initialization when cache bdev mentioned in the config doesn't
exist when the FTL bdev is being created.

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: I084502ae38c9ae5e385e5566550ec3cb8b6f9d2e
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/448630


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarPaul Luse <paul.e.luse@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarWojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent a0cb5e9d
Loading
Loading
Loading
Loading
+81 −8
Original line number Diff line number Diff line
@@ -89,6 +89,12 @@ struct ftl_bdev_io {
	struct spdk_thread		*orig_thread;
};

struct ftl_deferred_init {
	struct ftl_bdev_init_opts	opts;

	LIST_ENTRY(ftl_deferred_init)	entry;
};

typedef void (*bdev_ftl_finish_fn)(void);

static LIST_HEAD(, ftl_bdev)		g_ftl_bdevs = LIST_HEAD_INITIALIZER(g_ftl_bdevs);
@@ -96,9 +102,11 @@ static bdev_ftl_finish_fn g_finish_cb;
static size_t				g_num_conf_bdevs;
static size_t				g_num_init_bdevs;
static pthread_mutex_t			g_ftl_bdev_lock;
static LIST_HEAD(, ftl_deferred_init)	g_deferred_init;

static int bdev_ftl_initialize(void);
static void bdev_ftl_finish(void);
static void bdev_ftl_examine(struct spdk_bdev *);

static int
bdev_ftl_get_ctx_size(void)
@@ -112,6 +120,7 @@ static struct spdk_bdev_module g_ftl_if = {
	.async_fini	= true,
	.module_init	= bdev_ftl_initialize,
	.module_fini	= bdev_ftl_finish,
	.examine_disk	= bdev_ftl_examine,
	.get_ctx_size	= bdev_ftl_get_ctx_size,
};

@@ -492,13 +501,29 @@ out:
	return rc;
}

static int
bdev_ftl_defer_init(struct ftl_bdev_init_opts *opts)
{
	struct ftl_deferred_init *init;

	init = calloc(1, sizeof(*init));
	if (!init) {
		return -ENOMEM;
	}

	init->opts = *opts;
	LIST_INSERT_HEAD(&g_deferred_init, init, entry);

	return 0;
}

static int
bdev_ftl_read_bdev_config(struct spdk_conf_section *sp,
			  struct ftl_bdev_init_opts *opts,
			  size_t *num_bdevs)
{
	const char *val, *trid;
	int i, rc = 0;
	int i, rc = 0, num_deferred = 0;

	*num_bdevs = 0;

@@ -567,17 +592,22 @@ bdev_ftl_read_bdev_config(struct spdk_conf_section *sp,
			continue;
		}

		opts->cache_bdev = val;
		if (!spdk_bdev_get_by_name(val)) {
			SPDK_ERRLOG("Invalid cache bdev name: %s for TransportID: %s\n", val, trid);
			SPDK_INFOLOG(SPDK_LOG_BDEV_FTL, "Deferring bdev %s initialization\n", opts->name);

			if (bdev_ftl_defer_init(opts)) {
				SPDK_ERRLOG("Unable to initialize bdev %s\n", opts->name);
				rc = -1;
				break;
			}

		opts->cache_bdev = val;
			num_deferred++;
		}
	}

	if (!rc) {
		*num_bdevs = i;
		*num_bdevs = i - num_deferred;
	}

	return rc;
@@ -818,10 +848,21 @@ bdev_ftl_bdev_init_done(void)
static void
bdev_ftl_init_cb(const struct ftl_bdev_info *info, void *ctx, int status)
{
	struct ftl_deferred_init *opts;

	if (status) {
		SPDK_ERRLOG("Failed to initialize FTL bdev\n");
	}

	LIST_FOREACH(opts, &g_deferred_init, entry) {
		if (!strcmp(opts->opts.name, info->name)) {
			spdk_bdev_module_examine_done(&g_ftl_if);
			LIST_REMOVE(opts, entry);
			free(opts);
			break;
		}
	}

	bdev_ftl_bdev_init_done();
}

@@ -830,6 +871,7 @@ bdev_ftl_initialize_cb(void *ctx, int status)
{
	struct spdk_conf_section *sp;
	struct ftl_bdev_init_opts *opts = NULL;
	struct ftl_deferred_init *defer_opts;
	size_t i;

	if (status) {
@@ -853,7 +895,16 @@ bdev_ftl_initialize_cb(void *ctx, int status)
	}

	for (i = 0; i < g_num_conf_bdevs; ++i) {
		if (bdev_ftl_init_bdev(&opts[i], bdev_ftl_init_cb, NULL)) {
		bool defer_init = false;

		LIST_FOREACH(defer_opts, &g_deferred_init, entry) {
			if (!strcmp(defer_opts->opts.name, opts[i].name)) {
				defer_init = true;
				break;
			}
		}

		if (!defer_init && bdev_ftl_init_bdev(&opts[i], bdev_ftl_init_cb, NULL)) {
			SPDK_ERRLOG("Failed to create bdev '%s'\n", opts[i].name);
			bdev_ftl_bdev_init_done();
		}
@@ -937,6 +988,28 @@ bdev_ftl_init_bdev(struct ftl_bdev_init_opts *opts, ftl_bdev_init_fn cb, void *c
	return bdev_ftl_create(ctrlr, opts, cb, cb_arg);
}

static void
bdev_ftl_examine(struct spdk_bdev *bdev)
{
	struct ftl_deferred_init *opts;

	LIST_FOREACH(opts, &g_deferred_init, entry) {
		if (spdk_bdev_get_by_name(opts->opts.cache_bdev) == bdev) {
			if (bdev_ftl_init_bdev(&opts->opts, bdev_ftl_init_cb, NULL)) {
				SPDK_ERRLOG("Unable to initialize bdev '%s'\n", opts->opts.name);
				LIST_REMOVE(opts, entry);
				free(opts);
				break;
			}

			/* spdk_bdev_module_examine_done will be called by bdev_ftl_init_cb */
			return;
		}
	}

	spdk_bdev_module_examine_done(&g_ftl_if);
}

void
bdev_ftl_delete_bdev(const char *name, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
{
+6 −4
Original line number Diff line number Diff line
@@ -5,28 +5,30 @@ set -e
rootdir=$(readlink -f $(dirname $0))/..

function usage {
	echo "Usage: $0 -a TRANSPORT_ADDR -n BDEV_NAME -l PUNITS [-u UUID]"
	echo "Usage: $0 -a TRANSPORT_ADDR -n BDEV_NAME -l PUNITS [-u UUID] [-c CACHE]"
	echo "UUID is required when restoring device state"
	echo
	echo "TRANSPORT_ADDR - SSD's PCIe address"
	echo "BDEV_NAME - name of the bdev"
	echo "PUNITS - bdev's parallel unit range (e.g. 0-3)"
	echo "UUID - bdev's uuid (used when in restore mode)"
	echo "CACHE - name of the bdev to be used as write buffer cache"
}

function generate_config {
	echo "[Ftl]"
	echo "  TransportID \"trtype:PCIe traddr:$1\" $2 $3 $4"
	echo "  TransportID \"trtype:PCIe traddr:$1\" $2 $3 $4 $5"
}

uuid=00000000-0000-0000-0000-000000000000

while getopts ":a:n:l:m:u:" arg; do
while getopts ":a:n:l:m:u:c:" arg; do
	case "$arg" in
		a)	addr=$OPTARG	;;
		n)	name=$OPTARG	;;
		l)	punits=$OPTARG	;;
		u)	uuid=$OPTARG	;;
		c)	cache=$OPTARG	;;
		h)	usage
			exit 0		;;
		*)	usage
@@ -39,4 +41,4 @@ if [[ -z "$addr" || -z "$name" || -z "$punits" ]]; then
	exit 1
fi

generate_config $addr $name $punits $uuid
generate_config $addr $name $punits $uuid $cache