lunatik: percpu groups, one object owning one runtime per CPU - #693
Open
lneto wants to merge 3 commits into
Open
lunatik: percpu groups, one object owning one runtime per CPU#693lneto wants to merge 3 commits into
lneto wants to merge 3 commits into
Conversation
lneto
force-pushed
the
claude_percpu_enforcement
branch
from
August 9, 2026 13:43
e26a81e to
2786065
Compare
lneto
force-pushed
the
claude_percpu_groups
branch
2 times, most recently
from
August 9, 2026 15:00
88060fe to
b30a91c
Compare
lneto
force-pushed
the
claude_percpu_enforcement
branch
from
August 9, 2026 15:09
6b5d4e3 to
fdb5ccd
Compare
lneto
force-pushed
the
claude_percpu_groups
branch
from
August 9, 2026 15:09
b30a91c to
45edfad
Compare
lneto
force-pushed
the
claude_percpu_enforcement
branch
from
August 9, 2026 15:11
fdb5ccd to
9e474bc
Compare
lneto
force-pushed
the
claude_percpu_groups
branch
3 times, most recently
from
August 9, 2026 15:30
172cbe9 to
a7817c8
Compare
lneto
force-pushed
the
claude_percpu_groups
branch
7 times, most recently
from
August 11, 2026 14:35
11bf6f6 to
816942b
Compare
A percpu object owns one runtime per possible CPU id, allocated with alloc_percpu, and lunatik_run resolves it to the instance of the CPU the callback fired on: a plain runtime costs one bit test, so a binding gains dispatch without changing a line. The caller must hold a reference across the call, which is what keeps the instances alive. lunatik_stop splits into closing the state and dropping the reference, so stopping the set leaves the instances reachable until the last reference goes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
env.runtimes held plain script names while env.percpu held one `<script>:<cpu>` key per instance, and every consumer had to know both: the runner looped over CPU ids to run, stop and list, and the XDP kfunc built a per-packet key to look the instance up. A percpu script now registers as one object under its own name, so there is one table, one key and one lookup, and the dispatch happens inside lunatik_run. The runner loses the key convention along with the two-phase shutdown that existed because stopping a percpu script deleted N entries under an iteration that only allows deleting the entry it hands out. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The failing script counted its runs in _ENV, and the plain run at the end of the test left the counter at 1: on the next run of the suite the error fired on the first instance, so the rollback assertion covered the rollback of nothing. Keying the failure on lunatik.cpu() == 1 needs no state, and the plain run passes because a plain runtime has no id. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
lneto
force-pushed
the
claude_percpu_groups
branch
from
August 11, 2026 14:41
816942b to
8246b0d
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.
A percpu script now registers as a single object that owns one runtime per possible CPU id, allocated with
alloc_percpuas the object's private, andlunatik_runresolves it to the instance of the CPU the callback fired on: a plain runtime pays one bit test, so a binding gains dispatch without changing a line. This is the kernel's own shape: one registration, per-CPU data reached through the per-CPU pointer, instead of N registrations filtering by CPU.env.percpuand the<script>:<cpu>key convention are gone: one table, one key, one lookup. The runner loses the per-CPU loops and the two-phase shutdown that existed only because stopping a percpu script deleted N entries under an iteration that allows deleting only the entry it hands out; the XDP kfunc loses the per-packetscnprintfand second hash lookup.runner.startuprefuses a stale_ENV.percpuleft by an older runner, in the mold of the existing restore guard.Dispatch reads the instance with
raw_cpu_ptr: from a preemptible context this is the instance of the CPU the caller happened to be on, which is all a migratable caller can ask for, and it avoids thesmp_processor_idsplat underCONFIG_DEBUG_PREEMPT.This subsumes the registry split of 9b900f5, which existed to separate two key shapes in one table; the object removes the second shape.
Groundwork for the shared-registration layer that will let netfilter and probe opt into percpu (#675): the exactly-once dispatch becomes structural once there is a single hook per script.
The XDP path has no test suite; it was verified by hand on a veth pair with the remote end in a netns, with a minimal XDP program calling
bpf_luaxdp_run: a plain runtime takes every packet on one instance, a percpu script counts them on the instance of the receiving CPU.🤖 Generated with Claude Code