ftl: maintain state for the transaction that is currently active
This commit is contained in:
parent
e40bd819d6
commit
65d269e2d4
4 changed files with 38 additions and 60 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -56,13 +56,28 @@ 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 (!(map->outstanding.flags & FTL_PRESENT) || map->outstanding.va != va) {
|
||||
if (ftl_sync(map) < 0)
|
||||
return -1;
|
||||
|
||||
if ((ret = trace_path(map, NULL, &page, va)) < 0 &&
|
||||
ret != -ERR_NOT_FOUND)
|
||||
return -1;
|
||||
if ((ret = trace_path(map, NULL, &page, va)) < 0 &&
|
||||
ret != -ERR_NOT_FOUND)
|
||||
return -1;
|
||||
|
||||
if (prepare_head(map) < 0)
|
||||
return -1;
|
||||
|
||||
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;
|
||||
|
@ -70,16 +85,8 @@ static int ftl_seek(struct ftl_map *map, uint32_t va)
|
|||
if (offset == map->offset)
|
||||
return 0;
|
||||
|
||||
if (map->offset == 0) {
|
||||
if (prepare_head(map) < 0)
|
||||
return -1;
|
||||
|
||||
if (ret == -ERR_NOT_FOUND)
|
||||
++map->nused_pages;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue