Posix memory map optimization and tuning. - #884
Open
evoskuil wants to merge 17 commits into
Open
Conversation
Intent bits age (hot sampling), so a write preempted across release passes loses its declaration: the page settles clean under the write, which lands between the settle copy and installation and is silently discarded (a stale released page, observed as false invalid blocks). An unaged prepare/mark writer count invalidates the conversion instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mark() uncounts the writer counted by prepare(), so unpaired internal mark calls (transfer failure restoration, head expansion backfill) underflow the count: offset negative, in-flight writers read as drained and release settles under them (observed as a rare stale prevout head bucket after expansion). Transfer restores marks by remark_ (marking without the uncount) and the expansion backfill brackets with prepare(). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Anonymous heads with a dirty-page writer keep their content current in the file but leave the pages anonymous, so reclaim under scarcity is swap; release converts only quiet runs, and hash-uniform head writes are never quiet during download. Mapping heads writable-shared makes reclaim kernel writeback of a bounded rewrite-in-place mapping instead, without returning the unbounded append writeback that dirty ratio tuning exists to control (bodies remain staged). Selected by head_shared, which excludes the dirty bitmap, the lazy writer, and release. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Transferring a write-hot head amplifies writes without release payoff: transferred pages re-dirty within seconds and the quiet gate blocks their release regardless, so scarcity passes previously paid full head writeback (every page, every second) on top of swap. A hot instance now leaves its anonymous set to swap (dirty-exempt) until it quiesces, and quiet instances transfer and release as before, so the phase change flips each instance from swap-bound to file-backed with no write storm. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Scarcity clears as swap absorbs the write-hot anonymous set, which stopped conversion exactly when it becomes profitable: the swapped pages stay anonymous and the validation phase faults them back one probe at a time (serial random swap-in for hours). A clean swapped page settles without read-back (the file already holds its content), freeing the swap slot and routing reads through the file mapping, so once engaged a quiet instance now transfers and releases regardless of the momentary scarcity signal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The eviction sweep is inert on linux: MS_INVALIDATE invalidates other mappings of the file but leaves clean pages cached, so streaming body cache pressure stands and the kernel preserves it by swapping the anonymous heads (the observed disaster: the precious random-access set pays disk swap to cache pages that are never read again). Pageout reclaims the mapped range regardless of page table references (dirty pages write back, clean pages drop, later reads fault from the file). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The kernel cannot infer the store's priority: settled bodies are worth caching for imminent re-read (validation follows archival) but never at the price of head residency, while lru ranks a just-read body page above a cold head bucket and swaps the head set to preserve the body cache. Deactivating each settled extent encodes the ordering: cached until pressure, first reclaimed under it, reactivated by an actual read. The open-time settle pass demotes the whole settled prefix, so a fresh open starts cold and promotes only what is hot. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two defects left the body sweep unable to hold the cache down. It lapped the whole body, so with hundreds of gigabytes settled and only the recent tail resident, most of a lap evicted nothing while the tail refilled faster than the cursor returned. And it triggered at the reclaim watermark, conceding victim selection to the kernel, which balances anon against file and swaps the heads it cannot know are the priority. The lap now covers the tail (a lap holds at most physical memory, as nothing below is resident) and the floor leads reclaim. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Measured on a 32GB box: 13.1GB active anonymous heads beside 14.9GB of page cache, of which only 5.6GB is mapped. The unmapped remainder is the transfer itself, as every written head page leaves a cached copy of the write, so the head is resident twice (live anonymous, plus file cache that is never read while the head is resident). That fills memory before any body is cached, and the kernel resolves it by swapping the live copy back in from disk. Discarding after each transfer leaves the anonymous head alone (mapped released runs hold a reference and are skipped). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The population read caches the whole head, duplicating in page cache what it just copied to anonymous memory, so the head is resident twice before a block is processed (measured: 14GB of head files read at load against a 32GB box). The mapped settled prefix holds a reference and is unaffected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.