Extended emubd to test metastability, added ckprog/ckread tests

Metastability is a rather nasty error condition where successive reads
to a memory location may return different values, either due to bus
issues or a failed prog. It's a tricky error condition to detect, and
one that ckreads was, in theory, supposed to help with.

To help test metastability (and other single-bit errors), emubd gained
several new features:

- LFS_EMUBD_BADBLOCK_PROGFLIP    - Prog flips a bit
- LFS_EMUBD_BADBLOCK_READFLIP    - Read flips a bit sometimes
- LFS_EMUBD_POWERLOSS_METASTABLE - Reads may flip a bit

These only affect a single bit in a given block, but by randomizing
which bit during every erase (and exhaustive bit testing in test_ck) we
should still see some fairly interesting bit-error patterns over time.

It's a bit difficult to test with more than a single bit error because
you can quickly find checksum/parity collisions when fuzz testing. But
there may be other interesting error patterns to look at in the future?

Also the erase_cycles implementation got a bit of a rework since it was
lopsided previously (progs/reads would always error before erases). And
since I was messing with emubd's internals I added lfs_emubd_markbad/
markgood and a few other convenience functions that seem useful:

- lfs_emubd_seed - Manually set the prng, needed in test_ck actually
- lfs_emubd_markbad - Mark block as bad, same as wear=-1
- lfs_emubd_markgood - Mark block as good, same as wear=0
- lfs_emubd_badbit - Get which big failed
- lfs_emubd_setbadbit - Set which bit will fail
- lfs_emubd_randomizebadbit - Randomize bad bit on erase
- lfs_emubd_markbadbit - Mark bit as bad, same as setbadbit+markbad

---

The intention of this new metastability emulation was to extend test_ck
to test ckreads/ckprogs. This went... interestingly.

The good news, the new emulation and tests worked quite well. They were
able to quite quickly show that ckreads is fundamentally not able to
detect all single-bit errors in our current design.

The problem boils down to the fact that the location of our parity bits
depends on the tag's leb128-encoded size. If a bit flip changes this
size field, we end up with a new parity bit, which 50/50 may or may not
detect the error.

For example, one bit flip:

  40 0c 00 12 80 0d ff ff
  '----.----' ^--------------------.
       '- altble 0xc w0 -18 parity=1

  40 0c 80 12 80 0d ff ff
  '-------.-------' ^----------------------.
          '- altble 0xc w2304 -1664 parity=1

This doesn't make ckreads _completely_ useless, just mostly useless. We
can still use it to check parity bits, but without a systematic proof.

But there's enough problems with ckreads: performance, RAM, code, etc,
that I think it may just be an interesting proof-of-concept and not
something users should actually use. Checking reads in the bd-layer
solves all of these problems...

---

At the very least ckprogs gets better testing, thanks to new tests in
test_ck and the addition of LFS_EMUBD_BADBLOCK_PROGFLIP in
test_badblocks.

The extra testing also found a ckprog/ckread hole in that we don't
ckprog/ckread during lfsr_format! I fixed this by making lfsr_format
always use ckprogs/ckreads if available, but maybe lfsr_format should
take its own set of flags?

Funnily enough this had no impact on code size since it probably just
changed the constant in a constant pool:

          code           stack
  before: 37872           3048
  after:  37872 (+0.0%)   3048 (+0.0%)
