Commit b5e2c59a authored by Kozlowski Mateusz's avatar Kozlowski Mateusz Committed by Ben Walker
Browse files

FTL: Add fast shutdown path



Adds the ability to persist only the most important metadata. The rest
is stored in shared memory.

Signed-off-by: default avatarKozlowski Mateusz <mateusz.kozlowski@intel.com>
Signed-off-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Change-Id: I4084c04ba09115a7a08ff66fd33552a2ec60d801
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13360


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent ef93cc38
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -138,6 +138,16 @@ ftl_mngt_persist_nv_cache_metadata(struct spdk_ftl_dev *dev, struct ftl_mngt_pro
	persist(dev, mngt, FTL_LAYOUT_REGION_TYPE_NVC_MD);
}

static void
ftl_mngt_fast_persist_nv_cache_metadata(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
	if (ftl_nv_cache_save_state(&dev->nv_cache)) {
		ftl_mngt_fail_step(mngt);
		return;
	}
	ftl_mngt_next_step(mngt);
}

static void
ftl_mngt_persist_vld_map_metadata(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
@@ -223,6 +233,33 @@ ftl_mngt_persist_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
	ftl_mngt_call_process(mngt, &desc_persist);
}

/*
 * Fast clean shutdown path - skips the persistance of most metadata regions and
 * relies on their shared memory state instead.
 */
static const struct ftl_mngt_process_desc desc_fast_persist = {
	.name = "Fast persist metadata",
	.steps = {
		{
			.name = "Fast persist NV cache metadata",
			.action = ftl_mngt_fast_persist_nv_cache_metadata,
		},
#ifdef SPDK_FTL_VSS_EMU
		{
			.name = "Persist VSS metadata",
			.action = ftl_mngt_persist_vss,
		},
#endif
		{}
	}
};

void
ftl_mngt_fast_persist_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
	ftl_mngt_call_process(mngt, &desc_fast_persist);
}

void
ftl_mngt_init_default_sb(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
@@ -274,6 +311,17 @@ ftl_mngt_set_clean(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
	dev->sb_shm->shm_ready = false;
}

void
ftl_mngt_set_shm_clean(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
	struct ftl_superblock *sb = dev->sb;

	sb->clean = 1;
	dev->sb_shm->shm_clean = true;
	sb->header.crc = get_sb_crc(sb);
	ftl_mngt_next_step(mngt);
}

/*
 * Initializes the superblock fields during first startup of FTL
 */
+52 −1
Original line number Diff line number Diff line
@@ -55,8 +55,59 @@ static const struct ftl_mngt_process_desc desc_shutdown = {
	}
};

/*
 * Steps executed during fast clean shutdown (shutting down to shared memory). Utilizes
 * minimum amount of metadata persistence and rolls back any setup steps executed during
 * startup (closing bdevs, io channels, etc)
 */
static const struct ftl_mngt_process_desc desc_fast_shutdown = {
	.name = "FTL fast shutdown",
	.steps = {
		{
			.name = "Deinit core IO channel",
			.action = ftl_mngt_deinit_io_channel
		},
		{
			.name = "Unregister IO device",
			.action = ftl_mngt_unregister_io_device
		},
		{
			.name = "Stop core poller",
			.action = ftl_mngt_stop_core_poller
		},
		{
			.name = "Fast persist metadata",
			.action = ftl_mngt_fast_persist_md
		},
		{
			.name = "Set FTL SHM clean state",
			.action = ftl_mngt_set_shm_clean
		},
		{
			.name = "Dump statistics",
			.action = ftl_mngt_dump_stats
		},
		{
			.name = "Deinitialize L2P",
			.action = ftl_mngt_deinit_l2p
		},
		{
			.name = "Rollback FTL device",
			.action = ftl_mngt_rollback_device
		},
		{}
	}
};

int
ftl_mngt_call_dev_shutdown(struct spdk_ftl_dev *dev, ftl_mngt_completion cb, void *cb_cntx)
{
	return ftl_mngt_process_execute(dev, &desc_shutdown, cb, cb_cntx);
	const struct ftl_mngt_process_desc *pdesc;

	if (dev->conf.fast_shutdown) {
		pdesc = &desc_fast_shutdown;
	} else {
		pdesc = &desc_shutdown;
	}
	return ftl_mngt_process_execute(dev, pdesc, cb, cb_cntx);
}
+4 −0
Original line number Diff line number Diff line
@@ -84,6 +84,8 @@ void ftl_mngt_deinit_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)

void ftl_mngt_persist_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

void ftl_mngt_fast_persist_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

void ftl_mngt_rollback_device(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

void ftl_mngt_dump_stats(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);
@@ -94,6 +96,8 @@ void ftl_mngt_set_dirty(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)

void ftl_mngt_set_clean(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

void ftl_mngt_set_shm_clean(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

void ftl_mngt_init_vld_map(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);

void ftl_mngt_deinit_vld_map(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);