Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

selftests/bpf: Fix task_local_data failure with 64K page

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>

authored by

Yonghong Song and committed by
Alexei Starovoitov
d8df8781 82f3b142

+4 -4
+2 -2
tools/testing/selftests/bpf/prog_tests/task_local_data.h
··· 94 94 }; 95 95 96 96 struct tld_meta_u { 97 - _Atomic __u8 cnt; 97 + _Atomic __u16 cnt; 98 98 __u16 size; 99 99 struct tld_metadata metadata[]; 100 100 }; ··· 217 217 static tld_key_t __tld_create_key(const char *name, size_t size, bool dyn_data) 218 218 { 219 219 int err, i, sz, off = 0; 220 - __u8 cnt; 220 + __u16 cnt; 221 221 222 222 if (!TLD_READ_ONCE(tld_meta_p)) { 223 223 err = __tld_init_meta_p();
+1 -1
tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
··· 4 4 #include <test_progs.h> 5 5 6 6 #define TLD_FREE_DATA_ON_THREAD_EXIT 7 - #define TLD_DYN_DATA_SIZE 4096 7 + #define TLD_DYN_DATA_SIZE (getpagesize() - 8) 8 8 #include "task_local_data.h" 9 9 10 10 struct test_tld_struct {
+1 -1
tools/testing/selftests/bpf/progs/task_local_data.bpf.h
··· 80 80 }; 81 81 82 82 struct tld_meta_u { 83 - __u8 cnt; 83 + __u16 cnt; 84 84 __u16 size; 85 85 struct tld_metadata metadata[TLD_MAX_DATA_CNT]; 86 86 };