Commit 101a0399 authored by Kozlowski Mateusz's avatar Kozlowski Mateusz Committed by Jim Harris
Browse files

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: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: default avatarKozlowski Mateusz <mateusz.kozlowski@intel.com>
Change-Id: I519441af05e4d0f57768835bf01c800556873c58
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13347


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 71a17628
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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));

+5 −0
Original line number Diff line number Diff line
@@ -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)));
+3 −0
Original line number Diff line number Diff line
@@ -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;

+8 −0
Original line number Diff line number Diff line
@@ -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;
+20 −5
Original line number Diff line number Diff line
@@ -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,
	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,
					   SPDK_ENV_SOCKET_ID_ANY);
					       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;
Loading