Commit 522a0c82 authored by Lukasz Lasek's avatar Lukasz Lasek Committed by Jim Harris
Browse files

lib/ftl: Simplify ftl_md mirror operations



Use already instantiated ftl::layout::md struct for ftl_md mirror
operations, i.e. persist, restore, clear.
With this change, the ftl_md::mirror member isn't needed anymore.

Change-Id: Ia9282911daa88b3ce30e53fa852f54d031683dde
Signed-off-by: default avatarLukasz Lasek <lukasz.lasek@solidigm.com>
Signed-off-by: default avatarMariusz Barczak <Mariusz.Barczak@solidigmtechnology.com>
Signed-off-by: default avatarMateusz Kozlowski <mateusz.kozlowski@solidigm.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/19592


Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
parent b0556d4a
Loading
Loading
Loading
Loading
+34 −1
Original line number Diff line number Diff line
@@ -53,10 +53,12 @@ ftl_mngt_init_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
	struct ftl_layout *layout = &dev->layout;
	struct ftl_layout_region *region = layout->region;
	struct ftl_md *md, *md_mirror;
	uint64_t i;
	int md_flags;

	for (i = 0; i < FTL_LAYOUT_REGION_TYPE_MAX; i++, region++) {
		assert(i == region->type);
		if (layout->md[i]) {
			/*
			 * Some metadata objects are initialized by other FTL
@@ -76,6 +78,26 @@ ftl_mngt_init_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
		}
	}

	/* Initialize mirror regions */
	region = layout->region;
	for (i = 0; i < FTL_LAYOUT_REGION_TYPE_MAX; i++, region++) {
		assert(i == region->type);
		if (region->mirror_type != FTL_LAYOUT_REGION_TYPE_INVALID &&
		    !is_buffer_needed(region->mirror_type)) {
			md = layout->md[i];
			md_mirror = layout->md[region->mirror_type];

			md_mirror->dev = md->dev;
			md_mirror->data_blocks = md->data_blocks;
			md_mirror->data = md->data;
			if (md_mirror->region->vss_blksz == md->region->vss_blksz) {
				md_mirror->vss_data = md->vss_data;
			}
			md_mirror->region = &layout->region[region->mirror_type];
			md_mirror->is_mirror = true;
		}
	}

	ftl_mngt_next_step(mngt);
}

@@ -505,6 +527,8 @@ static const struct ftl_mngt_process_desc desc_init_sb = {
void
ftl_mngt_superblock_init(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
	struct ftl_md *md;
	struct ftl_md *md_mirror;
	struct ftl_layout *layout = &dev->layout;
	struct ftl_layout_region *region = &layout->region[FTL_LAYOUT_REGION_TYPE_SB];
	char uuid[SPDK_UUID_STRING_LEN];
@@ -565,12 +589,21 @@ shm_retry:
	/* Setup superblock mirror to QLC */
	region = &layout->region[FTL_LAYOUT_REGION_TYPE_SB_BASE];
	layout->md[FTL_LAYOUT_REGION_TYPE_SB_BASE] = ftl_md_create(dev, region->current.blocks,
			region->vss_blksz, NULL, FTL_MD_CREATE_HEAP, region);
			region->vss_blksz, NULL, FTL_MD_CREATE_NO_MEM, region);
	if (NULL == layout->md[FTL_LAYOUT_REGION_TYPE_SB_BASE]) {
		ftl_mngt_fail_step(mngt);
		return;
	}

	/* Initialize mirror region buffer */
	md = layout->md[FTL_LAYOUT_REGION_TYPE_SB];
	md_mirror = layout->md[FTL_LAYOUT_REGION_TYPE_SB_BASE];

	md_mirror->dev = md->dev;
	md_mirror->data_blocks = md->data_blocks;
	md_mirror->data = md->data;
	md_mirror->is_mirror = true;

	/* Initialize the superblock */
	if (dev->conf.mode & SPDK_FTL_MODE_CREATE) {
		ftl_mngt_call_process(mngt, &desc_init_sb);
+1 −4
Original line number Diff line number Diff line
@@ -374,10 +374,7 @@ ftl_mngt_recovery_iteration_load_l2p(struct spdk_ftl_dev *dev, struct ftl_mngt_p
		      region->current.offset, region->current.offset + region->current.blocks,
		      ctx->iter.lba_first, ctx->iter.lba_last);

	if (ftl_md_set_region(md, &ctx->l2p_snippet.region)) {
		ftl_mngt_fail_step(mngt);
		return;
	}
	ftl_md_set_region(md, &ctx->l2p_snippet.region);

	md->owner.cb_ctx = mngt;
	md->cb = l2p_cb;
+5 −3
Original line number Diff line number Diff line
@@ -48,11 +48,13 @@ md_region_create(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type,
	/* As new MD regions are added one after another, find where all existing regions end on the device */
	region = layout->region;
	for (int reg_idx = 0; reg_idx < FTL_LAYOUT_REGION_TYPE_MAX; reg_idx++, region++) {
		if (region->bdev_desc == dev->nv_cache.bdev_desc) {
			reg_current_end = region->current.offset + region->current.blocks;
			if (reg_free_offs < reg_current_end) {
				reg_free_offs = reg_current_end;
			}
		}
	}

	region = &layout->region[reg_type];
	region->type = reg_type;
+40 −64
Original line number Diff line number Diff line
@@ -27,27 +27,14 @@ has_mirror(struct ftl_md *md)
	return false;
}

static int
setup_mirror(struct ftl_md *md)
static struct ftl_md *
ftl_md_get_mirror(struct ftl_md *md)
{
	if (!md->mirror) {
		md->mirror = calloc(1, sizeof(*md->mirror));
		if (!md->mirror) {
			return -ENOMEM;
		}
		md->mirror_enabled = true;
	if (has_mirror(md)) {
		return md->dev->layout.md[md->region->mirror_type];
	}

	md->mirror->dev = md->dev;
	md->mirror->data_blocks = md->data_blocks;
	md->mirror->data = md->data;
	md->mirror->vss_data = md->vss_data;

	/* Set proper region in secondary object */
	assert(md->region->mirror_type != FTL_LAYOUT_REGION_TYPE_INVALID);
	md->mirror->region = &md->dev->layout.region[md->region->mirror_type];

	return 0;
	return NULL;
}

uint64_t
@@ -305,9 +292,7 @@ struct ftl_md *ftl_md_create(struct spdk_ftl_dev *dev, uint64_t blocks,
			}
		}

		if (ftl_md_set_region(md, region)) {
			goto err;
		}
		ftl_md_set_region(md, region);
	}

	return md;
@@ -339,11 +324,10 @@ ftl_md_destroy(struct ftl_md *md, int flags)
		return;
	}

	if (!md->is_mirror) {
		ftl_md_free_buf(md, flags);

		spdk_free(md->entry_vss_dma_buf);

	free(md->mirror);
	}
	free(md);
}

