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>
This commit is contained in:
Yonghong Song 2026-01-22 21:51:22 -08:00 committed by Alexei Starovoitov
parent 82f3b142c9
commit d8df878140
3 changed files with 4 additions and 4 deletions

View 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 @@ static int __tld_init_data_p(int map_fd)
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();

View 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 {

View 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];
};