ftl: p2l map on shm

Stores P2L map of open bands in shared memory, allowing for
faster recovery times from application crash.

Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Kozlowski Mateusz <mateusz.kozlowski@intel.com>
Change-Id: I519441af05e4d0f57768835bf01c800556873c58
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13347
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Kozlowski Mateusz 2022-07-29 13:16:38 +02:00 committed by Jim Harris
parent 71a1762821
commit 101a039923
6 changed files with 47 additions and 5 deletions

View File

@ -40,6 +40,7 @@ ftl_band_free_p2l_map(struct ftl_band *band)
assert(p2l_map->ref_cnt == 0);
assert(p2l_map->band_map != NULL);
band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
ftl_mempool_put(dev->p2l_pool, p2l_map->band_map);
p2l_map->band_map = NULL;
}
@ -309,6 +310,7 @@ ftl_band_alloc_p2l_map(struct ftl_band *band)
assert(p2l_map->ref_cnt == 0);
assert(p2l_map->band_map == NULL);
assert(band->md->df_p2l_map == FTL_DF_OBJ_ID_INVALID);
p2l_map->band_map = ftl_mempool_get(dev->p2l_pool);
if (!p2l_map->band_map) {
return -1;
@ -319,6 +321,8 @@ ftl_band_alloc_p2l_map(struct ftl_band *band)
return -1;
}
band->md->df_p2l_map = ftl_mempool_get_df_obj_id(dev->p2l_pool, p2l_map->band_map);
/* Set the P2L to FTL_LBA_INVALID */
memset(p2l_map->band_map, -1, FTL_BLOCK_SIZE * ftl_p2l_map_num_blocks(band->dev));

View File

@ -15,6 +15,8 @@
#include "ftl_internal.h"
#include "ftl_core.h"
#include "utils/ftl_df.h"
#define FTL_MAX_OPEN_BANDS 4
#define FTL_BAND_VERSION_0 0
@ -61,6 +63,9 @@ struct ftl_band_md {
/* Number of times band was fully written (ie. number of free -> closed state cycles) */
uint64_t wr_cnt;
/* Durable format object id for P2L map, allocated on shared memory */
ftl_df_obj_id df_p2l_map;
/* CRC32 checksum of the associated P2L map when band is in closed state */
uint32_t p2l_map_checksum;
} __attribute__((aligned(FTL_BLOCK_SIZE)));

View File

@ -79,6 +79,9 @@ struct spdk_ftl_dev {
/* P2L map memory pool */
struct ftl_mempool *p2l_pool;
/* Underlying SHM buf for LBA map mempool */
struct ftl_md *p2l_pool_md;
/* Band md memory pool */
struct ftl_mempool *band_md_pool;

View File

@ -16,6 +16,7 @@ ftl_band_init_md(struct ftl_band *band)
struct ftl_band_md *band_md = ftl_md_get_buffer(band_info_md);
band->md = &band_md[band->id];
band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
return 0;
}
@ -224,6 +225,10 @@ ftl_mngt_finalize_init_bands(struct spdk_ftl_dev *dev, struct ftl_mngt_process *
uint64_t i, num_open = 0, num_shut = 0;
uint64_t offset;
TAILQ_FOREACH_SAFE(band, &dev->free_bands, queue_entry, temp_band) {
band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
}
TAILQ_FOREACH_SAFE(band, &dev->shut_bands, queue_entry, temp_band) {
if (band->md->state == FTL_BAND_STATE_OPEN ||
band->md->state == FTL_BAND_STATE_FULL) {
@ -241,6 +246,8 @@ ftl_mngt_finalize_init_bands(struct spdk_ftl_dev *dev, struct ftl_mngt_process *
} else {
num_shut++;
}
band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
}
/* Assign open bands to writers and alloc necessary resources */
@ -269,6 +276,7 @@ ftl_mngt_finalize_init_bands(struct spdk_ftl_dev *dev, struct ftl_mngt_process *
ftl_band_set_owner(band, ftl_writer_band_state_change, writer);
if (dev->sb->clean) {
band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
if (ftl_band_alloc_p2l_map(band)) {
ftl_mngt_fail_step(mngt);
return;

View File

@ -26,15 +26,25 @@ static int
init_p2l_map_pool(struct spdk_ftl_dev *dev)
{
size_t p2l_pool_el_blks = spdk_divide_round_up(ftl_p2l_map_pool_elem_size(dev), FTL_BLOCK_SIZE);
size_t p2l_pool_buf_blks = P2L_MEMPOOL_SIZE * p2l_pool_el_blks;
void *p2l_pool_buf;
dev->p2l_pool = ftl_mempool_create(P2L_MEMPOOL_SIZE,
p2l_pool_el_blks * FTL_BLOCK_SIZE,
FTL_BLOCK_SIZE,
SPDK_ENV_SOCKET_ID_ANY);
dev->p2l_pool_md = ftl_md_create(dev, p2l_pool_buf_blks, 0, "p2l_pool",
FTL_MD_CREATE_SHM | FTL_MD_CREATE_SHM_NEW, NULL);
if (!dev->p2l_pool_md) {
return -ENOMEM;
}
p2l_pool_buf = ftl_md_get_buffer(dev->p2l_pool_md);
dev->p2l_pool = ftl_mempool_create_ext(p2l_pool_buf, P2L_MEMPOOL_SIZE,
p2l_pool_el_blks * FTL_BLOCK_SIZE,
FTL_BLOCK_SIZE);
if (!dev->p2l_pool) {
return -ENOMEM;
}
ftl_mempool_initialize_ext(dev->p2l_pool);
return 0;
}
@ -70,10 +80,15 @@ void
ftl_mngt_deinit_mem_pools(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
if (dev->p2l_pool) {
ftl_mempool_destroy(dev->p2l_pool);
ftl_mempool_destroy_ext(dev->p2l_pool);
dev->p2l_pool = NULL;
}
if (dev->p2l_pool_md) {
ftl_md_destroy(dev->p2l_pool_md);
dev->p2l_pool_md = NULL;
}
if (dev->band_md_pool) {
ftl_mempool_destroy(dev->band_md_pool);
dev->band_md_pool = NULL;

View File

@ -50,6 +50,12 @@ ftl_mempool_put(struct ftl_mempool *mpool, void *element)
spdk_mempool_put((struct spdk_mempool *)mpool, element);
}
ftl_df_obj_id
ftl_mempool_get_df_obj_id(struct ftl_mempool *mpool, void *df_obj_ptr)
{
return (ftl_df_obj_id)df_obj_ptr;
}
struct spdk_ftl_dev *
test_init_ftl_dev(const struct base_bdev_geometry *geo)
{
@ -107,6 +113,7 @@ test_init_ftl_band(struct spdk_ftl_dev *dev, size_t id, size_t zone_size)
band->id = id;
band->md->state = FTL_BAND_STATE_CLOSED;
band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
TAILQ_INSERT_HEAD(&dev->shut_bands, band, queue_entry);
band->start_addr = zone_size * id;