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: Kozlowski Mateusz <mateusz.kozlowski@intel.com> Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com> Change-Id: Iaf3812177b61376bb38aa209e4ba8576d784ffb5 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13354 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Mellanox Build Bot Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
e7e5bc07b2
commit
db65602a39
@ -44,7 +44,7 @@ struct ftl_l2p_page {
|
|||||||
enum ftl_l2p_page_state state;
|
enum ftl_l2p_page_state state;
|
||||||
uint64_t pin_ref_cnt;
|
uint64_t pin_ref_cnt;
|
||||||
struct ftl_l2p_cache_page_io_ctx ctx;
|
struct ftl_l2p_cache_page_io_ctx ctx;
|
||||||
bool on_rank_list;
|
bool on_lru_list;
|
||||||
void *page_buffer;
|
void *page_buffer;
|
||||||
ftl_df_obj_id obj_id;
|
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();
|
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 *
|
static void *
|
||||||
_ftl_l2p_cache_init(struct spdk_ftl_dev *dev, size_t addr_size, uint64_t l2p_size)
|
_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;
|
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
|
int
|
||||||
ftl_l2p_cache_init(struct spdk_ftl_dev *dev)
|
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
|
void
|
||||||
ftl_l2p_cache_process(struct spdk_ftl_dev *dev)
|
ftl_l2p_cache_process(struct spdk_ftl_dev *dev)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user