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:
parent
71a1762821
commit
101a039923
@ -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));
|
||||
|
||||
|
@ -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)));
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user