Commit a3b7ae8a authored by Mateusz Kozlowski's avatar Mateusz Kozlowski Committed by Jim Harris
Browse files

lib/ftl: IO channel handling for nv cache



Moved scrubbing of nv cache to core thread. Added IO channel which is
used in user context, during shutdown of nv cache.

Signed-off-by: default avatarMateusz Kozlowski <mateusz.kozlowski@intel.com>
Change-Id: I88e680324e361bf7e0c0a9a9d29323f179c56e3b
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/465932


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 863512e9
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -407,7 +407,6 @@ ftl_get_io_channel(const struct spdk_ftl_dev *dev)
	return NULL;
}


int
ftl_io_erase(struct ftl_io *io)
{
+2 −0
Original line number Diff line number Diff line
@@ -157,6 +157,8 @@ struct spdk_ftl_dev {
	/* Indicates the device is about to be stopped */
	int					halt;

	/* Status to return for halt completion callback */
	int					halt_complete_status;
	/* Initializaton context */
	struct ftl_init_context			init_ctx;
	/* Destruction context */
+41 −32
Original line number Diff line number Diff line
@@ -909,12 +909,26 @@ ftl_clear_nv_cache_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
	}
}

static void
_ftl_nv_cache_scrub(void *ctx)
{
	struct spdk_ftl_dev *dev = ctx;
	int rc;

	rc = ftl_nv_cache_scrub(&dev->nv_cache, ftl_clear_nv_cache_cb, dev);

	if (spdk_unlikely(rc != 0)) {
		SPDK_ERRLOG("Unable to clear the non-volatile cache bdev: %s\n",
			    spdk_strerror(-rc));
		ftl_init_fail(dev);
	}
}

static int
ftl_setup_initial_state(struct spdk_ftl_dev *dev)
{
	struct spdk_ftl_conf *conf = &dev->conf;
	size_t i;
	int rc;

	spdk_uuid_generate(&dev->uuid);

@@ -938,12 +952,7 @@ ftl_setup_initial_state(struct spdk_ftl_dev *dev)
	if (!ftl_dev_has_nv_cache(dev)) {
		ftl_init_complete(dev);
	} else {
		rc = ftl_nv_cache_scrub(&dev->nv_cache, ftl_clear_nv_cache_cb, dev);
		if (spdk_unlikely(rc != 0)) {
			SPDK_ERRLOG("Unable to clear the non-volatile cache bdev: %s\n",
				    spdk_strerror(-rc));
			return -1;
		}
		spdk_thread_send_msg(ftl_get_core_thread(dev), _ftl_nv_cache_scrub, dev);
	}

	return 0;
@@ -1229,6 +1238,13 @@ ftl_dev_free_sync(struct spdk_ftl_dev *dev)

	spdk_io_device_unregister(dev, NULL);

	if (dev->core_thread.thread) {
		ftl_dev_free_thread(dev, &dev->core_thread);
	}
	if (dev->read_thread.thread) {
		ftl_dev_free_thread(dev, &dev->read_thread);
	}

	if (dev->bands) {
		for (i = 0; i < ftl_dev_num_bands(dev); ++i) {
			free(dev->bands[i].chunk_buf);
@@ -1268,36 +1284,27 @@ ftl_call_fini_complete(struct spdk_ftl_dev *dev, int status)
}

static void
ftl_nv_cache_header_fini_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
ftl_halt_complete_cb(void *ctx)
{
	int status = 0;

	spdk_bdev_free_io(bdev_io);
	if (spdk_unlikely(!success)) {
		SPDK_ERRLOG("Failed to write non-volatile cache metadata header\n");
		status = -EIO;
	}
	struct spdk_ftl_dev *dev = ctx;

	ftl_call_fini_complete((struct spdk_ftl_dev *)cb_arg, status);
	ftl_call_fini_complete(dev, dev->halt_complete_status);
}

static void
ftl_halt_complete_cb(void *ctx)
ftl_nv_cache_header_fini_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
	struct spdk_ftl_dev *dev = ctx;
	struct ftl_nv_cache *nv_cache = &dev->nv_cache;
	struct spdk_ftl_dev *dev = cb_arg;
	int rc = 0;

	if (!ftl_dev_has_nv_cache(dev)) {
		ftl_call_fini_complete(dev, 0);
	} else {
		rc = ftl_nv_cache_write_header(nv_cache, true, ftl_nv_cache_header_fini_cb, dev);
		if (spdk_unlikely(rc != 0)) {
			SPDK_ERRLOG("Failed to write non-volatile cache metadata header: %s\n",
				    spdk_strerror(-rc));
			ftl_call_fini_complete(dev, rc);
		}
	spdk_bdev_free_io(bdev_io);
	if (spdk_unlikely(!success)) {
		SPDK_ERRLOG("Failed to write non-volatile cache metadata header\n");
		rc = -EIO;
	}

	dev->halt_complete_status = rc;
	spdk_thread_send_msg(dev->fini_ctx.thread, ftl_halt_complete_cb, dev);
}

static int
@@ -1308,13 +1315,15 @@ ftl_halt_poller(void *ctx)
	if (!dev->core_thread.poller && !dev->read_thread.poller) {
		spdk_poller_unregister(&dev->fini_ctx.poller);

		ftl_dev_free_thread(dev, &dev->read_thread);
		ftl_dev_free_thread(dev, &dev->core_thread);

		ftl_anm_unregister_device(dev);

		if (ftl_dev_has_nv_cache(dev)) {
			ftl_nv_cache_write_header(&dev->nv_cache, true, ftl_nv_cache_header_fini_cb, dev);
		} else {
			dev->halt_complete_status = 0;
			spdk_thread_send_msg(dev->fini_ctx.thread, ftl_halt_complete_cb, dev);
		}
	}

	return 0;
}