Commit db65602a authored by Kozlowski Mateusz's avatar Kozlowski Mateusz Committed by Ben Walker
Browse files

FTL: Add l2p cache get/set logic



This commit also introduces ranking pages, based on usage for determining the least used
page to be evicted.

Signed-off-by: default avatarKozlowski Mateusz <mateusz.kozlowski@intel.com>
Signed-off-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Change-Id: Iaf3812177b61376bb38aa209e4ba8576d784ffb5
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13354


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent e7e5bc07
Loading
Loading
Loading
Loading
+106 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ struct ftl_l2p_page {
	enum ftl_l2p_page_state state;
	uint64_t pin_ref_cnt;
	struct ftl_l2p_cache_page_io_ctx ctx;
	bool on_rank_list;
	bool on_lru_list;
	void *page_buffer;
	ftl_df_obj_id obj_id;
};
@@ -149,6 +149,52 @@ ftl_l2p_cache_get_page_all_size(void)
	return sizeof(struct ftl_l2p_page) + ftl_l2p_cache_get_l1_page_size();
}

static void
ftl_l2p_cache_lru_remove_page(struct ftl_l2p_cache *cache, struct ftl_l2p_page *page)
{
	assert(page);
	assert(page->on_lru_list);

	TAILQ_REMOVE(&cache->lru_list, page, list_entry);
	page->on_lru_list = false;
}

static void
ftl_l2p_cache_lru_add_page(struct ftl_l2p_cache *cache, struct ftl_l2p_page *page)
{
	assert(page);
	assert(!page->on_lru_list);

	TAILQ_INSERT_HEAD(&cache->lru_list, page, list_entry);

	page->on_lru_list = true;
}

static void
ftl_l2p_cache_lru_promote_page(struct ftl_l2p_cache *cache, struct ftl_l2p_page *page)
{
	if (!page->on_lru_list) {
		return;
	}

	ftl_l2p_cache_lru_remove_page(cache, page);
	ftl_l2p_cache_lru_add_page(cache, page);
}

static inline ftl_addr
ftl_l2p_cache_get_addr(struct spdk_ftl_dev *dev,
		       struct ftl_l2p_cache *cache, struct ftl_l2p_page *page, uint64_t lba)
{
	return ftl_addr_load(dev, page->page_buffer, lba % cache->lbas_in_page);
}

static inline void
ftl_l2p_cache_set_addr(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache,
		       struct ftl_l2p_page *page, uint64_t lba, ftl_addr addr)
{
	ftl_addr_store(dev, page->page_buffer, lba % cache->lbas_in_page, addr);
}

static void *
_ftl_l2p_cache_init(struct spdk_ftl_dev *dev, size_t addr_size, uint64_t l2p_size)
{
@@ -181,6 +227,19 @@ fail_l2_md:
	return NULL;
}

static struct ftl_l2p_page *
get_l2p_page_by_df_id(struct ftl_l2p_cache *cache, size_t page_no)
{
	struct ftl_l2p_l1_map_entry *me = cache->l2_mapping;
	ftl_df_obj_id obj_id = me[page_no].page_obj_id;

	if (obj_id != FTL_DF_OBJ_ID_INVALID) {
		return ftl_mempool_get_df_ptr(cache->l2_ctx_pool, obj_id);
	}

	return NULL;
}

int
ftl_l2p_cache_init(struct spdk_ftl_dev *dev)
{
@@ -350,6 +409,52 @@ ftl_l2p_cache_halt(struct spdk_ftl_dev *dev)
	}
}

static inline struct ftl_l2p_page *
get_page(struct ftl_l2p_cache *cache, uint64_t lba)
{
	return get_l2p_page_by_df_id(cache, lba / cache->lbas_in_page);
}

static inline bool
ftl_l2p_cache_running(struct ftl_l2p_cache *cache)
{
	return cache->state == L2P_CACHE_RUNNING;
}

ftl_addr
ftl_l2p_cache_get(struct spdk_ftl_dev *dev, uint64_t lba)
{
	assert(dev->num_lbas > lba);
	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
	struct ftl_l2p_page *page = get_page(cache, lba);
	ftl_addr addr;

	ftl_bug(!page);
	assert(ftl_l2p_cache_running(cache));
	assert(page->pin_ref_cnt);

	ftl_l2p_cache_lru_promote_page(cache, page);
	addr = ftl_l2p_cache_get_addr(dev, cache, page, lba);

	return addr;
}

void
ftl_l2p_cache_set(struct spdk_ftl_dev *dev, uint64_t lba, ftl_addr addr)
{
	assert(dev->num_lbas > lba);
	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
	struct ftl_l2p_page *page = get_page(cache, lba);

	ftl_bug(!page);
	assert(ftl_l2p_cache_running(cache));
	assert(page->pin_ref_cnt);

	page->updates++;
	ftl_l2p_cache_lru_promote_page(cache, page);
	ftl_l2p_cache_set_addr(dev, cache, page, lba, addr);
}

void
ftl_l2p_cache_process(struct spdk_ftl_dev *dev)
{