This commit is contained in:
Christopher Haster
2024-08-10 17:41:51 -05:00
parent 89565ec513
commit 458fe16f38
5 changed files with 1174 additions and 135 deletions
+76 -78
View File
@@ -19,7 +19,6 @@ after = [
# B-tree's ridiculous branching factor is great for performance, but it makes
# them a bit of a pain to test, here we test them explicitly
[cases.test_badblocks_single_btree_many]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK = -1
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
@@ -27,6 +26,7 @@ defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -43,7 +43,7 @@ code = '''
i++) {
lfs_size_t badblock = (BADBLOCK == -1) ? i : BADBLOCK;
// mark our badblock as bad
lfs_emubd_setwear(CFG, badblock, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, badblock) => 0;
printf("--- badblock: 0x%x ---\n", badblock);
// test creating a btree
@@ -124,13 +124,12 @@ code = '''
lfs_deinit(&lfs) => 0;
// reset badblock
lfs_emubd_setwear(CFG, badblock, 0) => 0;
lfs_emubd_markgood(CFG, badblock) => 0;
}
'''
# with dirs
[cases.test_badblocks_single_dir_many]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK = -1
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
@@ -138,6 +137,7 @@ defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -149,7 +149,7 @@ code = '''
i++) {
lfs_size_t badblock = (BADBLOCK == -1) ? i : BADBLOCK;
// mark our badblock as bad
lfs_emubd_setwear(CFG, badblock, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, badblock) => 0;
printf("--- badblock: 0x%x ---\n", badblock);
// test creating directories
@@ -234,13 +234,12 @@ code = '''
lfsr_unmount(&lfs) => 0;
// reset badblock
lfs_emubd_setwear(CFG, badblock, 0) => 0;
lfs_emubd_markgood(CFG, badblock) => 0;
}
'''
# fuzz dirs
[cases.test_badblocks_single_dir_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK = -1
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
@@ -248,6 +247,7 @@ defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -262,7 +262,7 @@ code = '''
i++) {
lfs_size_t badblock = (BADBLOCK == -1) ? i : BADBLOCK;
// mark our badblock as bad
lfs_emubd_setwear(CFG, badblock, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, badblock) => 0;
printf("--- badblock: 0x%x ---\n", badblock);
// test fuzz with dirs
@@ -415,13 +415,12 @@ code = '''
lfsr_unmount(&lfs) => 0;
// reset badblock
lfs_emubd_setwear(CFG, badblock, 0) => 0;
lfs_emubd_markgood(CFG, badblock) => 0;
}
'''
# with files
[cases.test_badblocks_single_file_many]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK = -1
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
@@ -429,6 +428,7 @@ defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -450,7 +450,7 @@ code = '''
i++) {
lfs_size_t badblock = (BADBLOCK == -1) ? i : BADBLOCK;
// mark our badblock as bad
lfs_emubd_setwear(CFG, badblock, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, badblock) => 0;
printf("--- badblock: 0x%x ---\n", badblock);
// test creating files
@@ -519,13 +519,12 @@ code = '''
lfsr_unmount(&lfs) => 0;
// reset badblock
lfs_emubd_setwear(CFG, badblock, 0) => 0;
lfs_emubd_markgood(CFG, badblock) => 0;
}
'''
# fuzz files
[cases.test_badblocks_single_file_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK = -1
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
@@ -533,6 +532,7 @@ defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -557,7 +557,7 @@ code = '''
i++) {
lfs_size_t badblock = (BADBLOCK == -1) ? i : BADBLOCK;
// mark our badblock as bad
lfs_emubd_setwear(CFG, badblock, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, badblock) => 0;
printf("--- badblock: 0x%x ---\n", badblock);
// test fuzz with files
@@ -762,13 +762,12 @@ code = '''
lfsr_unmount(&lfs) => 0;
// reset badblock
lfs_emubd_setwear(CFG, badblock, 0) => 0;
lfs_emubd_markgood(CFG, badblock) => 0;
}
'''
# with more complex file writes
[cases.test_badblocks_single_fwrite_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK = -1
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
@@ -776,6 +775,7 @@ defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -809,7 +809,7 @@ code = '''
i++) {
lfs_size_t badblock = (BADBLOCK == -1) ? i : BADBLOCK;
// mark our badblock as bad
lfs_emubd_setwear(CFG, badblock, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, badblock) => 0;
printf("--- badblock: 0x%x ---\n", badblock);
// test with complex file writes
@@ -927,13 +927,12 @@ code = '''
lfsr_unmount(&lfs) => 0;
// reset badblock
lfs_emubd_setwear(CFG, badblock, 0) => 0;
lfs_emubd_markgood(CFG, badblock) => 0;
}
'''
# with orphans, zombies, etc
[cases.test_badblocks_single_orphanzombie_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK = -1
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
@@ -941,6 +940,7 @@ defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -965,7 +965,7 @@ code = '''
i++) {
lfs_size_t badblock = (BADBLOCK == -1) ? i : BADBLOCK;
// mark our badblock as bad
lfs_emubd_setwear(CFG, badblock, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, badblock) => 0;
printf("--- badblock: 0x%x ---\n", badblock);
// test with orphans, zombies, etc
@@ -1293,13 +1293,12 @@ code = '''
free(sim_files);
lfsr_unmount(&lfs) => 0;
// reset badblock
lfs_emubd_setwear(CFG, badblock, 0) => 0;
lfs_emubd_markgood(CFG, badblock) => 0;
}
'''
# with orphans, zombies, dirs, etc
[cases.test_badblocks_single_orphanzombiedir_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK = -1
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
@@ -1307,6 +1306,7 @@ defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -1331,7 +1331,7 @@ code = '''
i++) {
lfs_size_t badblock = (BADBLOCK == -1) ? i : BADBLOCK;
// mark our badblock as bad
lfs_emubd_setwear(CFG, badblock, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, badblock) => 0;
printf("--- badblock: 0x%x ---\n", badblock);
// test with orphans, zombies, dirs, etc
@@ -1739,7 +1739,7 @@ code = '''
lfsr_unmount(&lfs) => 0;
// reset badblock
lfs_emubd_setwear(CFG, badblock, 0) => 0;
lfs_emubd_markgood(CFG, badblock) => 0;
}
'''
@@ -1753,13 +1753,13 @@ code = '''
# B-tree's ridiculous branching factor is great for performance, but it makes
# them a bit of a pain to test, here we test them explicitly
[cases.test_badblocks_region_btree_many]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -1775,9 +1775,9 @@ code = '''
for (lfs_size_t i = 0; i < BLOCK_COUNT/2; i++) {
// mark our badblock as bad
if (!MIRROR) {
lfs_emubd_setwear(CFG, i, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i) => 0;
} else {
lfs_emubd_setwear(CFG, i + BLOCK_COUNT/2, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i + BLOCK_COUNT/2) => 0;
}
}
@@ -1861,13 +1861,13 @@ code = '''
# with dirs
[cases.test_badblocks_region_dir_many]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -1879,11 +1879,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (i >= 2) {
lfs_emubd_setwear(CFG, i, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i) => 0;
}
} else {
if (i+BLOCK_COUNT/2 >= 2) {
lfs_emubd_setwear(CFG, i+BLOCK_COUNT/2, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i+BLOCK_COUNT/2) => 0;
}
}
}
@@ -1972,13 +1972,13 @@ code = '''
# fuzz dirs
[cases.test_badblocks_region_dir_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -1993,11 +1993,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (i >= 2) {
lfs_emubd_setwear(CFG, i, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i) => 0;
}
} else {
if (i+BLOCK_COUNT/2 >= 2) {
lfs_emubd_setwear(CFG, i+BLOCK_COUNT/2, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i+BLOCK_COUNT/2) => 0;
}
}
}
@@ -2154,13 +2154,13 @@ code = '''
# with files
[cases.test_badblocks_region_file_many]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -2182,11 +2182,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (i >= 2) {
lfs_emubd_setwear(CFG, i, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i) => 0;
}
} else {
if (i+BLOCK_COUNT/2 >= 2) {
lfs_emubd_setwear(CFG, i+BLOCK_COUNT/2, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i+BLOCK_COUNT/2) => 0;
}
}
}
@@ -2259,13 +2259,13 @@ code = '''
# fuzz files
[cases.test_badblocks_region_file_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -2290,11 +2290,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (i >= 2) {
lfs_emubd_setwear(CFG, i, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i) => 0;
}
} else {
if (i+BLOCK_COUNT/2 >= 2) {
lfs_emubd_setwear(CFG, i+BLOCK_COUNT/2, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i+BLOCK_COUNT/2) => 0;
}
}
}
@@ -2503,13 +2503,13 @@ code = '''
# with more complex file writes
[cases.test_badblocks_region_fwrite_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -2543,11 +2543,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (i >= 2) {
lfs_emubd_setwear(CFG, i, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i) => 0;
}
} else {
if (i+BLOCK_COUNT/2 >= 2) {
lfs_emubd_setwear(CFG, i+BLOCK_COUNT/2, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i+BLOCK_COUNT/2) => 0;
}
}
}
@@ -2669,13 +2669,13 @@ code = '''
# with orphans, zombies, etc
[cases.test_badblocks_region_orphanzombie_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -2700,11 +2700,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (i >= 2) {
lfs_emubd_setwear(CFG, i, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i) => 0;
}
} else {
if (i+BLOCK_COUNT/2 >= 2) {
lfs_emubd_setwear(CFG, i+BLOCK_COUNT/2, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i+BLOCK_COUNT/2) => 0;
}
}
}
@@ -3036,13 +3036,13 @@ code = '''
# with orphans, zombies, dirs, etc
[cases.test_badblocks_region_orphanzombiedir_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -3067,11 +3067,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (i >= 2) {
lfs_emubd_setwear(CFG, i, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i) => 0;
}
} else {
if (i+BLOCK_COUNT/2 >= 2) {
lfs_emubd_setwear(CFG, i+BLOCK_COUNT/2, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, i+BLOCK_COUNT/2) => 0;
}
}
}
@@ -3488,13 +3488,13 @@ code = '''
# B-tree's ridiculous branching factor is great for performance, but it makes
# them a bit of a pain to test, here we test them explicitly
[cases.test_badblocks_alternating_btree_many]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -3510,9 +3510,9 @@ code = '''
for (lfs_size_t i = 0; i < BLOCK_COUNT/2; i++) {
// mark our badblock as bad
if (!MIRROR) {
lfs_emubd_setwear(CFG, 2*i+0, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+0) => 0;
} else {
lfs_emubd_setwear(CFG, 2*i+1, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+1) => 0;
}
}
@@ -3596,13 +3596,13 @@ code = '''
# with dirs
[cases.test_badblocks_alternating_dir_many]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -3614,11 +3614,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (2*i+0 >= 2) {
lfs_emubd_setwear(CFG, 2*i+0, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+0) => 0;
}
} else {
if (2*i+1 >= 2) {
lfs_emubd_setwear(CFG, 2*i+1, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+1) => 0;
}
}
}
@@ -3707,13 +3707,13 @@ code = '''
# fuzz dirs
[cases.test_badblocks_alternating_dir_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -3728,11 +3728,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (2*i+0 >= 2) {
lfs_emubd_setwear(CFG, 2*i+0, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+0) => 0;
}
} else {
if (2*i+1 >= 2) {
lfs_emubd_setwear(CFG, 2*i+1, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+1) => 0;
}
}
}
@@ -3889,13 +3889,13 @@ code = '''
# with files
[cases.test_badblocks_alternating_file_many]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -3917,11 +3917,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (2*i+0 >= 2) {
lfs_emubd_setwear(CFG, 2*i+0, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+0) => 0;
}
} else {
if (2*i+1 >= 2) {
lfs_emubd_setwear(CFG, 2*i+1, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+1) => 0;
}
}
}
@@ -3994,13 +3994,13 @@ code = '''
# fuzz files
[cases.test_badblocks_alternating_file_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -4025,11 +4025,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (2*i+0 >= 2) {
lfs_emubd_setwear(CFG, 2*i+0, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+0) => 0;
}
} else {
if (2*i+1 >= 2) {
lfs_emubd_setwear(CFG, 2*i+1, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+1) => 0;
}
}
}
@@ -4238,13 +4238,13 @@ code = '''
# with more complex file writes
[cases.test_badblocks_alternating_fwrite_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -4278,11 +4278,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (2*i+0 >= 2) {
lfs_emubd_setwear(CFG, 2*i+0, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+0) => 0;
}
} else {
if (2*i+1 >= 2) {
lfs_emubd_setwear(CFG, 2*i+1, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+1) => 0;
}
}
}
@@ -4402,13 +4402,13 @@ code = '''
# with orphans, zombies, etc
[cases.test_badblocks_alternating_orphanzombie_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -4433,11 +4433,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (2*i+0 >= 2) {
lfs_emubd_setwear(CFG, 2*i+0, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+0) => 0;
}
} else {
if (2*i+1 >= 2) {
lfs_emubd_setwear(CFG, 2*i+1, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+1) => 0;
}
}
}
@@ -4769,13 +4769,13 @@ code = '''
# with orphans, zombies, dirs, etc
[cases.test_badblocks_alternating_orphanzombiedir_fuzz]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
'LFS_EMUBD_BADBLOCK_ERASEERROR',
'LFS_EMUBD_BADBLOCK_READERROR',
'LFS_EMUBD_BADBLOCK_PROGNOOP',
'LFS_EMUBD_BADBLOCK_ERASENOOP',
'LFS_EMUBD_BADBLOCK_PROGFLIP',
]
# we need prog checking to detect read errors
defines.CKPROGS = 'BADBLOCK_BEHAVIOR >= LFS_EMUBD_BADBLOCK_READERROR'
@@ -4800,11 +4800,11 @@ code = '''
// mark our badblock as bad
if (!MIRROR) {
if (2*i+0 >= 2) {
lfs_emubd_setwear(CFG, 2*i+0, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+0) => 0;
}
} else {
if (2*i+1 >= 2) {
lfs_emubd_setwear(CFG, 2*i+1, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 2*i+1) => 0;
}
}
}
@@ -5218,7 +5218,6 @@ code = '''
# test formatting with 0 or 1 bad, this should just error
[cases.test_badblocks_mrootanchor_format]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCKS = [0x1, 0x2, 0x3]
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
@@ -5229,10 +5228,10 @@ defines.BADBLOCK_BEHAVIOR = [
]
code = '''
if (BADBLOCKS & 0x1) {
lfs_emubd_setwear(CFG, 0, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 0) => 0;
}
if (BADBLOCKS & 0x2) {
lfs_emubd_setwear(CFG, 1, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 1) => 0;
}
lfs_t lfs;
@@ -5241,7 +5240,6 @@ code = '''
# test blocks 0 or 1 going bad, this should just error
[cases.test_badblocks_mrootanchor_wear]
defines.ERASE_CYCLES = 0xffffffff
defines.BADBLOCKS = [0x1, 0x2]
defines.BADBLOCK_BEHAVIOR = [
'LFS_EMUBD_BADBLOCK_PROGERROR',
@@ -5257,10 +5255,10 @@ code = '''
lfsr_format(&lfs, CFG) => 0;
if (BADBLOCKS & 0x1) {
lfs_emubd_setwear(CFG, 0, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 0) => 0;
}
if (BADBLOCKS & 0x2) {
lfs_emubd_setwear(CFG, 1, 0xffffffff) => 0;
lfs_emubd_markbad(CFG, 1) => 0;
}
lfsr_mount(&lfs,