Skip to content

[1289] Fix eBPF kernel 5.10 compatibility: use PERCPU_HASH for rate buckets - #196

Open
ashevadepostman wants to merge 1 commit into
mainfrom
1289_Fix_kernel_compatibility
Open

[1289] Fix eBPF kernel 5.10 compatibility: use PERCPU_HASH for rate buckets#196
ashevadepostman wants to merge 1 commit into
mainfrom
1289_Fix_kernel_compatibility

Conversation

@ashevadepostman

Copy link
Copy Markdown
Collaborator

BPF_ATOMIC instructions (used by __sync_fetch_and_sub / __sync_fetch_and_add in rate_take()) require kernel 5.12+. On kernel 5.10 the verifier rejects them with "BPF_STX uses reserved fields".

Fix: change pid_rate_buckets from BPF_MAP_TYPE_HASH to BPF_MAP_TYPE_PERCPU_HASH. Per-CPU maps give each CPU its own copy of the bucket, eliminating the need for atomic operations entirely. Simple non-atomic decrement is sufficient and correct — the only trade-off is soft over-admission of at most N_CPUs events per refill interval, which is acceptable for a rate limiter.

  • BPF_MAP_TYPE_PERCPU_HASH available since kernel 4.6
  • Removes the 5.12 BPF_ATOMIC dependency
  • Compatible with all kernels >= 5.8 (ringbuf lower bound)
  • Update RefillRateBucket in loader_linux.go to populate all CPU slots
  • Update ratecap tests to verify per-CPU map semantics

…uckets

BPF_ATOMIC instructions (used by __sync_fetch_and_sub / __sync_fetch_and_add
in rate_take()) require kernel 5.12+. On kernel 5.10 the verifier rejects
them with "BPF_STX uses reserved fields".

Fix: change pid_rate_buckets from BPF_MAP_TYPE_HASH to BPF_MAP_TYPE_PERCPU_HASH.
Per-CPU maps give each CPU its own copy of the bucket, eliminating the need
for atomic operations entirely. Simple non-atomic decrement is sufficient and
correct — the only trade-off is soft over-admission of at most N_CPUs events
per refill interval, which is acceptable for a rate limiter.

- BPF_MAP_TYPE_PERCPU_HASH available since kernel 4.6
- Removes the 5.12 BPF_ATOMIC dependency
- Compatible with all kernels >= 5.8 (ringbuf lower bound)
- Update RefillRateBucket in loader_linux.go to populate all CPU slots
- Update ratecap tests to verify per-CPU map semantics

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Attempts to restore eBPF compatibility with Linux 5.10 by using per-CPU rate buckets, but the BPF map and atomic operations remain unchanged.

Changes:

  • Populates and tests per-CPU bucket values.
  • Updates loader documentation and stub formatting.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

File Description
ebpf/loader/ratecap_test.go Adds per-CPU bucket tests.
ebpf/loader/loader_linux.go Writes rate tokens to every CPU slot.
ebpf/loader/loader_stub.go Aligns stub formatting.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +98 to +100
values := make([]uint64, nCPU)
for i := range values {
values[i] = tokens
for i := range values {
values[i] = tokens
}
return l.libssl.PidRateBuckets.Update(&pid, values, ebpf.UpdateAny)
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