@@ -729,8 +713,9 @@ static void
ftl_md_persist_entry_mirror(void *_ctx)
{
	struct ftl_md_io_entry_ctx *ctx = _ctx;
	struct ftl_md *md_mirror = ftl_md_get_mirror(ctx->md);

	ftl_md_persist_entry_write_blocks(ctx, ctx->md->mirror, ftl_md_persist_entry_mirror);
	ftl_md_persist_entry_write_blocks(ctx, md_mirror, ftl_md_persist_entry_mirror);
}

static void
@@ -743,7 +728,7 @@ ftl_md_persist_entry_primary(void *_ctx)
	rc = ftl_md_persist_entry_write_blocks(ctx, md, ftl_md_persist_entry_primary);

	if (!rc && has_mirror(md)) {
		assert(md->region->entry_size == md->mirror->region->entry_size);
		assert(md->region->entry_size == (ftl_md_get_mirror(md))->region->entry_size);

		/* The MD object has mirror so execute persist on it too */
		ftl_md_persist_entry_mirror(ctx);
@@ -794,14 +779,11 @@ read_entry_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)

	if (!success) {
		if (has_mirror(md)) {
			if (setup_mirror(md)) {
				/* An error when setup the mirror */
				ctx->status = -EIO;
				goto finish_io;
			}
			md->mirror_enabled = true;

			/* First read from the mirror */
			ftl_md_read_entry(md->mirror, ctx->start_entry, ctx->buffer, ctx->vss_buffer,
			ftl_md_read_entry(ftl_md_get_mirror(md), ctx->start_entry, ctx->buffer,
					  ctx->vss_buffer,
					  ctx->cb, ctx->cb_arg,
					  ctx);
			return;
@@ -896,18 +878,16 @@ void
ftl_md_persist(struct ftl_md *md)
{
	if (has_mirror(md)) {
		if (setup_mirror(md)) {
			/* An error when setup the mirror */
			spdk_thread_send_msg(spdk_get_thread(), exception, md);
			return;
		}
		struct ftl_md *md_mirror = ftl_md_get_mirror(md);

		md->mirror_enabled = true;

		/* Set callback and context in mirror */
		md->mirror->cb = persist_mirror_cb;
		md->mirror->owner.private = md;
		md_mirror->cb = persist_mirror_cb;
		md_mirror->owner.private = md;

		/* First persist the mirror */
		ftl_md_persist(md->mirror);
		ftl_md_persist(md_mirror);
		return;
	}

@@ -967,31 +947,31 @@ restore_done(struct ftl_md *md)
		 */

		if (has_mirror(md)) {
			if (setup_mirror(md)) {
				/* An error when setup the mirror */
				return -EIO;
			}
			struct ftl_md *md_mirror = ftl_md_get_mirror(md);

			md->mirror_enabled = true;

			/* Set callback and context in mirror */
			md->mirror->cb = restore_mirror_cb;
			md->mirror->owner.private = md;
			md_mirror->cb = restore_mirror_cb;
			md_mirror->owner.private = md;

			/* First persist the mirror */
			ftl_md_restore(md->mirror);
			ftl_md_restore(md_mirror);
			return -EAGAIN;
		} else {
			return -EIO;
		}
	} else if (0 == md->io.status && false == md->dev->sb->clean) {
		if (has_mirror(md)) {
			struct ftl_md *md_mirror = ftl_md_get_mirror(md);
			/* There was a dirty shutdown, synchronize primary to mirror */

			/* Set callback and context in the mirror */
			md->mirror->cb = restore_sync_cb;
			md->mirror->owner.private = md;
			md_mirror->cb = restore_sync_cb;
			md_mirror->owner.private = md;

			/* First persist the mirror */
			ftl_md_persist(md->mirror);
			ftl_md_persist(md_mirror);
			return -EAGAIN;
		}
	}
@@ -1076,18 +1056,16 @@ void
ftl_md_clear(struct ftl_md *md, int data_pattern, union ftl_md_vss *vss_pattern)
{
	if (has_mirror(md)) {
		if (setup_mirror(md)) {
			/* An error when setup the mirror */
			spdk_thread_send_msg(spdk_get_thread(), exception, md);
			return;
		}
		struct ftl_md *md_mirror = ftl_md_get_mirror(md);

		md->mirror_enabled = true;

		/* Set callback and context in mirror */
		md->mirror->cb = clear_mirror_cb;
		md->mirror->owner.private = md;
		md_mirror->cb = clear_mirror_cb;
		md_mirror->owner.private = md;

		/* First persist the mirror */
		ftl_md_clear(md->mirror, data_pattern, vss_pattern);
		ftl_md_clear(md_mirror, data_pattern, vss_pattern);
		return;
	}

@@ -1104,7 +1082,7 @@ ftl_md_get_region(struct ftl_md *md)
	return md->region;
}

int
void
ftl_md_set_region(struct ftl_md *md,
		  const struct ftl_layout_region *region)
{
@@ -1122,10 +1100,8 @@ ftl_md_set_region(struct ftl_md *md,
	}

	if (has_mirror(md)) {
		return setup_mirror(md);
		md->mirror_enabled = true;
	}

	return 0;
}

int
+5 −7
Original line number Diff line number Diff line
@@ -89,11 +89,11 @@ struct ftl_md {
	/* Memory was registered to SPDK */
	bool mem_reg;

	/* Metadata primary object */
	struct ftl_md *mirror;

	/* This flag is used by the primary to disable mirror temporarily */
	bool mirror_enabled;

	/* This MD descriptor is used for a mirror region */
	bool is_mirror;
};

typedef void (*ftl_md_io_entry_cb)(int status, void *cb_arg);
@@ -213,10 +213,8 @@ void ftl_md_free_buf(struct ftl_md *md, int flags);
 *
 * @param md The FTL metadata
 * @param region The device region to be set
 *
 * @return Operation status
 */
int ftl_md_set_region(struct ftl_md *md,
void ftl_md_set_region(struct ftl_md *md,
		       const struct ftl_layout_region *region);

/**