]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/bpf: Fix task_local_data failure with 64K page
authorYonghong Song <yonghong.song@linux.dev>
Fri, 23 Jan 2026 05:51:22 +0000 (21:51 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Sun, 25 Jan 2026 00:51:21 +0000 (16:51 -0800)
On arm64 systems with 64K pages, the selftest task_local_data has the following
failures:
  ...
  test_task_local_data_basic:PASS:tld_create_key 0 nsec
  test_task_local_data_basic:FAIL:tld_create_key unexpected tld_create_key: actual 0 != expected -28
  ...
  test_task_local_data_basic_thread:PASS:run task_main 0 nsec
  test_task_local_data_basic_thread:FAIL:task_main retval unexpected error: 2 (errno 0)
  test_task_local_data_basic_thread:FAIL:tld_get_data value0 unexpected tld_get_data value0: actual 0 != expected 6268
  ...
  #447/1   task_local_data/task_local_data_basic:FAIL
  ...
  #447/2   task_local_data/task_local_data_race:FAIL
  #447     task_local_data:FAIL

When TLD_DYN_DATA_SIZE is 64K page size, for
  struct tld_meta_u {
       _Atomic __u8 cnt;
       __u16 size;
        struct tld_metadata metadata[];
  };
field 'cnt' would overflow. For example, for 4K page, 'cnt' will
be 4096/64 = 64. But for 64K page, 'cnt' will be 65536/64 = 1024
and 'cnt' is not enough for 1024. To accommodate 64K page,
'_Atomic __u8 cnt' becomes '_Atomic __u16 cnt'. A few other places
are adjusted accordingly.

In test_task_local_data.c, the value for TLD_DYN_DATA_SIZE is changed
from 4096 to (getpagesize() - 8) since the maximum buffer size for
TLD_DYN_DATA_SIZE is (getpagesize() - 8).

Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
Tested-by: Alan Maguire <alan.maguire@oracle.com>
Cc: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
Acked-by: Amery Hung <ameryhung@gmail.com>
Link: https://lore.kernel.org/r/20260123055122.494352-1-yonghong.song@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/task_local_data.h
tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
tools/testing/selftests/bpf/progs/task_local_data.bpf.h

index 2de38776a2d49972e20b66fcd10489bcf45c1c62..0f86b9275cf98d7303d8109d5e2bb9a10dec1b49 100644 (file)
@@ -94,7 +94,7 @@ struct tld_metadata {
 };
 
 struct tld_meta_u {
-       _Atomic __u8 cnt;
+       _Atomic __u16 cnt;
        __u16 size;
        struct tld_metadata metadata[];
 };
@@ -217,7 +217,7 @@ out:
 static tld_key_t __tld_create_key(const char *name, size_t size, bool dyn_data)
 {
        int err, i, sz, off = 0;
-       __u8 cnt;
+       __u16 cnt;
 
        if (!TLD_READ_ONCE(tld_meta_p)) {
                err = __tld_init_meta_p();
index 9fd6306b455c3c147607df289c92f8a4af931220..9556ad3d986fa9e412952dae03e2b002d5b4ffda 100644 (file)
@@ -4,7 +4,7 @@
 #include <test_progs.h>
 
 #define TLD_FREE_DATA_ON_THREAD_EXIT
-#define TLD_DYN_DATA_SIZE 4096
+#define TLD_DYN_DATA_SIZE (getpagesize() - 8)
 #include "task_local_data.h"
 
 struct test_tld_struct {
index 432fff2af8441ffc9f89268824e02d0f1202a1e0..fed53d63a7e50306685f520e7ce64c4abddddfae 100644 (file)
@@ -80,7 +80,7 @@ struct tld_metadata {
 };
 
 struct tld_meta_u {
-       __u8 cnt;
+       __u16 cnt;
        __u16 size;
        struct tld_metadata metadata[TLD_MAX_DATA_CNT];
 };