Skip to content

feat(memory): apply kernel memory tunables before memory-mode runs - #507

Open
not-matthias wants to merge 3 commits into
mainfrom
cod-3300-kernel-memory-tunables
Open

feat(memory): apply kernel memory tunables before memory-mode runs#507
not-matthias wants to merge 3 commits into
mainfrom
cod-3300-kernel-memory-tunables

Conversation

@not-matthias

@not-matthias not-matthias commented Aug 18, 2026

Copy link
Copy Markdown
Member

Benchmark repos running codspeed --mode memory currently need a hand-written CI step to stabilise kernel memory behaviour before measuring: disable THP, zero vm.compaction_proactiveness / vm.swappiness / kernel.numa_balancing, swapoff -a, and drop the page cache before each suite.

The runner now does this itself at the start of every memory-mode execution.

Behaviour

  • Applied only when a CI run environment is detected, so developer machines are not silently mutated. Skipped entirely when privileges cannot be elevated without a password prompt.
  • Best effort: a knob that cannot be applied is a warning, never fatal.
  • MemoryTunables::apply() returns a guard holding the previous value of every knob it changed, and restores it on drop — including on the error paths, where teardown() never runs. Only knobs that were not already at the target are captured, and THP is restored to the exact mode it held (madvise stays madvise).
  • swapoff -a is guarded: skipped on zram devices (it permanently resets their disksize) and whenever the swapped pages would not fit in MemAvailable. Restoring re-enables the recorded entries one by one, since swapon -a would miss a swap file absent from /etc/fstab.
  • The page cache drop has no previous state to restore; the node is a write-only trigger.
  • Applied in run() rather than setup(), so the page cache is dropped before every suite and --skip-setup does not bypass it. The sysctl/THP writes are no-ops on later suites since ensure_sysctl compares before writing.

Commits

  1. refactor(executor): move linux_sysctl into executor helpers — pure move, the sysctl primitive is no longer walltime-specific.
  2. feat(memory): apply kernel memory tunables before memory-mode runs

Verification

  • cargo clippy --all-targets clean, cargo test --lib (pre-existing failures on this host are the sudo-requiring tests, which write kernel.kptr_restrict and are identical on main).
  • Local non-CI run logs Not running in CI, skipping kernel memory tunables; host THP unchanged.
  • Privileged container: THP enabled/defrag become [never], vm.compaction_proactiveness = 0, vm.swappiness = 0, and the swap guard correctly logged Leaving swap enabled: swapped pages do not fit in available memory.

The sysctl read-then-write-with-sudo primitive is not walltime-specific;
memory mode needs it too.
@codspeed-hq

codspeed-hq Bot commented Aug 18, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

✅ 17 untouched benchmarks


Comparing cod-3300-kernel-memory-tunables (8bfb28b) with main (3f5123d)

Open in CodSpeed

@not-matthias
not-matthias force-pushed the cod-3300-kernel-memory-tunables branch from febfce2 to a219b76 Compare August 19, 2026 15:40
@not-matthias
not-matthias marked this pull request as ready for review August 19, 2026 15:45
@not-matthias
not-matthias force-pushed the cod-3300-kernel-memory-tunables branch from a219b76 to 3568cec Compare August 19, 2026 15:46
@greptile-apps

greptile-apps Bot commented Aug 19, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds best-effort kernel memory tuning around memory-mode benchmark execution and moves shared sysctl support into executor helpers. It also adds CI gating and restoration guards, but CircleCI is omitted and two host-state restoration paths remain unsafe.

  • Applies THP, sysctl, swap, and page-cache tuning before each memory suite
  • Restores captured THP, sysctl, and swap state through a Drop guard
  • Generalizes Linux sysctl helpers for memory and wall-time executors
  • Adds a run-environment predicate controlling whether host tuning is enabled

Confidence Score: 2/5

The PR should not merge until CircleCI receives the intended tuning and host swap/kernel state is reliably recoverable after partial swapoff failure and forced termination.

The new feature silently skips a supported CI provider and can leave persistent runners with altered host-global memory settings through two reachable cleanup gaps.

Files Needing Attention: src/executor/memory/tunables.rs, src/run_environment/mod.rs

Important Files Changed

