bmap: The initial bmapcache algorithm seems to be working

At least at a proof-of-concept level, there's still a lot of cleanup
needed.

To make things work, lfs3_alloc_ckpoint now takes an mdir, which
provides the target for gbmap gstate updates.

When the bmap is close to empty (configurable via bmap_scan_thresh), we
opportunistically rebuild it during lfs3_alloc_ckpoints. The nice thing
about lfs3_alloc_ckpoint is we know the state of all in-flight blocks,
so rebuilding the bmap just requires traversing the filesystem + in-RAM
state.

We might still fall back to the lookahead buffer, but in theory a well
tuned bmap_scan_thresh can prevent this from becoming a bottleneck (at
the cost of more frequent bmap rebuilds).

---

This is also probably a good time to resume measuring code/ram costs,
though it's worth repeating the above note about the bmap work still
needing cleanup:

             code          stack          ctx
  before:   36840           2368          684
  after:    36920 (+0.2%)   2368 (+0.0%)  684 (+0.0%)

Haha, no, the bmap isn't basically free, it's just an opt-in features.
With -DLFS3_YES_BMAP=1:

             code          stack          ctx
  no bmap:  36920           2368          684
  yes bmap: 38552 (+4.4%)   2472 (+4.4%)  812 (+18.7%)
This commit is contained in:
Christopher Haster
2025-07-28 23:27:02 -05:00
parent 8666830515
commit 316ca1cc05
17 changed files with 329 additions and 135 deletions
+11
View File
@@ -568,6 +568,17 @@ struct lfs3_cfg {
#ifndef LFS3_RDONLY
lfs3_size_t crystal_thresh;
#endif
// Threshold for when to rebuild block-map information. littlefs
// will attempt to rebuild the block-map when fewer than this many
// blocks are known. Larger values rebuild the block-map more
// frequently, reducing the chance of falling back to a slower
// allocator at a performance cost.
//
// 0 only rebuilds the block-map when empty.
#ifdef LFS3_BMAP
lfs3_block_t bmap_scan_thresh;
#endif
};
// File info structure