Reduced scope of ckparity to lfsr_bd_readtag_

Unfortunately ckparity has proven itself to be much less useful than
originally thought.

The use of leb128 encoding in our tags means that ckparity can't even
detect single bit-errors reliably. Which raises the question: is
ckparity really worth all of the extra baggage necessary to track parity
in our codebase?

Fortunately we don't have to toss out ckparity entirely!

If we only check parity bits in lfsr_bd_readtag_, instead of on every
read, we still have a reasonable chance of noticing parity errors during
metadata lookups.

This does weaken ckparity, but allows us to drop a lot of lfsr_data_t's
ckparity baggage, at the cost of no longer, uh, unreliably detecting
parity errors during reads?

The limited error detection of ckparity means we can't reliably detect
errors during reads anyways, so we might as well keep the code/RAM/
maintenance implications at a minimum to make ckparity remotely worth
it.

---

Note the significant savings for both LFS_CKPARITY and LFS_CKCKSUMS.
Tracking parity info in lfsr_data_t had a heavy cost:

                    code          stack           ctx
  default before:  38128           2624           752
  default after:   38128 (+0.0%)   2624 (+0.0%)   752 (+0.0%)

  ckparity before: 39700           3048           760
  ckparity after:  38476 (-3.1%)   2696 (-11.5%)  760 (+0.0%)

  ckcksums before: 39396           3096           760
  ckcksums after:  39240 (-0.4%)   3008 (-2.8%)   752 (-1.1%)

This also means lfsr_ck_ckprefix/cksuffix calls always have a ckoff of 0
(bptrs only), which means even more code savings, yay!
This commit is contained in:
Christopher Haster
2025-01-03 17:54:41 -06:00
parent 7edb3b231f
commit 2e35def6e8
2 changed files with 176 additions and 316 deletions
+8 -12
View File
@@ -166,7 +166,7 @@ enum lfs_type {
#define LFS_F_CKFETCHES 0x00200000 // Check block checksums before first use
#endif
#ifdef LFS_CKPARITY
#define LFS_F_CKPARITY 0x00400000 // Check tag parity bits on reads
#define LFS_F_CKPARITY 0x00400000 // Check metadata tag parity bits
#endif
#ifdef LFS_CKCKSUMS
#define LFS_F_CKCKSUMS 0x00800000 // Check data checksums on reads
@@ -189,7 +189,7 @@ enum lfs_type {
#define LFS_M_CKFETCHES 0x00200000 // Check block checksums before first use
#endif
#ifdef LFS_CKPARITY
#define LFS_M_CKPARITY 0x00400000 // Check tag parity bits on reads
#define LFS_M_CKPARITY 0x00400000 // Check metadata tag parity bits
#endif
#ifdef LFS_CKCKSUMS
#define LFS_M_CKCKSUMS 0x00800000 // Check data checksums on reads
@@ -609,17 +609,13 @@ typedef struct lfsr_omdir {
// lfs_block_t tail[2];
//} lfs_mdir_t;
#if defined(LFS_CKPARITY) || defined(LFS_CKCKSUMS)
#ifdef LFS_CKCKSUMS
// context for validating data
typedef struct lfsr_ck {
// sign(cksize)=0 => cksum check
// sign(cksize)=1 => parity check
// cksize=0 => no checksum
// cksize>0 => yes checksum
lfs_size_t cksize;
union {
// sign(ckoff) => parity
lfs_size_t ckoff;
uint32_t cksum;
} u;
uint32_t cksum;
} lfsr_ck_t;
#endif
@@ -633,7 +629,7 @@ typedef struct lfsr_data {
struct {
lfs_block_t block;
lfs_size_t off;
#if defined(LFS_CKPARITY) || defined(LFS_CKCKSUMS)
#ifdef LFS_CKCKSUMS
lfsr_ck_t ck;
#endif
} disk;
@@ -666,7 +662,7 @@ typedef lfsr_data_t lfsr_sprout_t;
typedef struct lfsr_bptr {
lfsr_data_t data;
#ifndef LFS_CKPARITY
#ifndef LFS_CKCKSUMS
lfs_size_t cksize;
uint32_t cksum;
#endif