Filename Overview
src/executor/memory/tunables.rs Adds the complete tuning guard, but aggregate swapoff failure can lose restoration state and process termination bypasses the only cleanup path.
src/run_environment/mod.rs Adds the CI predicate but omits the already-supported CircleCI provider, disabling the feature there.
src/executor/memory/executor.rs Correctly scopes the guard around each memory run, including ordinary error returns, but necessarily depends on the guard's cleanup guarantees.
src/executor/helpers/linux_sysctl.rs Generalizes sysctl mutation to return previous values while preserving existing wall-time setup behavior.
src/executor/wall_time/profiler/perf/mod.rs Updates the profiling sysctl import after moving the helper.
src/executor/wall_time/profiler/samply/mod.rs Updates the profiling sysctl import after moving the helper.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[MemoryExecutor::run] --> B{Supported CI detected?}
  B -- No --> C[Run without tunables]
  B -- Yes --> D{Passwordless elevation?}
  D -- No --> C
  D -- Yes --> E[Capture and apply THP/sysctl/swap state]
  E --> F[Drop page cache]
  F --> G[Run memtrack benchmark]
  G --> H[MemoryTunables::drop]
  H --> I[Restore swap, sysctls, and THP]
  G -. process termination .-> J[Restoration bypassed]
Loading

Fix all with Greploop Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
### Issue 1
src/run_environment/mod.rs:58-60
**CircleCI bypasses memory tuning**

When a memory-mode run executes on CircleCI, `is_ci_environment()` returns false because it omits the supported CircleCI provider, causing all THP, sysctl, swap, and page-cache stabilization to be skipped.

```suggestion
pub fn is_ci_environment() -> bool {
    BuildkiteProvider::detect()
        || CircleCIProvider::detect()
        || GitHubActionsProvider::detect()
        || GitLabCIProvider::detect()
}
```

### Issue 2
src/executor/memory/tunables.rs:145-148
**Failed swapoff loses restoration state**

If `swapoff -a` disables one swap entry and then fails on another, this branch discards the previously captured entry list, so `Drop` never re-enables the entry already disabled and leaves the host partially swap-disabled.

### Issue 3
src/executor/memory/tunables.rs:48-53
**Forced termination bypasses restoration**

If a memory run is cancelled or killed on a persistent self-hosted CI runner after these host-global settings are applied, process termination bypasses the sole `Drop` restoration path, causing later jobs to inherit disabled swap and altered THP, compaction, swappiness, or NUMA-balancing settings.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: a219b76 | Re-trigger Greptile

Comment thread src/run_environment/mod.rs Outdated
Comment thread src/executor/memory/tunables.rs Outdated
Comment thread src/executor/memory/tunables.rs
Comment thread src/executor/memory/tunables.rs
Comment thread src/executor/memory/tunables.rs Outdated
Comment on lines +1 to +6
//! Kernel knobs that stabilise memory measurements: transparent huge pages,
//! compaction/swap/NUMA-balancing sysctls, swap and the page cache.
//!
//! [`MemoryTunables`] captures the previous value of every knob it changes and
//! restores it on drop, so a host that only looks like CI — `CI=true` inside a
//! container sharing the host's non-namespaced knobs, say — is left as it was.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have some traceability and documentation about these tuneables?

Ideally, each should be individually tested for its variance effect. This is to make sure we are not vibe-disabling swap because opus/fable felt like it was a good idea.

Comment thread src/executor/memory/tunables.rs Outdated
@not-matthias
not-matthias force-pushed the cod-3300-kernel-memory-tunables branch from 3568cec to 4f9378e Compare August 24, 2026 12:38
Disables transparent huge pages, sets vm.compaction_proactiveness,
vm.swappiness and kernel.numa_balancing to 0, disables swap and drops the
page cache, so benchmark repos no longer need a hand-written CI step.

Applied only in CI, best-effort: a knob that cannot be set is a warning.
swapoff is skipped on zram devices and whenever the swapped pages would not
fit in available memory.
Keep the original profiler sysctl values in the walltime executor and restore them when it is dropped. This prevents a local or containerized run from leaving host-global profiling access enabled.
@not-matthias
not-matthias force-pushed the cod-3300-kernel-memory-tunables branch from 755df11 to 8bfb28b Compare August 24, 2026 13:07
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.

2 participants