gbmap: Added gc_repoplookahead_thresh and gc_repopgbmap_thresh
To allow relaxing when LFS3_I_REPOPLOOKAHEAD and LFS3_I_REPOPGBMAP will
be set, potentially reducing gc workload after allocating only a couple
blocks.
The relevant cfg comments have quite a bit more info.
Note -1 (not the default, 0, maybe we should explicitly flip this?)
restores the previous functionality of setting these flags on the first
block allocation.
---
Also tweaked gbmap repops during gc/traversals to _not_ try to repop
unless LFS3_I_REPOPGBMAP is set. We probably should have done this from
the beginning since repopulating the gbmap writes to disk and is
potentially destructive.
Adds code, though hopefully we can claw this back with future config
rework:
code stack ctx
before: 37176 2352 684
after: 37208 (+0.1%) 2352 (+0.0%) 688 (+0.6%)
code stack ctx
gbmap before: 40024 2368 848
gbmap after: 40120 (+0.2%) 2368 (+0.0%) 856 (+0.9%)
This commit is contained in:
@@ -161,6 +161,117 @@ code = '''
|
||||
lfs3_unmount(&lfs3) => 0;
|
||||
'''
|
||||
|
||||
# test that we can relax lookahead repopulation with
|
||||
# gc_repoplookahead_thresh
|
||||
[cases.test_gc_repoplookahead_relaxed]
|
||||
# relax our repop thresh
|
||||
defines.GC_REPOPLOOKAHEAD_THRESH = [
|
||||
'-1',
|
||||
'8*LOOKAHEAD_SIZE - (8*LOOKAHEAD_SIZE/4)',
|
||||
'8*LOOKAHEAD_SIZE - (8*LOOKAHEAD_SIZE/2)',
|
||||
]
|
||||
defines.CKMETA = [false, true]
|
||||
defines.CKDATA = [false, true]
|
||||
defines.GC_FLAGS = '''
|
||||
LFS3_GC_REPOPLOOKAHEAD
|
||||
| ((CKMETA) ? LFS3_GC_CKMETA : 0)
|
||||
| ((CKDATA) ? LFS3_GC_CKDATA : 0)
|
||||
'''
|
||||
defines.GC_STEPS = [-1, 1, 2, 10, 100, 1000]
|
||||
defines.SIZE = 'BLOCK_SIZE'
|
||||
ifdef = 'LFS3_GC'
|
||||
code = '''
|
||||
lfs3_t lfs3;
|
||||
lfs3_format(&lfs3,
|
||||
LFS3_F_RDWR
|
||||
| ((GBMAP) ? LFS3_IFDEF_GBMAP(LFS3_F_GBMAP, -1) : 0),
|
||||
CFG) => 0;
|
||||
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
|
||||
|
||||
uint32_t prng = 42;
|
||||
|
||||
// create a file
|
||||
lfs3_file_t file;
|
||||
lfs3_file_open(&lfs3, &file, "spider",
|
||||
LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
for (lfs3_size_t j = 0; j < SIZE; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||
}
|
||||
lfs3_file_write(&lfs3, &file, wbuf, SIZE) => SIZE;
|
||||
lfs3_file_close(&lfs3, &file) => 0;
|
||||
|
||||
// run GC until we make progress
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
LFS3_ASSERT(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
if (!(fsinfo.flags & LFS3_I_REPOPLOOKAHEAD)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check the file contents
|
||||
lfs3_file_open(&lfs3, &file, "spider", LFS3_O_RDONLY) => 0;
|
||||
uint8_t rbuf[SIZE];
|
||||
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
lfs3_file_close(&lfs3, &file) => 0;
|
||||
|
||||
// rewrite file until we need to repopulate
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
LFS3_ASSERT(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "spider",
|
||||
LFS3_O_WRONLY | LFS3_O_TRUNC) => 0;
|
||||
for (lfs3_size_t j = 0; j < SIZE; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||
}
|
||||
lfs3_file_write(&lfs3, &file, wbuf, SIZE) => SIZE;
|
||||
lfs3_file_close(&lfs3, &file) => 0;
|
||||
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
if (fsinfo.flags & LFS3_I_REPOPLOOKAHEAD) {
|
||||
// check that we actually relaxed repopulations
|
||||
if ((lfs3_size_t)GC_REPOPLOOKAHEAD_THRESH
|
||||
< (lfs3_size_t)(8*LOOKAHEAD_SIZE-1)) {
|
||||
assert(i > 0);
|
||||
} else {
|
||||
assert(i == 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// run GC until we make progress
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
LFS3_ASSERT(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
if (!(fsinfo.flags & LFS3_I_REPOPLOOKAHEAD)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check the file contents
|
||||
lfs3_file_open(&lfs3, &file, "spider", LFS3_O_RDONLY) => 0;
|
||||
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
lfs3_file_close(&lfs3, &file) => 0;
|
||||
|
||||
lfs3_unmount(&lfs3) => 0;
|
||||
'''
|
||||
|
||||
|
||||
# test that repopgbmap can make progress in isolation
|
||||
[cases.test_gc_repopgbmap_progress]
|
||||
@@ -314,6 +425,119 @@ code = '''
|
||||
lfs3_unmount(&lfs3) => 0;
|
||||
'''
|
||||
|
||||
# test that we can relax gbmap repopulation with gc_repopgbmap_thresh
|
||||
[cases.test_gc_repopgbmap_relaxed]
|
||||
# relax our repop thresh
|
||||
defines.GC_REPOPGBMAP_THRESH = [
|
||||
'-1',
|
||||
'BLOCK_COUNT - (BLOCK_COUNT/4)',
|
||||
'BLOCK_COUNT - (BLOCK_COUNT/2)',
|
||||
]
|
||||
defines.REPOPLOOKAHEAD = [false, true]
|
||||
defines.CKMETA = [false, true]
|
||||
defines.CKDATA = [false, true]
|
||||
defines.GC_FLAGS = '''
|
||||
LFS3_GC_REPOPGBMAP
|
||||
| ((REPOPLOOKAHEAD) ? LFS3_GC_REPOPLOOKAHEAD : 0)
|
||||
| ((CKMETA) ? LFS3_GC_CKMETA : 0)
|
||||
| ((CKDATA) ? LFS3_GC_CKDATA : 0)
|
||||
'''
|
||||
defines.GC_STEPS = [-1, 1, 2, 10, 100, 1000]
|
||||
defines.SIZE = 'BLOCK_SIZE'
|
||||
if = 'GBMAP'
|
||||
ifdef = ['LFS3_GC', 'LFS3_GBMAP']
|
||||
code = '''
|
||||
lfs3_t lfs3;
|
||||
lfs3_format(&lfs3,
|
||||
LFS3_F_RDWR
|
||||
| ((GBMAP) ? LFS3_IFDEF_GBMAP(LFS3_F_GBMAP, -1) : 0),
|
||||
CFG) => 0;
|
||||
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
|
||||
|
||||
uint32_t prng = 42;
|
||||
|
||||
// create a file
|
||||
lfs3_file_t file;
|
||||
lfs3_file_open(&lfs3, &file, "spider",
|
||||
LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
for (lfs3_size_t j = 0; j < SIZE; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||
}
|
||||
lfs3_file_write(&lfs3, &file, wbuf, SIZE) => SIZE;
|
||||
lfs3_file_close(&lfs3, &file) => 0;
|
||||
|
||||
// run GC until we make progress
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
LFS3_ASSERT(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
if (!(fsinfo.flags & LFS3_I_REPOPGBMAP)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check the file contents
|
||||
lfs3_file_open(&lfs3, &file, "spider", LFS3_O_RDONLY) => 0;
|
||||
uint8_t rbuf[SIZE];
|
||||
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
lfs3_file_close(&lfs3, &file) => 0;
|
||||
|
||||
// rewrite file until we need to repopulate
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
LFS3_ASSERT(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "spider",
|
||||
LFS3_O_WRONLY | LFS3_O_TRUNC) => 0;
|
||||
for (lfs3_size_t j = 0; j < SIZE; j++) {
|
||||
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||
}
|
||||
lfs3_file_write(&lfs3, &file, wbuf, SIZE) => SIZE;
|
||||
lfs3_file_close(&lfs3, &file) => 0;
|
||||
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
if (fsinfo.flags & LFS3_I_REPOPGBMAP) {
|
||||
// check that we actually relaxed repopulations
|
||||
if ((lfs3_size_t)GC_REPOPGBMAP_THRESH
|
||||
< BLOCK_COUNT-1) {
|
||||
assert(i > 0);
|
||||
} else {
|
||||
assert(i == 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// run GC until we make progress
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
LFS3_ASSERT(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
if (!(fsinfo.flags & LFS3_I_REPOPGBMAP)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check the file contents
|
||||
lfs3_file_open(&lfs3, &file, "spider", LFS3_O_RDONLY) => 0;
|
||||
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
lfs3_file_close(&lfs3, &file) => 0;
|
||||
|
||||
lfs3_unmount(&lfs3) => 0;
|
||||
'''
|
||||
|
||||
|
||||
# test that compactmeta can make progress in isolation
|
||||
[cases.test_gc_compactmeta_progress]
|
||||
|
||||
Reference in New Issue
Block a user