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->ref_cnt == 0);
|
||||||
assert(p2l_map->band_map != NULL);
|
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);
|
ftl_mempool_put(dev->p2l_pool, p2l_map->band_map);
|
||||||
p2l_map->band_map = NULL;
|
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->ref_cnt == 0);
|
||||||
assert(p2l_map->band_map == NULL);
|
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);
|
p2l_map->band_map = ftl_mempool_get(dev->p2l_pool);
|
||||||
if (!p2l_map->band_map) {
|
if (!p2l_map->band_map) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -319,6 +321,8 @@ ftl_band_alloc_p2l_map(struct ftl_band *band)
|
|||||||
return -1;
|
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 */
|
/* Set the P2L to FTL_LBA_INVALID */
|
||||||
memset(p2l_map->band_map, -1, FTL_BLOCK_SIZE * ftl_p2l_map_num_blocks(band->dev));
|
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_internal.h"
|
||||||
#include "ftl_core.h"
|
#include "ftl_core.h"
|
||||||
|
|
||||||
|
#include "utils/ftl_df.h"
|
||||||
|
|
||||||
#define FTL_MAX_OPEN_BANDS 4
|
#define FTL_MAX_OPEN_BANDS 4
|
||||||
|
|
||||||
#define FTL_BAND_VERSION_0 0
|
#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) */
|
/* Number of times band was fully written (ie. number of free -> closed state cycles) */
|
||||||
uint64_t wr_cnt;
|
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 */
|
/* CRC32 checksum of the associated P2L map when band is in closed state */
|
||||||
uint32_t p2l_map_checksum;
|
uint32_t p2l_map_checksum;
|
||||||
} __attribute__((aligned(FTL_BLOCK_SIZE)));
|
} __attribute__((aligned(FTL_BLOCK_SIZE)));
|
||||||
|
@ -79,6 +79,9 @@ struct spdk_ftl_dev {
|
|||||||
/* P2L map memory pool */
|
/* P2L map memory pool */
|
||||||
struct ftl_mempool *p2l_pool;
|
struct ftl_mempool *p2l_pool;
|
||||||
|
|
||||||
|
/* Underlying SHM buf for LBA map mempool */
|
||||||
|
struct ftl_md *p2l_pool_md;
|
||||||
|
|
||||||
/* Band md memory pool */
|
/* Band md memory pool */
|
||||||
struct ftl_mempool *band_md_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);
|
struct ftl_band_md *band_md = ftl_md_get_buffer(band_info_md);
|
||||||
|
|
||||||
band->md = &band_md[band->id];
|
band->md = &band_md[band->id];
|
||||||
|
band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
|
||||||
|
|
||||||
return 0;
|
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 i, num_open = 0, num_shut = 0;
|
||||||
uint64_t offset;
|
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) {
|
TAILQ_FOREACH_SAFE(band, &dev->shut_bands, queue_entry, temp_band) {
|
||||||
if (band->md->state == FTL_BAND_STATE_OPEN ||
|
if (band->md->state == FTL_BAND_STATE_OPEN ||
|
||||||
band->md->state == FTL_BAND_STATE_FULL) {
|
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 {
|
} else {
|
||||||
num_shut++;
|
num_shut++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign open bands to writers and alloc necessary resources */
|
/* 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);
|
ftl_band_set_owner(band, ftl_writer_band_state_change, writer);
|
||||||
|
|
||||||
if (dev->sb->clean) {
|
if (dev->sb->clean) {
|
||||||
|
band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
|
||||||
if (ftl_band_alloc_p2l_map(band)) {
|
if (ftl_band_alloc_p2l_map(band)) {
|
||||||
ftl_mngt_fail_step(mngt);
|
ftl_mngt_fail_step(mngt);
|
||||||
return;
|
return;
|
||||||
|
@ -26,15 +26,25 @@ static int
|
|||||||
init_p2l_map_pool(struct spdk_ftl_dev *dev)
|
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_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,
|
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,
|
p2l_pool_el_blks * FTL_BLOCK_SIZE,
|
||||||
FTL_BLOCK_SIZE,
|
FTL_BLOCK_SIZE);
|
||||||
SPDK_ENV_SOCKET_ID_ANY);
|
|
||||||
if (!dev->p2l_pool) {
|
if (!dev->p2l_pool) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ftl_mempool_initialize_ext(dev->p2l_pool);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,10 +80,15 @@ void
|
|||||||
ftl_mngt_deinit_mem_pools(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
|
ftl_mngt_deinit_mem_pools(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
|
||||||
{
|
{
|
||||||
if (dev->p2l_pool) {
|
if (dev->p2l_pool) {
|
||||||
ftl_mempool_destroy(dev->p2l_pool);
|
ftl_mempool_destroy_ext(dev->p2l_pool);
|
||||||
dev->p2l_pool = NULL;
|
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) {
|
if (dev->band_md_pool) {
|
||||||
ftl_mempool_destroy(dev->band_md_pool);
|
ftl_mempool_destroy(dev->band_md_pool);
|
||||||
dev->band_md_pool = NULL;
|
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);
|
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 *
|
struct spdk_ftl_dev *
|
||||||
test_init_ftl_dev(const struct base_bdev_geometry *geo)
|
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->id = id;
|
||||||
|
|
||||||
band->md->state = FTL_BAND_STATE_CLOSED;
|
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);
|
TAILQ_INSERT_HEAD(&dev->shut_bands, band, queue_entry);
|
||||||
|
|
||||||
band->start_addr = zone_size * id;
|
band->start_addr = zone_size * id;
|
||||||
|
Loading…
Reference in New Issue
Block a user