* [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.