From f45c00751256b3435351e104a183c967a1b01b21 Mon Sep 17 00:00:00 2001 From: Artur Paszkiewicz Date: Thu, 9 Jun 2022 14:51:45 +0200 Subject: [PATCH] ftl: superblock in shared memory Signed-off-by: Artur Paszkiewicz Signed-off-by: Kozlowski Mateusz Change-Id: I86e2cbf364ae3075aad2e09429754027df33eadf Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13342 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/ftl/ftl_core.h | 7 +++++++ lib/ftl/ftl_init.c | 12 ++++++++++++ lib/ftl/ftl_sb_common.h | 17 +++++++++++++++++ lib/ftl/mngt/ftl_mngt_md.c | 18 ++++++++++++++++++ lib/ftl/mngt/ftl_mngt_misc.c | 1 + lib/ftl/utils/ftl_md.c | 11 +++++++++++ 6 files changed, 66 insertions(+) diff --git a/lib/ftl/ftl_core.h b/lib/ftl/ftl_core.h index e6112fecd..56d85c6c5 100644 --- a/lib/ftl/ftl_core.h +++ b/lib/ftl/ftl_core.h @@ -47,6 +47,10 @@ struct spdk_ftl_dev { /* FTL superblock */ struct ftl_superblock *sb; + /* FTL shm superblock */ + struct ftl_superblock_shm *sb_shm; + struct ftl_md *sb_shm_md; + /* Queue of registered IO channels */ TAILQ_HEAD(, ftl_io_channel) ioch_queue; @@ -145,6 +149,9 @@ struct spdk_ftl_dev { /* Writer for GC IOs */ struct ftl_writer writer_gc; + + /* Retry init sequence */ + bool init_retry; }; void ftl_apply_limits(struct spdk_ftl_dev *dev); diff --git a/lib/ftl/ftl_init.c b/lib/ftl/ftl_init.c index 96d2a0087..798594bb7 100644 --- a/lib/ftl/ftl_init.c +++ b/lib/ftl/ftl_init.c @@ -132,8 +132,20 @@ static void dev_init_cb(struct spdk_ftl_dev *dev, void *_ctx, int status) { struct ftl_dev_init_ctx *ctx = _ctx; + int rc; if (status) { + if (dev->init_retry) { + FTL_NOTICELOG(dev, "Startup retry\n"); + rc = spdk_ftl_dev_init(&dev->conf, ctx->cb_fn, ctx->cb_arg); + if (!rc) { + free_dev(dev); + free(ctx); + return; + } + FTL_NOTICELOG(dev, "Startup retry failed: %d\n", rc); + } + free_dev(dev); dev = NULL; } diff --git a/lib/ftl/ftl_sb_common.h b/lib/ftl/ftl_sb_common.h index 61e54407c..82b085520 100644 --- a/lib/ftl/ftl_sb_common.h +++ b/lib/ftl/ftl_sb_common.h @@ -47,4 +47,21 @@ struct ftl_superblock_md_region { uint64_t blk_sz; }; +struct ftl_superblock_shm { + /* SHM initialization completed */ + bool shm_ready; + + /* SHM status - fast restart */ + bool shm_clean; + + /* Used to continue trim after SHM recovery */ + struct { + bool in_progress; + uint64_t start_lba; + uint64_t num_blocks; + } trim; + + struct ftl_superblock_gc_info gc_info; +}; + #endif /* FTL_SB_COMMON_H */ diff --git a/lib/ftl/mngt/ftl_mngt_md.c b/lib/ftl/mngt/ftl_mngt_md.c index cabe345be..5b50ef8d5 100644 --- a/lib/ftl/mngt/ftl_mngt_md.c +++ b/lib/ftl/mngt/ftl_mngt_md.c @@ -170,6 +170,7 @@ ftl_mngt_init_default_sb(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt sb->header.version = FTL_METADATA_VERSION_CURRENT; sb->uuid = dev->conf.uuid; sb->clean = 0; + dev->sb_shm->shm_clean = false; /* Max 16 IO depth per band relocate */ sb->max_reloc_qdepth = 16; @@ -191,6 +192,7 @@ ftl_mngt_set_dirty(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) struct ftl_superblock *sb = dev->sb; sb->clean = 0; + dev->sb_shm->shm_clean = false; sb->header.crc = get_sb_crc(sb); persist(dev, mngt, FTL_LAYOUT_REGION_TYPE_SB); } @@ -258,6 +260,18 @@ ftl_mngt_superblock_init(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt FTL_NOTICELOG(dev, "Create new FTL, UUID %s\n", uuid); } + /* Allocate md buf */ + dev->sb_shm = NULL; + dev->sb_shm_md = ftl_md_create(dev, spdk_divide_round_up(sizeof(*dev->sb_shm), FTL_BLOCK_SIZE), + 0, "sb_shm", + md_create_flags, NULL); + if (dev->sb_shm_md == NULL) { + ftl_mngt_fail_step(mngt); + return; + } + + dev->sb_shm = ftl_md_get_buffer(dev->sb_shm_md); + /* Setup the layout of a superblock */ if (ftl_layout_setup_superblock(dev)) { ftl_mngt_fail_step(mngt); @@ -308,5 +322,9 @@ ftl_mngt_superblock_deinit(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mn layout->md[FTL_LAYOUT_REGION_TYPE_SB_BASE] = NULL; } + ftl_md_destroy(dev->sb_shm_md); + dev->sb_shm_md = NULL; + dev->sb_shm = NULL; + ftl_mngt_next_step(mngt); } diff --git a/lib/ftl/mngt/ftl_mngt_misc.c b/lib/ftl/mngt/ftl_mngt_misc.c index 55e8fc5d3..1c3121b7a 100644 --- a/lib/ftl/mngt/ftl_mngt_misc.c +++ b/lib/ftl/mngt/ftl_mngt_misc.c @@ -139,6 +139,7 @@ void ftl_mngt_finalize_startup(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) { dev->initialized = 1; + dev->sb_shm->shm_ready = true; ftl_writer_resume(&dev->writer_user); ftl_writer_resume(&dev->writer_gc); diff --git a/lib/ftl/utils/ftl_md.c b/lib/ftl/utils/ftl_md.c index b29d396f4..45341e362 100644 --- a/lib/ftl/utils/ftl_md.c +++ b/lib/ftl/utils/ftl_md.c @@ -115,6 +115,15 @@ ftl_md_setup_obj(struct ftl_md *md, int flags, } } +static void +ftl_md_invalidate_shm(struct ftl_md *md) +{ + if (md->dev->sb_shm && md->dev->sb_shm->shm_ready) { + md->dev->init_retry = true; + md->dev->sb_shm->shm_ready = false; + } +} + static void ftl_md_create_shm(struct ftl_md *md, uint64_t vss_blksz, int flags) { @@ -138,6 +147,7 @@ ftl_md_create_shm(struct ftl_md *md, uint64_t vss_blksz, int flags) /* If specified, unlink before create a new SHM object */ if (flags & FTL_MD_CREATE_SHM_NEW) { if (md->shm_unlink(md->name) < 0 && errno != ENOENT) { + ftl_md_invalidate_shm(md); return; } open_flags += O_CREAT | O_TRUNC; @@ -215,6 +225,7 @@ err_shm: md->shm_unlink(md->name); md->shm_fd = -1; } + ftl_md_invalidate_shm(md); } static void