All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data failure with 64K page
@ 2026-01-22 16:26 Yonghong Song
  2026-01-22 16:26 ` [PATCH bpf-next v2 2/2] selftests/bpf: Fix xdp_pull_data " Yonghong Song
  2026-01-22 21:49 ` [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data " Amery Hung
  0 siblings, 2 replies; 11+ messages in thread
From: Yonghong Song @ 2026-01-22 16:26 UTC (permalink / raw)
  To: bpf
  Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team,
	Martin KaFai Lau, Alan Maguire, Amery Hung

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[];
  };
fields 'cnt' and 'size' 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.
For field 'size', it is okay for value 4K, but it is not enough
for 64K as maximum 'size' value is '64K - 1'.

To accommodate 64K page, '_Atomic __u8 cnt' becomes '_Atomic __u16 cnt'
and '__u16 size' becomes '__u32 size'. A few other places are adjusted
accordingly.

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>
---
 tools/testing/selftests/bpf/prog_tests/task_local_data.h    | 6 +++---
 .../testing/selftests/bpf/prog_tests/test_task_local_data.c | 2 +-
 tools/testing/selftests/bpf/progs/task_local_data.bpf.h     | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/task_local_data.h b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
index 2de38776a2d4..4c38f9a7bc90 100644
--- a/tools/testing/selftests/bpf/prog_tests/task_local_data.h
+++ b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
@@ -94,8 +94,8 @@ struct tld_metadata {
 };
 
 struct tld_meta_u {
-	_Atomic __u8 cnt;
-	__u16 size;
+	_Atomic __u16 cnt;
+	__u32 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();
diff --git a/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c b/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
index 9fd6306b455c..cc4d49222d9d 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
@@ -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()
 #include "task_local_data.h"
 
 struct test_tld_struct {
diff --git a/tools/testing/selftests/bpf/progs/task_local_data.bpf.h b/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
index 432fff2af844..e13f239b46b0 100644
--- a/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
+++ b/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
@@ -80,8 +80,8 @@ struct tld_metadata {
 };
 
 struct tld_meta_u {
-	__u8 cnt;
-	__u16 size;
+	__u16 cnt;
+	__u32 size;
 	struct tld_metadata metadata[TLD_MAX_DATA_CNT];
 };
 
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH bpf-next v2 2/2] selftests/bpf: Fix xdp_pull_data failure with 64K page
  2026-01-22 16:26 [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data failure with 64K page Yonghong Song
@ 2026-01-22 16:26 ` Yonghong Song
  2026-01-22 21:18   ` Amery Hung
  2026-01-22 21:49 ` [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data " Amery Hung
  1 sibling, 1 reply; 11+ messages in thread
From: Yonghong Song @ 2026-01-22 16:26 UTC (permalink / raw)
  To: bpf
  Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team,
	Martin KaFai Lau, Alan Maguire, Amery Hung

If the argument 'pull_len' of run_test() is 'PULL_MAX' or
'PULL_MAX | PULL_PLUS_ONE', the eventual pull_len size
will close to the page size. On arm64 systems with 64K pages,
the pull_len size will be close to 64K. But the existing buffer
will be close to 9000 which is not enough to pull.

For those failed run_tests(), make buff size to
  2 * pg_sz + (pg_sz / 2)
This way, there will be enough buffer space to pull
regardless of page size.

Tested-by: Alan Maguire <alan.maguire@oracle.com>
Cc: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
 .../testing/selftests/bpf/prog_tests/xdp_pull_data.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

Changelog:
 v1 -> v2:
   - v1: https://lore.kernel.org/bpf/20260120210930.2544950-1-yonghong.song@linux.dev/
   - Use pg_sz to simplify buff_len calculation.

diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
index efa350d04ec5..35f0eb5b43f3 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
@@ -114,12 +114,14 @@ static void test_xdp_pull_data_basic(void)
 {
 	u32 pg_sz, max_meta_len, max_data_len;
 	struct test_xdp_pull_data *skel;
+	int buff_len;
 
 	skel = test_xdp_pull_data__open_and_load();
 	if (!ASSERT_OK_PTR(skel, "test_xdp_pull_data__open_and_load"))
 		return;
 
 	pg_sz = sysconf(_SC_PAGE_SIZE);
+	buff_len = 2 * pg_sz + pg_sz / 2;
 
 	if (find_xdp_sizes(skel, pg_sz))
 		goto out;
@@ -140,13 +142,13 @@ static void test_xdp_pull_data_basic(void)
 	run_test(skel, XDP_PASS, pg_sz, 9000, 0, 1025, 1025);
 
 	/* multi-buf pkt, empty linear data area, pull requires memmove */
-	run_test(skel, XDP_PASS, pg_sz, 9000, 0, 0, PULL_MAX);
+	run_test(skel, XDP_PASS, pg_sz, buff_len, 0, 0, PULL_MAX);
 
 	/* multi-buf pkt, no headroom */
-	run_test(skel, XDP_PASS, pg_sz, 9000, max_meta_len, 1024, PULL_MAX);
+	run_test(skel, XDP_PASS, pg_sz, buff_len, max_meta_len, 1024, PULL_MAX);
 
 	/* multi-buf pkt, no tailroom, pull requires memmove */
-	run_test(skel, XDP_PASS, pg_sz, 9000, 0, max_data_len, PULL_MAX);
+	run_test(skel, XDP_PASS, pg_sz, buff_len, 0, max_data_len, PULL_MAX);
 
 	/* Test cases with invalid pull length */
 
@@ -154,7 +156,7 @@ static void test_xdp_pull_data_basic(void)
 	run_test(skel, XDP_DROP, pg_sz, 2048, 0, 2048, 2049);
 
 	/* multi-buf pkt with no space left in linear data area */
-	run_test(skel, XDP_DROP, pg_sz, 9000, max_meta_len, max_data_len,
+	run_test(skel, XDP_DROP, pg_sz, buff_len, max_meta_len, max_data_len,
 		 PULL_MAX | PULL_PLUS_ONE);
 
 	/* multi-buf pkt, empty linear data area */
@@ -165,7 +167,7 @@ static void test_xdp_pull_data_basic(void)
 		 PULL_MAX | PULL_PLUS_ONE);
 
 	/* multi-buf pkt, no tailroom */
-	run_test(skel, XDP_DROP, pg_sz, 9000, 0, max_data_len,
+	run_test(skel, XDP_DROP, pg_sz, buff_len, 0, max_data_len,
 		 PULL_MAX | PULL_PLUS_ONE);
 
 out:
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v2 2/2] selftests/bpf: Fix xdp_pull_data failure with 64K page
  2026-01-22 16:26 ` [PATCH bpf-next v2 2/2] selftests/bpf: Fix xdp_pull_data " Yonghong Song
@ 2026-01-22 21:18   ` Amery Hung
  2026-01-22 21:28     ` Yonghong Song
  2026-01-22 21:38     ` Yonghong Song
  0 siblings, 2 replies; 11+ messages in thread
From: Amery Hung @ 2026-01-22 21:18 UTC (permalink / raw)
  To: Yonghong Song
  Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	kernel-team, Martin KaFai Lau, Alan Maguire

On Thu, Jan 22, 2026 at 8:56 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>
> If the argument 'pull_len' of run_test() is 'PULL_MAX' or
> 'PULL_MAX | PULL_PLUS_ONE', the eventual pull_len size
> will close to the page size. On arm64 systems with 64K pages,
> the pull_len size will be close to 64K. But the existing buffer
> will be close to 9000 which is not enough to pull.
>
> For those failed run_tests(), make buff size to
>   2 * pg_sz + (pg_sz / 2)
> This way, there will be enough buffer space to pull
> regardless of page size.
>
> Tested-by: Alan Maguire <alan.maguire@oracle.com>
> Cc: Amery Hung <ameryhung@gmail.com>
> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
> ---
>  .../testing/selftests/bpf/prog_tests/xdp_pull_data.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
>
> Changelog:
>  v1 -> v2:
>    - v1: https://lore.kernel.org/bpf/20260120210930.2544950-1-yonghong.song@linux.dev/
>    - Use pg_sz to simplify buff_len calculation.
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
> index efa350d04ec5..35f0eb5b43f3 100644
> --- a/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
> +++ b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
> @@ -114,12 +114,14 @@ static void test_xdp_pull_data_basic(void)
>  {
>         u32 pg_sz, max_meta_len, max_data_len;
>         struct test_xdp_pull_data *skel;
> +       int buff_len;
>
>         skel = test_xdp_pull_data__open_and_load();
>         if (!ASSERT_OK_PTR(skel, "test_xdp_pull_data__open_and_load"))
>                 return;
>
>         pg_sz = sysconf(_SC_PAGE_SIZE);
> +       buff_len = 2 * pg_sz + pg_sz / 2;

Thanks for fixing the test. Just curious if there is an issue with 1.5
pg_sz as suggested by Alan?

>
>         if (find_xdp_sizes(skel, pg_sz))
>                 goto out;
> @@ -140,13 +142,13 @@ static void test_xdp_pull_data_basic(void)
>         run_test(skel, XDP_PASS, pg_sz, 9000, 0, 1025, 1025);
>
>         /* multi-buf pkt, empty linear data area, pull requires memmove */
> -       run_test(skel, XDP_PASS, pg_sz, 9000, 0, 0, PULL_MAX);
> +       run_test(skel, XDP_PASS, pg_sz, buff_len, 0, 0, PULL_MAX);
>
>         /* multi-buf pkt, no headroom */
> -       run_test(skel, XDP_PASS, pg_sz, 9000, max_meta_len, 1024, PULL_MAX);
> +       run_test(skel, XDP_PASS, pg_sz, buff_len, max_meta_len, 1024, PULL_MAX);
>
>         /* multi-buf pkt, no tailroom, pull requires memmove */
> -       run_test(skel, XDP_PASS, pg_sz, 9000, 0, max_data_len, PULL_MAX);
> +       run_test(skel, XDP_PASS, pg_sz, buff_len, 0, max_data_len, PULL_MAX);
>
>         /* Test cases with invalid pull length */
>
> @@ -154,7 +156,7 @@ static void test_xdp_pull_data_basic(void)
>         run_test(skel, XDP_DROP, pg_sz, 2048, 0, 2048, 2049);
>
>         /* multi-buf pkt with no space left in linear data area */
> -       run_test(skel, XDP_DROP, pg_sz, 9000, max_meta_len, max_data_len,
> +       run_test(skel, XDP_DROP, pg_sz, buff_len, max_meta_len, max_data_len,
>                  PULL_MAX | PULL_PLUS_ONE);
>
>         /* multi-buf pkt, empty linear data area */
> @@ -165,7 +167,7 @@ static void test_xdp_pull_data_basic(void)
>                  PULL_MAX | PULL_PLUS_ONE);

We should also change these two cases above to use buff_len to make
sure we are testing the right logic in bpf_xdp_pull_data().

>
>         /* multi-buf pkt, no tailroom */
> -       run_test(skel, XDP_DROP, pg_sz, 9000, 0, max_data_len,
> +       run_test(skel, XDP_DROP, pg_sz, buff_len, 0, max_data_len,
>                  PULL_MAX | PULL_PLUS_ONE);
>
>  out:
> --
> 2.47.3
>
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v2 2/2] selftests/bpf: Fix xdp_pull_data failure with 64K page
  2026-01-22 21:18   ` Amery Hung
@ 2026-01-22 21:28     ` Yonghong Song
  2026-01-22 21:38     ` Yonghong Song
  1 sibling, 0 replies; 11+ messages in thread
From: Yonghong Song @ 2026-01-22 21:28 UTC (permalink / raw)
  To: Amery Hung
  Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	kernel-team, Martin KaFai Lau, Alan Maguire



On 1/22/26 1:18 PM, Amery Hung wrote:
> On Thu, Jan 22, 2026 at 8:56 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>> If the argument 'pull_len' of run_test() is 'PULL_MAX' or
>> 'PULL_MAX | PULL_PLUS_ONE', the eventual pull_len size
>> will close to the page size. On arm64 systems with 64K pages,
>> the pull_len size will be close to 64K. But the existing buffer
>> will be close to 9000 which is not enough to pull.
>>
>> For those failed run_tests(), make buff size to
>>    2 * pg_sz + (pg_sz / 2)
>> This way, there will be enough buffer space to pull
>> regardless of page size.
>>
>> Tested-by: Alan Maguire <alan.maguire@oracle.com>
>> Cc: Amery Hung <ameryhung@gmail.com>
>> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
>> ---
>>   .../testing/selftests/bpf/prog_tests/xdp_pull_data.c | 12 +++++++-----
>>   1 file changed, 7 insertions(+), 5 deletions(-)
>>
>> Changelog:
>>   v1 -> v2:
>>     - v1: https://lore.kernel.org/bpf/20260120210930.2544950-1-yonghong.song@linux.dev/
>>     - Use pg_sz to simplify buff_len calculation.
>>
>> diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
>> index efa350d04ec5..35f0eb5b43f3 100644
>> --- a/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
>> +++ b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
>> @@ -114,12 +114,14 @@ static void test_xdp_pull_data_basic(void)
>>   {
>>          u32 pg_sz, max_meta_len, max_data_len;
>>          struct test_xdp_pull_data *skel;
>> +       int buff_len;
>>
>>          skel = test_xdp_pull_data__open_and_load();
>>          if (!ASSERT_OK_PTR(skel, "test_xdp_pull_data__open_and_load"))
>>                  return;
>>
>>          pg_sz = sysconf(_SC_PAGE_SIZE);
>> +       buff_len = 2 * pg_sz + pg_sz / 2;
> Thanks for fixing the test. Just curious if there is an issue with 1.5
> pg_sz as suggested by Alan?

Yes. It works fine with 1.5 pg_sz too. I picked '2 * pg_sz + pg_sz / 2'
as for 4K page, 9000 will have 2 frags and I intend to maintain
2 frags for the tests.

>
>>          if (find_xdp_sizes(skel, pg_sz))
>>                  goto out;
>> @@ -140,13 +142,13 @@ static void test_xdp_pull_data_basic(void)
>>          run_test(skel, XDP_PASS, pg_sz, 9000, 0, 1025, 1025);
>>
>>          /* multi-buf pkt, empty linear data area, pull requires memmove */
>> -       run_test(skel, XDP_PASS, pg_sz, 9000, 0, 0, PULL_MAX);
>> +       run_test(skel, XDP_PASS, pg_sz, buff_len, 0, 0, PULL_MAX);
>>
>>          /* multi-buf pkt, no headroom */
>> -       run_test(skel, XDP_PASS, pg_sz, 9000, max_meta_len, 1024, PULL_MAX);
>> +       run_test(skel, XDP_PASS, pg_sz, buff_len, max_meta_len, 1024, PULL_MAX);
>>
>>          /* multi-buf pkt, no tailroom, pull requires memmove */
>> -       run_test(skel, XDP_PASS, pg_sz, 9000, 0, max_data_len, PULL_MAX);
>> +       run_test(skel, XDP_PASS, pg_sz, buff_len, 0, max_data_len, PULL_MAX);
>>
>>          /* Test cases with invalid pull length */
>>
>> @@ -154,7 +156,7 @@ static void test_xdp_pull_data_basic(void)
>>          run_test(skel, XDP_DROP, pg_sz, 2048, 0, 2048, 2049);
>>
>>          /* multi-buf pkt with no space left in linear data area */
>> -       run_test(skel, XDP_DROP, pg_sz, 9000, max_meta_len, max_data_len,
>> +       run_test(skel, XDP_DROP, pg_sz, buff_len, max_meta_len, max_data_len,
>>                   PULL_MAX | PULL_PLUS_ONE);
>>
>>          /* multi-buf pkt, empty linear data area */
>> @@ -165,7 +167,7 @@ static void test_xdp_pull_data_basic(void)
>>                   PULL_MAX | PULL_PLUS_ONE);
> We should also change these two cases above to use buff_len to make
> sure we are testing the right logic in bpf_xdp_pull_data().

Sure. Will do. Replacing 9000 with buff_len for those two cases
works okay too for both x86 and 64-page arm64.

>
>>          /* multi-buf pkt, no tailroom */
>> -       run_test(skel, XDP_DROP, pg_sz, 9000, 0, max_data_len,
>> +       run_test(skel, XDP_DROP, pg_sz, buff_len, 0, max_data_len,
>>                   PULL_MAX | PULL_PLUS_ONE);
>>
>>   out:
>> --
>> 2.47.3
>>
>>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v2 2/2] selftests/bpf: Fix xdp_pull_data failure with 64K page
  2026-01-22 21:18   ` Amery Hung
  2026-01-22 21:28     ` Yonghong Song
@ 2026-01-22 21:38     ` Yonghong Song
  2026-01-22 21:53       ` Amery Hung
  1 sibling, 1 reply; 11+ messages in thread
From: Yonghong Song @ 2026-01-22 21:38 UTC (permalink / raw)
  To: Amery Hung
  Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	kernel-team, Martin KaFai Lau, Alan Maguire



On 1/22/26 1:18 PM, Amery Hung wrote:
> On Thu, Jan 22, 2026 at 8:56 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>> If the argument 'pull_len' of run_test() is 'PULL_MAX' or
>> 'PULL_MAX | PULL_PLUS_ONE', the eventual pull_len size
>> will close to the page size. On arm64 systems with 64K pages,
>> the pull_len size will be close to 64K. But the existing buffer
>> will be close to 9000 which is not enough to pull.
>>
>> For those failed run_tests(), make buff size to
>>    2 * pg_sz + (pg_sz / 2)
>> This way, there will be enough buffer space to pull
>> regardless of page size.
>>
>> Tested-by: Alan Maguire <alan.maguire@oracle.com>
>> Cc: Amery Hung <ameryhung@gmail.com>
>> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
>> ---
>>   .../testing/selftests/bpf/prog_tests/xdp_pull_data.c | 12 +++++++-----
>>   1 file changed, 7 insertions(+), 5 deletions(-)
>>
>> Changelog:
>>   v1 -> v2:
>>     - v1: https://lore.kernel.org/bpf/20260120210930.2544950-1-yonghong.song@linux.dev/
>>     - Use pg_sz to simplify buff_len calculation.
>>
>> diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
>> index efa350d04ec5..35f0eb5b43f3 100644
>> --- a/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
>> +++ b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
>> @@ -114,12 +114,14 @@ static void test_xdp_pull_data_basic(void)
>>   {
>>          u32 pg_sz, max_meta_len, max_data_len;
>>          struct test_xdp_pull_data *skel;
>> +       int buff_len;
>>
>>          skel = test_xdp_pull_data__open_and_load();
>>          if (!ASSERT_OK_PTR(skel, "test_xdp_pull_data__open_and_load"))
>>                  return;
>>
>>          pg_sz = sysconf(_SC_PAGE_SIZE);
>> +       buff_len = 2 * pg_sz + pg_sz / 2;
> Thanks for fixing the test. Just curious if there is an issue with 1.5
> pg_sz as suggested by Alan?

Although existing 'buff_len = 2 * pg_sz + pg_sz / 2' works fine for the test,
but let us use the Alan's suggestion (buff_len = pg_sz + pg_sz / 2)
since the buffer size is tighter and potentially better for test.

>
>>          if (find_xdp_sizes(skel, pg_sz))
>>                  goto out;

[...]


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data failure with 64K page
  2026-01-22 16:26 [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data failure with 64K page Yonghong Song
  2026-01-22 16:26 ` [PATCH bpf-next v2 2/2] selftests/bpf: Fix xdp_pull_data " Yonghong Song
@ 2026-01-22 21:49 ` Amery Hung
  2026-01-22 22:58   ` Yonghong Song
  1 sibling, 1 reply; 11+ messages in thread
From: Amery Hung @ 2026-01-22 21:49 UTC (permalink / raw)
  To: Yonghong Song
  Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	kernel-team, Martin KaFai Lau, Alan Maguire

On Thu, Jan 22, 2026 at 8:54 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>
> 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[];
>   };
> fields 'cnt' and 'size' 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.
> For field 'size', it is okay for value 4K, but it is not enough
> for 64K as maximum 'size' value is '64K - 1'.
>
> To accommodate 64K page, '_Atomic __u8 cnt' becomes '_Atomic __u16 cnt'
> and '__u16 size' becomes '__u32 size'. A few other places are adjusted
> accordingly.
>
> 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>
> ---
>  tools/testing/selftests/bpf/prog_tests/task_local_data.h    | 6 +++---
>  .../testing/selftests/bpf/prog_tests/test_task_local_data.c | 2 +-
>  tools/testing/selftests/bpf/progs/task_local_data.bpf.h     | 4 ++--
>  3 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/task_local_data.h b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
> index 2de38776a2d4..4c38f9a7bc90 100644
> --- a/tools/testing/selftests/bpf/prog_tests/task_local_data.h
> +++ b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
> @@ -94,8 +94,8 @@ struct tld_metadata {
>  };
>
>  struct tld_meta_u {
> -       _Atomic __u8 cnt;
> -       __u16 size;
> +       _Atomic __u16 cnt;
> +       __u32 size;

Agree cnt should be __u16.

size can remain to be __u16 as maximum data size is page_size - 8
byte. The 8 byte is tld_data_u->start recording thread-specific offset
of data in a page.

>         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();
> diff --git a/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c b/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
> index 9fd6306b455c..cc4d49222d9d 100644
> --- a/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
> +++ b/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
> @@ -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()
>  #include "task_local_data.h"
>
>  struct test_tld_struct {
> diff --git a/tools/testing/selftests/bpf/progs/task_local_data.bpf.h b/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
> index 432fff2af844..e13f239b46b0 100644
> --- a/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
> +++ b/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
> @@ -80,8 +80,8 @@ struct tld_metadata {
>  };
>
>  struct tld_meta_u {
> -       __u8 cnt;
> -       __u16 size;
> +       __u16 cnt;
> +       __u32 size;

Same here. We can keep __u16 size.

>         struct tld_metadata metadata[TLD_MAX_DATA_CNT];
>  };
>
> --
> 2.47.3
>
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v2 2/2] selftests/bpf: Fix xdp_pull_data failure with 64K page
  2026-01-22 21:38     ` Yonghong Song
@ 2026-01-22 21:53       ` Amery Hung
  0 siblings, 0 replies; 11+ messages in thread
From: Amery Hung @ 2026-01-22 21:53 UTC (permalink / raw)
  To: Yonghong Song
  Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	kernel-team, Martin KaFai Lau, Alan Maguire

On Thu, Jan 22, 2026 at 1:38 PM Yonghong Song <yonghong.song@linux.dev> wrote:
>
>
>
> On 1/22/26 1:18 PM, Amery Hung wrote:
> > On Thu, Jan 22, 2026 at 8:56 AM Yonghong Song <yonghong.song@linux.dev> wrote:
> >> If the argument 'pull_len' of run_test() is 'PULL_MAX' or
> >> 'PULL_MAX | PULL_PLUS_ONE', the eventual pull_len size
> >> will close to the page size. On arm64 systems with 64K pages,
> >> the pull_len size will be close to 64K. But the existing buffer
> >> will be close to 9000 which is not enough to pull.
> >>
> >> For those failed run_tests(), make buff size to
> >>    2 * pg_sz + (pg_sz / 2)
> >> This way, there will be enough buffer space to pull
> >> regardless of page size.
> >>
> >> Tested-by: Alan Maguire <alan.maguire@oracle.com>
> >> Cc: Amery Hung <ameryhung@gmail.com>
> >> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
> >> ---
> >>   .../testing/selftests/bpf/prog_tests/xdp_pull_data.c | 12 +++++++-----
> >>   1 file changed, 7 insertions(+), 5 deletions(-)
> >>
> >> Changelog:
> >>   v1 -> v2:
> >>     - v1: https://lore.kernel.org/bpf/20260120210930.2544950-1-yonghong.song@linux.dev/
> >>     - Use pg_sz to simplify buff_len calculation.
> >>
> >> diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
> >> index efa350d04ec5..35f0eb5b43f3 100644
> >> --- a/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
> >> +++ b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
> >> @@ -114,12 +114,14 @@ static void test_xdp_pull_data_basic(void)
> >>   {
> >>          u32 pg_sz, max_meta_len, max_data_len;
> >>          struct test_xdp_pull_data *skel;
> >> +       int buff_len;
> >>
> >>          skel = test_xdp_pull_data__open_and_load();
> >>          if (!ASSERT_OK_PTR(skel, "test_xdp_pull_data__open_and_load"))
> >>                  return;
> >>
> >>          pg_sz = sysconf(_SC_PAGE_SIZE);
> >> +       buff_len = 2 * pg_sz + pg_sz / 2;
> > Thanks for fixing the test. Just curious if there is an issue with 1.5
> > pg_sz as suggested by Alan?
>
> Although existing 'buff_len = 2 * pg_sz + pg_sz / 2' works fine for the test,
> but let us use the Alan's suggestion (buff_len = pg_sz + pg_sz / 2)
> since the buffer size is tighter and potentially better for test.

I see. Sounds good.

>
> >
> >>          if (find_xdp_sizes(skel, pg_sz))
> >>                  goto out;
>
> [...]
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data failure with 64K page
  2026-01-22 21:49 ` [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data " Amery Hung
@ 2026-01-22 22:58   ` Yonghong Song
  2026-01-22 23:34     ` Alexei Starovoitov
  2026-01-22 23:47     ` Amery Hung
  0 siblings, 2 replies; 11+ messages in thread
From: Yonghong Song @ 2026-01-22 22:58 UTC (permalink / raw)
  To: Amery Hung
  Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	kernel-team, Martin KaFai Lau, Alan Maguire



On 1/22/26 1:49 PM, Amery Hung wrote:
> On Thu, Jan 22, 2026 at 8:54 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>> 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[];
>>    };
>> fields 'cnt' and 'size' 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.
>> For field 'size', it is okay for value 4K, but it is not enough
>> for 64K as maximum 'size' value is '64K - 1'.
>>
>> To accommodate 64K page, '_Atomic __u8 cnt' becomes '_Atomic __u16 cnt'
>> and '__u16 size' becomes '__u32 size'. A few other places are adjusted
>> accordingly.
>>
>> 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>
>> ---
>>   tools/testing/selftests/bpf/prog_tests/task_local_data.h    | 6 +++---
>>   .../testing/selftests/bpf/prog_tests/test_task_local_data.c | 2 +-
>>   tools/testing/selftests/bpf/progs/task_local_data.bpf.h     | 4 ++--
>>   3 files changed, 6 insertions(+), 6 deletions(-)
>>
>> diff --git a/tools/testing/selftests/bpf/prog_tests/task_local_data.h b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
>> index 2de38776a2d4..4c38f9a7bc90 100644
>> --- a/tools/testing/selftests/bpf/prog_tests/task_local_data.h
>> +++ b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
>> @@ -94,8 +94,8 @@ struct tld_metadata {
>>   };
>>
>>   struct tld_meta_u {
>> -       _Atomic __u8 cnt;
>> -       __u16 size;
>> +       _Atomic __u16 cnt;
>> +       __u32 size;
> Agree cnt should be __u16.
>
> size can remain to be __u16 as maximum data size is page_size - 8
> byte. The 8 byte is tld_data_u->start recording thread-specific offset
> of data in a page.

In test_task_local_data.c, I made the change like below
    #define TLD_DYN_DATA_SIZE getpagesize()
so TLD_DYN_DATA_SIZE will be 64K for 64K page.

In function __tld_init_meta_p(), we have
   meta->size = TLD_DYN_DATA_SIZE;

So size needs to be 32 bit in order to hold the value 0x10000.

Are you saying
     #define TLD_DYN_DATA_SIZE getpagesize()
is not correct?
The previous one is
     #define TLD_DYN_DATA_SIZE 4096
for 4K page system. For 64K, I naturally tried
to replace the above 4096 with getpagesize().
Did I miss anything?

>
>>          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();
>> diff --git a/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c b/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
>> index 9fd6306b455c..cc4d49222d9d 100644
>> --- a/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
>> +++ b/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
>> @@ -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()
>>   #include "task_local_data.h"
>>
>>   struct test_tld_struct {
>> diff --git a/tools/testing/selftests/bpf/progs/task_local_data.bpf.h b/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
>> index 432fff2af844..e13f239b46b0 100644
>> --- a/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
>> +++ b/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
>> @@ -80,8 +80,8 @@ struct tld_metadata {
>>   };
>>
>>   struct tld_meta_u {
>> -       __u8 cnt;
>> -       __u16 size;
>> +       __u16 cnt;
>> +       __u32 size;
> Same here. We can keep __u16 size.
>
>>          struct tld_metadata metadata[TLD_MAX_DATA_CNT];
>>   };
>>
>> --
>> 2.47.3
>>
>>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data failure with 64K page
  2026-01-22 22:58   ` Yonghong Song
@ 2026-01-22 23:34     ` Alexei Starovoitov
  2026-01-22 23:47     ` Amery Hung
  1 sibling, 0 replies; 11+ messages in thread
From: Alexei Starovoitov @ 2026-01-22 23:34 UTC (permalink / raw)
  To: Yonghong Song
  Cc: Amery Hung, bpf, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kernel Team, Martin KaFai Lau, Alan Maguire

On Thu, Jan 22, 2026 at 2:58 PM Yonghong Song <yonghong.song@linux.dev> wrote:
>
>
>
> On 1/22/26 1:49 PM, Amery Hung wrote:
> > On Thu, Jan 22, 2026 at 8:54 AM Yonghong Song <yonghong.song@linux.dev> wrote:
> >> 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[];
> >>    };
> >> fields 'cnt' and 'size' 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.
> >> For field 'size', it is okay for value 4K, but it is not enough
> >> for 64K as maximum 'size' value is '64K - 1'.
> >>
> >> To accommodate 64K page, '_Atomic __u8 cnt' becomes '_Atomic __u16 cnt'
> >> and '__u16 size' becomes '__u32 size'. A few other places are adjusted
> >> accordingly.
> >>
> >> 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>
> >> ---
> >>   tools/testing/selftests/bpf/prog_tests/task_local_data.h    | 6 +++---
> >>   .../testing/selftests/bpf/prog_tests/test_task_local_data.c | 2 +-
> >>   tools/testing/selftests/bpf/progs/task_local_data.bpf.h     | 4 ++--
> >>   3 files changed, 6 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/tools/testing/selftests/bpf/prog_tests/task_local_data.h b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
> >> index 2de38776a2d4..4c38f9a7bc90 100644
> >> --- a/tools/testing/selftests/bpf/prog_tests/task_local_data.h
> >> +++ b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
> >> @@ -94,8 +94,8 @@ struct tld_metadata {
> >>   };
> >>
> >>   struct tld_meta_u {
> >> -       _Atomic __u8 cnt;
> >> -       __u16 size;
> >> +       _Atomic __u16 cnt;
> >> +       __u32 size;
> > Agree cnt should be __u16.
> >
> > size can remain to be __u16 as maximum data size is page_size - 8
> > byte. The 8 byte is tld_data_u->start recording thread-specific offset
> > of data in a page.
>
> In test_task_local_data.c, I made the change like below
>     #define TLD_DYN_DATA_SIZE getpagesize()
> so TLD_DYN_DATA_SIZE will be 64K for 64K page.
>
> In function __tld_init_meta_p(), we have
>    meta->size = TLD_DYN_DATA_SIZE;
>
> So size needs to be 32 bit in order to hold the value 0x10000.
>
> Are you saying
>      #define TLD_DYN_DATA_SIZE getpagesize()
> is not correct?
> The previous one is
>      #define TLD_DYN_DATA_SIZE 4096
> for 4K page system. For 64K, I naturally tried
> to replace the above 4096 with getpagesize().
> Did I miss anything?

iirc TLD_DYN_DATA_SIZE is a max size. Technically it can be anything,
but bigger than 4k is hard to imagine. Even 1k is hard to come up
with a real use case.

imo _u16 size is fine.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data failure with 64K page
  2026-01-22 22:58   ` Yonghong Song
  2026-01-22 23:34     ` Alexei Starovoitov
@ 2026-01-22 23:47     ` Amery Hung
  2026-01-23  0:23       ` Yonghong Song
  1 sibling, 1 reply; 11+ messages in thread
From: Amery Hung @ 2026-01-22 23:47 UTC (permalink / raw)
  To: Yonghong Song
  Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	kernel-team, Martin KaFai Lau, Alan Maguire

On Thu, Jan 22, 2026 at 2:58 PM Yonghong Song <yonghong.song@linux.dev> wrote:
>
>
>
> On 1/22/26 1:49 PM, Amery Hung wrote:
> > On Thu, Jan 22, 2026 at 8:54 AM Yonghong Song <yonghong.song@linux.dev> wrote:
> >> 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[];
> >>    };
> >> fields 'cnt' and 'size' 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.
> >> For field 'size', it is okay for value 4K, but it is not enough
> >> for 64K as maximum 'size' value is '64K - 1'.
> >>
> >> To accommodate 64K page, '_Atomic __u8 cnt' becomes '_Atomic __u16 cnt'
> >> and '__u16 size' becomes '__u32 size'. A few other places are adjusted
> >> accordingly.
> >>
> >> 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>
> >> ---
> >>   tools/testing/selftests/bpf/prog_tests/task_local_data.h    | 6 +++---
> >>   .../testing/selftests/bpf/prog_tests/test_task_local_data.c | 2 +-
> >>   tools/testing/selftests/bpf/progs/task_local_data.bpf.h     | 4 ++--
> >>   3 files changed, 6 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/tools/testing/selftests/bpf/prog_tests/task_local_data.h b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
> >> index 2de38776a2d4..4c38f9a7bc90 100644
> >> --- a/tools/testing/selftests/bpf/prog_tests/task_local_data.h
> >> +++ b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
> >> @@ -94,8 +94,8 @@ struct tld_metadata {
> >>   };
> >>
> >>   struct tld_meta_u {
> >> -       _Atomic __u8 cnt;
> >> -       __u16 size;
> >> +       _Atomic __u16 cnt;
> >> +       __u32 size;
> > Agree cnt should be __u16.
> >
> > size can remain to be __u16 as maximum data size is page_size - 8
> > byte. The 8 byte is tld_data_u->start recording thread-specific offset
> > of data in a page.
>
> In test_task_local_data.c, I made the change like below
>     #define TLD_DYN_DATA_SIZE getpagesize()
> so TLD_DYN_DATA_SIZE will be 64K for 64K page.
>
> In function __tld_init_meta_p(), we have
>    meta->size = TLD_DYN_DATA_SIZE;
>
> So size needs to be 32 bit in order to hold the value 0x10000.
>
> Are you saying
>      #define TLD_DYN_DATA_SIZE getpagesize()
> is not correct?
> The previous one is
>      #define TLD_DYN_DATA_SIZE 4096
> for 4K page system. For 64K, I naturally tried
> to replace the above 4096 with getpagesize().
> Did I miss anything?

It should be getpagesize() - 8 to be more precise, but that does not
matter to the user.

We currently do not do a sanity check on TLD_DYN_DATA_SIZE, but the
check in __tld_create_key() will make sure data cannot exceed
page_size - 8 byte:

if (off + TLD_ROUND_UP(size, 8) > TLD_PAGE_SIZE - sizeof(struct tld_data_u))
        return (tld_key_t){-E2BIG};

TLD_DYN_DATA_SIZE in the common use case should be small or even zero
if all tld is known at compile time (i.e., declared with
TLD_DEFINE_KEY) to avoid memory wastage.

>
> >
> >>          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();
> >> diff --git a/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c b/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
> >> index 9fd6306b455c..cc4d49222d9d 100644
> >> --- a/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
> >> +++ b/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
> >> @@ -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()
> >>   #include "task_local_data.h"
> >>
> >>   struct test_tld_struct {
> >> diff --git a/tools/testing/selftests/bpf/progs/task_local_data.bpf.h b/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
> >> index 432fff2af844..e13f239b46b0 100644
> >> --- a/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
> >> +++ b/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
> >> @@ -80,8 +80,8 @@ struct tld_metadata {
> >>   };
> >>
> >>   struct tld_meta_u {
> >> -       __u8 cnt;
> >> -       __u16 size;
> >> +       __u16 cnt;
> >> +       __u32 size;
> > Same here. We can keep __u16 size.
> >
> >>          struct tld_metadata metadata[TLD_MAX_DATA_CNT];
> >>   };
> >>
> >> --
> >> 2.47.3
> >>
> >>
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data failure with 64K page
  2026-01-22 23:47     ` Amery Hung
@ 2026-01-23  0:23       ` Yonghong Song
  0 siblings, 0 replies; 11+ messages in thread
From: Yonghong Song @ 2026-01-23  0:23 UTC (permalink / raw)
  To: Amery Hung
  Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	kernel-team, Martin KaFai Lau, Alan Maguire



On 1/22/26 3:47 PM, Amery Hung wrote:
> On Thu, Jan 22, 2026 at 2:58 PM Yonghong Song <yonghong.song@linux.dev> wrote:
>>
>>
>> On 1/22/26 1:49 PM, Amery Hung wrote:
>>> On Thu, Jan 22, 2026 at 8:54 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>>>> 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[];
>>>>     };
>>>> fields 'cnt' and 'size' 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.
>>>> For field 'size', it is okay for value 4K, but it is not enough
>>>> for 64K as maximum 'size' value is '64K - 1'.
>>>>
>>>> To accommodate 64K page, '_Atomic __u8 cnt' becomes '_Atomic __u16 cnt'
>>>> and '__u16 size' becomes '__u32 size'. A few other places are adjusted
>>>> accordingly.
>>>>
>>>> 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>
>>>> ---
>>>>    tools/testing/selftests/bpf/prog_tests/task_local_data.h    | 6 +++---
>>>>    .../testing/selftests/bpf/prog_tests/test_task_local_data.c | 2 +-
>>>>    tools/testing/selftests/bpf/progs/task_local_data.bpf.h     | 4 ++--
>>>>    3 files changed, 6 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/tools/testing/selftests/bpf/prog_tests/task_local_data.h b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
>>>> index 2de38776a2d4..4c38f9a7bc90 100644
>>>> --- a/tools/testing/selftests/bpf/prog_tests/task_local_data.h
>>>> +++ b/tools/testing/selftests/bpf/prog_tests/task_local_data.h
>>>> @@ -94,8 +94,8 @@ struct tld_metadata {
>>>>    };
>>>>
>>>>    struct tld_meta_u {
>>>> -       _Atomic __u8 cnt;
>>>> -       __u16 size;
>>>> +       _Atomic __u16 cnt;
>>>> +       __u32 size;
>>> Agree cnt should be __u16.
>>>
>>> size can remain to be __u16 as maximum data size is page_size - 8
>>> byte. The 8 byte is tld_data_u->start recording thread-specific offset
>>> of data in a page.
>> In test_task_local_data.c, I made the change like below
>>      #define TLD_DYN_DATA_SIZE getpagesize()
>> so TLD_DYN_DATA_SIZE will be 64K for 64K page.
>>
>> In function __tld_init_meta_p(), we have
>>     meta->size = TLD_DYN_DATA_SIZE;
>>
>> So size needs to be 32 bit in order to hold the value 0x10000.
>>
>> Are you saying
>>       #define TLD_DYN_DATA_SIZE getpagesize()
>> is not correct?
>> The previous one is
>>       #define TLD_DYN_DATA_SIZE 4096
>> for 4K page system. For 64K, I naturally tried
>> to replace the above 4096 with getpagesize().
>> Did I miss anything?
> It should be getpagesize() - 8 to be more precise, but that does not
> matter to the user.
>
> We currently do not do a sanity check on TLD_DYN_DATA_SIZE, but the
> check in __tld_create_key() will make sure data cannot exceed
> page_size - 8 byte:
>
> if (off + TLD_ROUND_UP(size, 8) > TLD_PAGE_SIZE - sizeof(struct tld_data_u))
>          return (tld_key_t){-E2BIG};
>
> TLD_DYN_DATA_SIZE in the common use case should be small or even zero
> if all tld is known at compile time (i.e., declared with
> TLD_DEFINE_KEY) to avoid memory wastage.

So TLD_DYN_DATA_SIZE should at most be
TLD_PAGE_SIZE - sizeof(struct tld_data_u).

Okay, I will make a change to
    #define TLD_DYN_DATA_SIZE (getpagesize() - 8)
and restore the original type for field '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();
>>>> diff --git a/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c b/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
>>>> index 9fd6306b455c..cc4d49222d9d 100644
>>>> --- a/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
>>>> +++ b/tools/testing/selftests/bpf/prog_tests/test_task_local_data.c
>>>> @@ -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()
>>>>    #include "task_local_data.h"
>>>>
>>>>    struct test_tld_struct {
>>>> diff --git a/tools/testing/selftests/bpf/progs/task_local_data.bpf.h b/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
>>>> index 432fff2af844..e13f239b46b0 100644
>>>> --- a/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
>>>> +++ b/tools/testing/selftests/bpf/progs/task_local_data.bpf.h
>>>> @@ -80,8 +80,8 @@ struct tld_metadata {
>>>>    };
>>>>
>>>>    struct tld_meta_u {
>>>> -       __u8 cnt;
>>>> -       __u16 size;
>>>> +       __u16 cnt;
>>>> +       __u32 size;
>>> Same here. We can keep __u16 size.

Same here. Will keep the original '__u16 size'.

>>>
>>>>           struct tld_metadata metadata[TLD_MAX_DATA_CNT];
>>>>    };
>>>>
>>>> --
>>>> 2.47.3
>>>>
>>>>


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-01-23  0:24 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-22 16:26 [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data failure with 64K page Yonghong Song
2026-01-22 16:26 ` [PATCH bpf-next v2 2/2] selftests/bpf: Fix xdp_pull_data " Yonghong Song
2026-01-22 21:18   ` Amery Hung
2026-01-22 21:28     ` Yonghong Song
2026-01-22 21:38     ` Yonghong Song
2026-01-22 21:53       ` Amery Hung
2026-01-22 21:49 ` [PATCH bpf-next v2 1/2] selftests/bpf: Fix task_local_data " Amery Hung
2026-01-22 22:58   ` Yonghong Song
2026-01-22 23:34     ` Alexei Starovoitov
2026-01-22 23:47     ` Amery Hung
2026-01-23  0:23       ` Yonghong Song

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.