Skip to content

vm: mergeable guest memory for host KSM dedup - #191

Merged
CMGS merged 1 commit into
masterfrom
feat/mergeable-memory
Aug 7, 2026
Merged

vm: mergeable guest memory for host KSM dedup#191
CMGS merged 1 commit into
masterfrom
feat/mergeable-memory

Conversation

@CMGS

@CMGS CMGS commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

CH already supports --memory ...,mergeable=on (madvise MADV_MERGEABLE on guest memory); cocoon never passed it, so host KSM had zero reachable candidates in VM memory regardless of host tuning. This wires it through as an opt-in create-time flag.

Semantics, mirroring --hugepages/--shared-memory:

  • --mergeable on vm run/vm create, fixed for the VM lifetime; recorded in types.Config, so it rides the snapshot's CH config.json and clones/restores inherit it with no CLI involvement — build the golden with it (or rebuild)
  • excludes --hugepages/--shared-memory: KSM merges only plain private pages, the combo would silently dedup nothing; guarded once in VMConfigFromFlags, the only place the combo can originate
  • FC rejects it in both layers of the existing capability gate: validateBackendFlags fast-fail (create + debug paths) and the backend-owned check in firecracker/create.go
  • cocoon only sets the madvise; enabling/tuning the scanner (/sys/kernel/mm/ksm/*) stays host-side operator policy
  • --memory value building is now shared between launch and vm debug (DebugMemoryCLIArg, same pattern as DebugDiskCLIArgs), so the printed command can't drift from the real one

Acceptance on a 384-core host (fork dev CH, checksum-verified):

  • combo: --mergeable --hugepages--mergeable needs plain private memory; drop --hugepages/--shared-memory
  • FC: --fc --mergeable → fast-fail --fc and --mergeable are mutually exclusive: Firecracker has no KSM madvise knob
  • launch: CH cmdline --memory size=2147483648,mergeable=on
  • inheritance: snapshot config.json carries "mergeable":true; both flag-less clones' run-dir configs show it (2 "mergeable":true)
  • live dedup: KSM enabled, two 2G clones each seeding an identical 512M anon pattern — pages_sharing 0 → 342k pages (~1.34 GB deduplicated) within 20s
  • negative control: same workload without the flag, same scanner settings, 40s → pages_sharing stays 0 (the madvise is the sole gate)
  • host KSM state restored after each run (run=0, pages_to_scan=100, sharing=0)

Gates: make lint (both GOOS) 0 issues, asl ./... (both GOOS) clean, go test ./... green; new TestMemoryCLIArg covers the memory kv for plain/hugepages+shared/mergeable.

Density measurement at fleet scale is deliberately out of scope here — mmap siblings already share untouched pages via the page cache, so KSM's marginal gain (dirtied-but-equal + cross-golden pages) needs measuring on the real workload; the doc note says so.

CH madvises guest memory MADV_MERGEABLE with --memory mergeable=on;
cocoon never passed it, so KSM could not reach VM pages. Opt-in at
create (--mergeable), persists through snapshot/clone/restore via the
snapshot's CH config. Excludes hugepages/shared memory (KSM merges
only plain private pages); FC rejects the flag. Enabling and tuning
the KSM scanner stays host-side operator policy.
@CMGS
CMGS merged commit 52549ed into master Aug 7, 2026
4 checks passed
@CMGS
CMGS deleted the feat/mergeable-memory branch August 7, 2026 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant