fix: avoid XADD-with-fetch atomic that aborts on older LLVM BPF backends#93
fix: avoid XADD-with-fetch atomic that aborts on older LLVM BPF backends#93raflyhangga wants to merge 1 commit into
Conversation
block_rq_issue used __sync_fetch_and_add's return value against a shared BPF_ARRAY counter to assign req_id, which lowers to a BPF XADD with the BPF_FETCH flag. Older/distro clang BPF backends can't legally emit that and hard-abort the whole process with "LLVM ERROR: Invalid usage of the XADD return value" (uncatchable as a Python exception, since BCC embeds clang/LLVM in-process). Replace the shared atomic counter with a BPF_PERCPU_ARRAY bumped via a plain per-CPU increment, folding the CPU id into the high bits for cross-CPU uniqueness, removing the need for any atomic fetch-and-add entirely. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request resolves a process crash (LLVM ERROR: Invalid usage of the XADD return value) on older LLVM/BCC builds by replacing the shared atomic counter block_req_id_gen with a per-CPU array counter (BPF_PERCPU_ARRAY). The request ID is now generated by combining the SMP processor ID in the high bits with a locally incremented counter, avoiding the need for atomic fetch-and-add operations that require newer LLVM backend support. Additionally, documentation was added to docs/COMPATIBILITY_FIXES.md detailing this fix. There are no review comments, so I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Summary
block_rq_issueassignedreq_idfrom__sync_fetch_and_add(gen, 1)'s return value against a sharedBPF_ARRAYcounter. Using the return value forces clang to lower this to a BPFXADDwith theBPF_FETCHflag, which older/distro-bundled LLVM BPF backends can't legally emit — they hard-abort the whole process withLLVM ERROR: Invalid usage of the XADD return value. Since BCC embeds clang/LLVM in-process, this is an uncatchableSIGABRT, not a Python exception, so it slips right past the existingtry/exceptaround BPF init.BPF_PERCPU_ARRAYbumped via a plain per-CPU increment, foldingbpf_get_smp_processor_id()into the high bits for cross-CPU uniqueness. This removes the need for any atomic fetch-and-add entirely, sidestepping the LLVM-version dependency instead of trying to detect/gate around it. No consumer relies on strict global ordering ofreq_id, only per-request uniqueness/correlation, so this is behavior-neutral.docs/COMPATIBILITY_FIXES.md(new section 5), matching the format of the other real-world compatibility fixes already recorded there.Test plan
grepconfirms no remaining__sync_fetch_and_add/atomic-builtin call sites inprober.c.github/scripts/bpf_smoke.pyas root:prober.ccompiles, all BPF programs load, and the in-kernel verifier passes (both default and-DENABLE_NETWORKbuilds), and all VFS probes attach successfully🤖 Generated with Claude Code