Skip to content

[bpf-ci-bot] cgrp_local_storage subtests flaky due to rqspinlock contention in parallel mode #497

Description

@kernel-patches-review-bot

Summary

The cgrp_local_storage/yes_rcu_lock and cgrp_local_storage/cgroup_iter_sleepable subtests fail intermittently in BPF CI when running with parallel execution (-j). The root cause is transient rqspinlock timeout in bpf_local_storage_update(), causing bpf_cgrp_storage_get() to return NULL.

Failure Details

Root Cause Analysis

Commit 8dabe34b9d5b ("bpf: Change local_storage->lock and b->lock to rqspinlock") by Amery Hung converted bpf_local_storage locks from raw_spin_lock to rqspinlock (resilient spinlock). Unlike traditional spinlocks, rqspinlocks have a 250ms timeout (RES_DEF_TIMEOUT in include/asm-generic/rqspinlock.h:62) and can fail with -EDEADLK or -ETIMEDOUT.

In bpf_local_storage_update() (kernel/bpf/bpf_local_storage.c:611):

err = raw_res_spin_lock_irqsave(&local_storage->lock, flags);
if (err)
    goto free_selem;

When this lock times out (due to contention from other tests running in parallel and accessing the same cgroup's local storage), the function returns an error pointer. The caller bpf_cgrp_storage_get() then returns NULL to the BPF program.

The CI log from run 29586716132 confirms this with: update_err: actual -11 != expected 0 (where -11 = -EAGAIN from the cmpxchg race path at bpf_local_storage.c:528 or the empty-list check at line 622).

A diagnostic tracing patch was merged as commit 7c528b364bd8 ("selftests/bpf: Trace bpf_local_storage_update to debug flaky local storage tests") in April 2026 by the same developer, confirming the issue was known but unresolved. No fix has followed in the 3 months since.

Proposed Fix

The attached patch (0001-selftests-bpf-Fix-flaky-cgrp_local_storage-subtests.patch) adds retry logic to both affected subtests:

  1. test_yes_rcu_lock: Retries syscall(SYS_getpgid) up to 5 times with 1ms delays until cgroup_id is set by the BPF program.

  2. test_cgroup_iter_sleepable: Retries the iterator creation and read cycle up to 5 times with 1ms delays, resetting update_err and cgroup_id between attempts.

This is a test-level fix. A complementary kernel-side fix could add retry logic in bpf_local_storage_update() for the specific -EAGAIN case from bpf_local_storage_alloc() (cmpxchg race, line 577-581), since that failure is always transient — the storage was just created by another thread.

Impact

Without this fix, the cgrp_local_storage test will continue to flake in CI parallel mode, blocking unrelated PRs. The flakiness rate is approximately 10-15% of runs (2-3 failures out of 20 examined runs). The retry approach is conservative (5 attempts × 1ms = 5ms worst case) and won't mask genuine regressions since a real bug would fail all 5 retries.

References

  • 8dabe34b9d5b bpf: Change local_storage->lock and b->lock to rqspinlock
  • 7c528b364bd8 selftests/bpf: Trace bpf_local_storage_update to debug flaky local storage tests
  • Lore thread: https://lore.kernel.org/bpf/20260417233631.1443199-1-ameryhung@gmail.com/ (diagnostic patch)
  • include/asm-generic/rqspinlock.h:62 — RES_DEF_TIMEOUT = 250ms
  • kernel/bpf/bpf_local_storage.c:611 — lock timeout propagation path

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions