Fix kperf hardware-counter sampling on Apple Silicon#5
Open
StefanoD wants to merge 1 commit into
Open
Conversation
Fixes D-Berg#4. `sudo crap` panicked on Apple Silicon (M2) before reporting any hardware counters. Two independent bugs in the kperf path: 1. Event lookup used the wrong name. The lookup passed the KpepEventAlias enum tag ("Cycles"/"Instructions") to kpep_db_event(), but the kpep database indexes events by their PMC names ("FIXED_CYCLES", "FIXED_INSTRUCTIONS", ...). The correct names were already listed in the never-called KpepEventAlias.getNames(); consult it and try each candidate. thread panic: unable to start kperf sampling: EventNotFound kperf.zig:366 ... return xnu.Error.EventNotFound 2. Counter-diff underflow. Summing per-thread deltas computed counters_1 - counters_0 as a plain u64 subtraction. Per-thread PMC snapshots are normally monotonic, but on asymmetric P/E cores a thread's accumulated counter can read lower on a later sample (counter virtualization), underflowing the subtraction. Extract addSaturatingDiffs() and saturate so such a thread contributes 0. thread panic: integer overflow kperf.zig:286 ... counter_diffs[i] += t_data.counters_1[i] - t_data.counters_0[i] Add a `zig build test` step and unit tests for both fixes (the saturating diff helper, and that getNames() yields real PMC event names). The kperf code is macOS-only, so the tests are discovered on the macOS target and pruned elsewhere; the executable still cross-compiles to Linux/Windows unchanged. Tested on an M2 (Darwin 25.5): `sudo crap` now reports cpu_cycles / instructions instead of panicking. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
0c5263b to
14fa9ed
Compare
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.
Fixes #4.
Summary
sudo crappanicked on Apple Silicon (M2) before printing any hardware counters. Two independent bugs in the kperf path, plus tests. (#4 reports the first panic on macOS 26; the second surfaces once that's fixed.)1.
EventNotFound— event lookup used the wrong namestartSamplinglooked events up by theKpepEventAliasenum tag ("Cycles","Instructions") instead of the real PMC event names. The kpep database indexes events asFIXED_CYCLES,FIXED_INSTRUCTIONS, … — the exact names already listed inKpepEventAlias.getNames(), which was defined but never called. The fix consultsgetNames()and tries each candidate name.2.
integer overflow— non-monotonic per-thread countersSumming per-thread deltas did
counters_1 - counters_0as a plainu64subtraction. Per-thread PMC snapshots are normally monotonic, but on Apple Silicon's asymmetric P/E cores a thread's accumulated counter can read lower on a later sample (counter virtualization across core types), underflowing the subtraction — a panic in Debug, a garbage wrap in ReleaseFast. ExtractedaddSaturatingDiffs(), which saturates so such a thread contributes0.Tests
Adds a
zig build teststep and unit tests for both fixes:addSaturatingDiffssaturates a backwards counter instead of underflowing.KpepEventAlias.getNames()yields the real PMC event names (FIXED_CYCLES, …), guarding the data the lookup now depends on.The kperf code is macOS-only, so the tests are referenced from
main.zigbehind acomptimemacOS guard — discovered on the macOS target and pruned on Linux/Windows (the executable still cross-compiles unchanged). CI currently runszig build releaseonly; on themacos-latestrunner azig build teststep would exercise these.Verified
M2 (Darwin 25.5). Before: panic (both, sequentially). After:
sudo crapreports counters — e.g. an AES-256-GCM 1200 B seal+open micro-benchmark, RustCrypto software vsring:zig build test→ 3 pass (verified failing when an assertion is broken).zig buildandzig build -Dtarget=x86_64-linuxunchanged.🤖 Generated with Claude Code