]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/bpf: Trace bpf_local_storage_update to debug flaky local storage tests
authorAmery Hung <ameryhung@gmail.com>
Fri, 17 Apr 2026 23:36:31 +0000 (16:36 -0700)
committerKumar Kartikeya Dwivedi <memxor@gmail.com>
Sun, 19 Apr 2026 11:52:50 +0000 (13:52 +0200)
task_local_storage/sys_enter_exit and cgrp_local_storage/
cgroup_iter_sleepable occasionally fail in CI possibly because
bpf_{task,cgrp}_storage_get() returns NULL. Add a fexit probe on
bpf_local_storage_update() to capture the actual error code when this
happens. It will allow us to tell if it is trylock failure in
kmalloc_nolock(), timeout/deadlock in rqspinlock or something else.

Signed-off-by: Amery Hung <ameryhung@gmail.com>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/bpf/20260417233631.1443199-1-ameryhung@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c
tools/testing/selftests/bpf/prog_tests/task_local_storage.c
tools/testing/selftests/bpf/progs/cgrp_ls_sleepable.c
tools/testing/selftests/bpf/progs/task_local_storage.c

index 478a77cb67e6cd584135ec7713e8fa248b1257e8..c4398ccf349396ad4ce16dfd2d5a9814e0cf5d05 100644 (file)
@@ -176,7 +176,7 @@ static void test_cgroup_iter_sleepable(int cgroup_fd, __u64 cgroup_id)
        DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts);
        union bpf_iter_link_info linfo;
        struct cgrp_ls_sleepable *skel;
-       struct bpf_link *link;
+       struct bpf_link *link, *fexit_link;
        int err, iter_fd;
        char buf[16];
 
@@ -200,16 +200,27 @@ static void test_cgroup_iter_sleepable(int cgroup_fd, __u64 cgroup_id)
        if (!ASSERT_OK_PTR(link, "attach_iter"))
                goto out;
 
+       fexit_link = bpf_program__attach(skel->progs.fexit_update);
+       if (!ASSERT_OK_PTR(fexit_link, "attach_fexit"))
+               goto out_link;
+
        iter_fd = bpf_iter_create(bpf_link__fd(link));
        if (!ASSERT_GE(iter_fd, 0, "iter_create"))
-               goto out_link;
+               goto out_fexit_link;
+
+       skel->bss->target_pid = sys_gettid();
 
        /* trigger the program run */
        (void)read(iter_fd, buf, sizeof(buf));
 
+       skel->bss->target_pid = 0;
+
+       ASSERT_EQ(skel->bss->update_err, 0, "update_err");
        ASSERT_EQ(skel->bss->cgroup_id, cgroup_id, "cgroup_id");
 
        close(iter_fd);
+out_fexit_link:
+       bpf_link__destroy(fexit_link);
 out_link:
        bpf_link__destroy(link);
 out:
index 1b26c12f255a74930fd52caa837842ed074e42fe..5b2b56cc3a4f385f2cb4dc67ce18a38a37aac41b 100644 (file)
@@ -47,6 +47,7 @@ static void test_sys_enter_exit(void)
        skel->bss->target_pid = 0;
 
        /* 2x gettid syscalls */
+       ASSERT_EQ(skel->bss->update_err, 0, "update_err");
        ASSERT_EQ(skel->bss->enter_cnt, 2, "enter_cnt");
        ASSERT_EQ(skel->bss->exit_cnt, 2, "exit_cnt");
        ASSERT_EQ(skel->bss->mismatch_cnt, 0, "mismatch_cnt");
index a2de95f85648bb60a9ad19ca836cd7af074c4096..37bd6b03ba0144cc98f837a67fcff2f656413588 100644 (file)
@@ -4,6 +4,7 @@
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>
 #include "bpf_misc.h"
+#include "err.h"
 
 char _license[] SEC("license") = "GPL";
 
@@ -16,6 +17,7 @@ struct {
 
 __s32 target_pid;
 __u64 cgroup_id;
+long update_err;
 int target_hid;
 bool is_cgroup1;
 
@@ -123,3 +125,19 @@ int yes_rcu_lock(void *ctx)
        bpf_rcu_read_unlock();
        return 0;
 }
+
+SEC("fexit/bpf_local_storage_update")
+int BPF_PROG(fexit_update, void *owner, struct bpf_local_storage_map *smap,
+            void *value, u64 map_flags, bool swap_uptrs,
+            struct bpf_local_storage_data *ret)
+{
+       struct task_struct *task = bpf_get_current_task_btf();
+
+       if (task->pid != target_pid)
+               return 0;
+
+       if (IS_ERR_VALUE(ret))
+               update_err = PTR_ERR(ret);
+
+       return 0;
+}
index 80a0a20db88d2c6f26dade9ebd42330074ed41b6..34fa3d6451d2ec66bd2d715ebcbaf61a937a780e 100644 (file)
@@ -14,12 +14,15 @@ struct {
        __type(value, long);
 } enter_id SEC(".maps");
 
+#include "err.h"
+
 #define MAGIC_VALUE 0xabcd1234
 
 pid_t target_pid = 0;
 int mismatch_cnt = 0;
 int enter_cnt = 0;
 int exit_cnt = 0;
+long update_err = 0;
 
 SEC("tp_btf/sys_enter")
 int BPF_PROG(on_enter, struct pt_regs *regs, long id)
@@ -62,3 +65,19 @@ int BPF_PROG(on_exit, struct pt_regs *regs, long id)
                __sync_fetch_and_add(&mismatch_cnt, 1);
        return 0;
 }
+
+SEC("fexit/bpf_local_storage_update")
+int BPF_PROG(fexit_update, void *owner, struct bpf_local_storage_map *smap,
+            void *value, u64 map_flags, bool swap_uptrs,
+            struct bpf_local_storage_data *ret)
+{
+       struct task_struct *task = bpf_get_current_task_btf();
+
+       if (task->pid != target_pid)
+               return 0;
+
+       if (IS_ERR_VALUE(ret))
+               update_err = PTR_ERR(ret);
+
+       return 0;
+}