diff --git a/include/ftl.h b/include/ftl.h index 7fc2318..7cb553f 100644 --- a/include/ftl.h +++ b/include/ftl.h @@ -15,11 +15,14 @@ struct ftl_page_desc { uint32_t subtrees[32]; } __attribute__((packed)); +struct ftl_tlb_entry { + uint32_t va, page; + uint8_t flags; +}; + struct ftl_map { struct flash_dev *dev; - unsigned flags; - uint32_t last_va; - uint32_t last_pa; + struct ftl_tlb_entry outstanding; uint32_t offset; uint32_t head, tail; uint32_t root; @@ -33,9 +36,9 @@ struct ftl_map { uint8_t epoch; }; -#define FTL_CACHED_VA BIT(0) -#define FTL_UNMAPPED BIT(1) -#define FTL_DIRTY BIT(2) +#define FTL_PRESENT BIT(7) +#define FTL_NO_MAPPING BIT(6) +#define FTL_AGE(x) (x & BITS(0, 3)) #define FTL_MAX_ATTEMPTS 8 diff --git a/source/ftl/ftl.c b/source/ftl/ftl.c index 91a1dfb..4803d5b 100644 --- a/source/ftl/ftl.c +++ b/source/ftl/ftl.c @@ -56,30 +56,37 @@ static int ftl_seek(struct ftl_map *map, uint32_t va) offset = va & ((1 << map->log2_page_size) - 1); va >>= map->log2_page_size; - if ((map->flags & FTL_CACHED_VA) && map->last_va != va && - ftl_sync(map) < 0) - return -1; - - if ((ret = trace_path(map, NULL, &page, va)) < 0 && - ret != -ERR_NOT_FOUND) - return -1; - - if (offset < map->offset) - return -1; + if (!(map->outstanding.flags & FTL_PRESENT) || map->outstanding.va != va) { + if (ftl_sync(map) < 0) + return -1; - if (offset == map->offset) - return 0; + if ((ret = trace_path(map, NULL, &page, va)) < 0 && + ret != -ERR_NOT_FOUND) + return -1; - if (map->offset == 0) { if (prepare_head(map) < 0) return -1; - if (ret == -ERR_NOT_FOUND) + map->outstanding.flags |= FTL_PRESENT; + map->outstanding.va = va; + map->outstanding.page = page; + + if (ret == -ERR_NOT_FOUND) { + map->outstanding.flags |= FTL_NO_MAPPING; ++map->nused_pages; + } + + map->offset = 0; } + if (offset < map->offset) + return -1; + + if (offset == map->offset) + return 0; + dst = map->head << map->log2_page_size; - src = page << map->log2_page_size; + src = map->outstanding.page << map->log2_page_size; len = offset - map->offset; if (ret == -ERR_NOT_FOUND) @@ -107,7 +114,6 @@ size_t ftl_write(struct ftl_map *map, uint32_t va, const void *udata, return 0; map->offset += len; - map->flags |= FTL_DIRTY; return len; } @@ -116,21 +122,16 @@ int ftl_sync(struct ftl_map *map) { struct ftl_page_desc page_desc; size_t len; - int ret; - uint32_t page, dst, src; + uint32_t dst, src; - if (!(map->flags & FTL_DIRTY)) + if (!(map->outstanding.flags & FTL_PRESENT)) return 0; - if ((ret = trace_path(map, &page_desc, &page, map->last_va)) < 0 && - ret != -ERR_NOT_FOUND) - return -1; - dst = (map->head << map->log2_page_size) + map->offset; - src = (page << map->log2_page_size) + map->offset; + src = (map->outstanding.page << map->log2_page_size) + map->offset; len = (1 << map->log2_page_size) - map->offset; - if (map->flags & FTL_UNMAPPED) + if (map->outstanding.flags & FTL_NO_MAPPING) flash_write0(map->dev, dst, len); else flash_copy(map->dev, dst, src, len); @@ -141,7 +142,7 @@ int ftl_sync(struct ftl_map *map) return -1; map->offset = 0; - map->flags &= ~(FTL_CACHED_VA | FTL_UNMAPPED | FTL_DIRTY); + map->outstanding.flags = 0; return 0; } diff --git a/source/ftl/map.c b/source/ftl/map.c index 6575fad..ba79d63 100644 --- a/source/ftl/map.c +++ b/source/ftl/map.c @@ -380,9 +380,8 @@ static void reset_map(struct ftl_map *map) map->nblocks = flash_get_size(map->dev) >> map->log2_block_size; - map->flags = 0; - map->last_va = 0; - map->last_pa = 0; + memset(&map->outstanding, 0, sizeof map->outstanding); + map->offset = 0; map->head = 0; map->tail = 0; @@ -459,21 +458,6 @@ int trace_path(struct ftl_map *map, struct ftl_page_desc *new_page_desc, uint8_t depth = 0; uint32_t upage = map->root; -#if 0 - /* FIXME */ - if (!new_page_desc && (map->flags & FTL_CACHED_VA) && map->last_va == va) { - if (map->flags & FTL_UNMAPPED) - return -1; - - if (page) - *page = map->last_pa; - - return 0; - } -#endif - - map->flags &= ~(FTL_CACHED_VA | FTL_UNMAPPED); - if (new_page_desc) new_page_desc->va = va; @@ -509,10 +493,6 @@ int trace_path(struct ftl_map *map, struct ftl_page_desc *new_page_desc, if (page) *page = upage; - map->flags |= FTL_CACHED_VA; - map->last_va = va; - map->last_pa = upage; - return 0; err_not_found: @@ -522,8 +502,5 @@ err_not_found: } } - map->flags |= FTL_CACHED_VA | FTL_UNMAPPED; - map->last_va = va; - return -ERR_NOT_FOUND; } diff --git a/source/tests/ftl/trace_path.c b/source/tests/ftl/trace_path.c index 438ded2..e3dfc9f 100644 --- a/source/tests/ftl/trace_path.c +++ b/source/tests/ftl/trace_path.c @@ -24,7 +24,6 @@ static void test_empty_root(void **state) map.log2_page_size = ilog2(4 * KIB); map.root = UINT32_MAX; - map.flags = 0; ret = __real_trace_path(&map, NULL, &page, 0); @@ -81,7 +80,6 @@ static void test_exact_match(void **state) map.log2_page_size = ilog2(4 * KIB); map.root = 75; - map.flags = 0; expect_value(__wrap_read_page_desc, map, &map); expect_value(__wrap_read_page_desc, upage, 75); @@ -149,7 +147,6 @@ static void test_walk(void **state) map.log2_page_size = ilog2(4 * KIB); map.root = 42; - map.flags = 0; expect_value(__wrap_read_page_desc, map, &map); expect_value(__wrap_read_page_desc, upage, 42);