bio: a buffer cache that grows to 1/32 of RAM, looked up by hash
The cache was NBUF buffers, 1 MB, on every machine: enough for one with tens of megabytes and nothing on one with gigabytes, which re-read the same directory and binary blocks off the disk for every command. It still starts as those 256 in the kernel image, and a miss with every buffer busy now makes a new one rather than evicting, up to 1/32 of RAM or 256 MB. Growing on demand means nothing is spent that is not used, and binit() needs nothing from the page allocator. Lookups go through a hash on (dev, blockno) instead of walking the LRU list, and bflush() walks a creation-order list with an unlocked filter first, so neither costs more at 65536 buffers than it did at 256. struct buf's data is a pointer to its own page now; the drivers copy through their own DMA buffers, so where it sits does not matter. On a 2 GB QEMU guest: a 40 MB file read back in 0.89 s instead of 1.83, the big binaries in 0.17 s instead of 0.26. /proc/fsstat shows the cache as buf_cached now / most. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
51983144e3
commit
62d2a85ac8
4 changed files with 179 additions and 26 deletions
|
|
@ -30,6 +30,7 @@
|
|||
#include "spinlock.h"
|
||||
#include "sleeplock.h"
|
||||
#include "fs.h"
|
||||
#include "buf.h"
|
||||
#include "file.h"
|
||||
#include "proc.h"
|
||||
#include "uaccess.h"
|
||||
|
|
@ -299,8 +300,14 @@ gen_fsstat(struct sbuf *sb)
|
|||
sb_puts(sb, "\nfile_peak "); sb_putu(sb, fsstat.file_peak);
|
||||
sb_puts(sb, " / "); sb_putu(sb, NFILE);
|
||||
sb_puts(sb, "\nbuf_pinned "); sb_putu(sb, fsstat.buf_pinned);
|
||||
sb_puts(sb, "\nbuf_pinned_peak "); sb_putu(sb, fsstat.buf_pinned_peak);
|
||||
sb_puts(sb, " / "); sb_putu(sb, NBUF);
|
||||
{
|
||||
uint nb, maxb;
|
||||
bcache_size(&nb, &maxb);
|
||||
sb_puts(sb, "\nbuf_pinned_peak "); sb_putu(sb, fsstat.buf_pinned_peak);
|
||||
sb_puts(sb, " / "); sb_putu(sb, nb);
|
||||
sb_puts(sb, "\nbuf_cached "); sb_putu(sb, nb);
|
||||
sb_puts(sb, " / "); sb_putu(sb, maxb);
|
||||
}
|
||||
|
||||
// The SchFS bracket. `locked 1` with `owner 0` is the wedge: the volume lock
|
||||
// is held by something that is not in a transaction, so nothing will ever
|
||||
|
|
|
|||
Loading…
Reference in a new issue