Skip to content

Windows: stop full process-table CPU sampling on every session (rebase of #13405) - #14955

Draft
oz-by-warp[bot] wants to merge 1 commit into
masterfrom
oz/13405-rebase-onto-master
Draft

Windows: stop full process-table CPU sampling on every session (rebase of #13405)#14955
oz-by-warp[bot] wants to merge 1 commit into
masterfrom
oz/13405-rebase-onto-master

Conversation

@oz-by-warp

@oz-by-warp oz-by-warp Bot commented Aug 11, 2026

Copy link
Copy Markdown

Description

This is @npapano42's #13405 rebased onto the latest master (no content changes), so it can be reviewed against current master and the latest version of the review skills.

Why a new branch instead of force-pushing the original PR branch: #13405 is from a fork (npapano42/warp), and pushing the rebased commit there was rejected — a GitHub App cannot create or update .github/workflows/* without the workflows permission, and rebasing onto current master necessarily carries updated workflow files (e.g. .github/workflows/changelog_draft.yml). So the rebased commit is pushed to a branch in this repo instead.

Original description, from #13405:

On Windows, is_kaspersky_running() enumerated the entire system process table with per-process CPU cycle-time sampling on every terminal session bootstrap (every tab/pane/subshell/SSH session), with no cache — solely to check whether a process named avp (Kaspersky) exists.

On Windows, per-process CPU sampling makes the kernel issue NtQueryInformationProcess(ProcessCycleTime) for every process, and the full enumeration issues NtQuerySystemInformation(SystemProcessInformation). Both force KeFlushProcessWriteBuffers, which broadcasts a synchronous inter-processor interrupt to every logical core. Across the whole process table, in bursts of session inits, on high-core-count machines (worse with HVCI, where each IPI is a hypercall) this keeps all cores spinning at DISPATCH_LEVEL long enough to trip the DPC watchdog and bugcheck the system (DPC_WATCHDOG_VIOLATION 0x133).

Fix

  1. app/src/system/info.rsrefresh_all_processes() now uses a dedicated name-only ProcessRefreshKind (all_processes_refresh_kind()ProcessRefreshKind::nothing()) instead of the CPU+memory refresh_kind() used by the single-PID self-poll. Process names are still populated, so processes_by_name("avp") is unchanged.
  2. app/src/util/windows.rsis_kaspersky_running() is cached in a OnceLock<bool>, so the full sweep runs at most once per launch instead of on every session bootstrap.

Linked Issue

Fixes #13404. Supersedes #13405 (same single commit, rebased).

  • The linked issue is labeled ready-to-spec or ready-to-implement.
  • Where appropriate, screenshots or a short video of the implementation are included below. (N/A — no UI change.)

Testing

Original author's testing (Windows 11, Ryzen 9 5900X, HVCI on) is described in #13405, including the regression test app/src/system/info_tests.rs::all_processes_refresh_kind_does_not_sample_cpu_or_memory and a standalone sysinfo probe confirming names are still populated under the name-only refresh.

Verification of the rebase itself, on this branch at current master:

  • Rebase applied cleanly with no conflicts; the diff versus master is byte-identical to the original commit's diff.

  • ./script/format --check → clean.

  • cargo clippy -p warp --all-targets --tests -- -D warnings → clean.

  • cargo check -p warp --all-targets → clean.

  • Running the unit test itself in this sandbox OOM'd while linking the warp lib test binary, so it was not re-executed here; it is a pure assertion over ProcessRefreshKind flags and type-checks under clippy --all-targets.

  • I have manually tested my changes locally with ./script/run

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

CHANGELOG-BUG-FIX: Windows — stopped enumerating the full process table with per-process CPU sampling on every terminal session, which could cause DPC_WATCHDOG_VIOLATION / high CPU on machines with many cores.

Conversation: https://app.warp.dev/conversation/3f7e68c2-5574-4bd2-8eb0-42c13931321f
Run: https://oz.warp.dev/runs/019ff261-4ae9-79b5-968a-2e3e41581388

This PR was generated with Oz.

is_kaspersky_running() enumerated the entire process table with per-process
CPU cycle-time sampling on every terminal session bootstrap, just to check
whether "avp" (Kaspersky) is running. On Windows each per-process CPU sample
issues NtQueryInformationProcess(ProcessCycleTime), which forces
KeFlushProcessWriteBuffers -- a synchronous inter-processor interrupt to every
logical core. Across the whole process table, in bursts of session inits, on
high-core-count machines this keeps all cores spinning at DISPATCH_LEVEL long
enough to trip the DPC watchdog and bugcheck the system
(DPC_WATCHDOG_VIOLATION 0x133). Confirmed via a kernel dump on a 24-thread
Ryzen 9 5900X with Memory Integrity/HVCI enabled.

Fix:
- refresh_all_processes() now uses a name-only ProcessRefreshKind
  (all_processes_refresh_kind) instead of the CPU+memory self-poll kind,
  eliminating the per-process ProcessCycleTime syscalls. Names are still
  populated, so the Kaspersky name check is unchanged.
- Cache is_kaspersky_running() in a OnceLock so the full sweep runs at most
  once per launch instead of on every session bootstrap.

Adds a regression test asserting the full-table sweep samples neither CPU nor
memory while the single-PID self-poll still does.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

1 participant