* [PATCH bpf-next v2 0/3] bpf: Fix a few test failures with 64K page size
@ 2025-06-11 17:15 Yonghong Song
2025-06-11 17:15 ` [PATCH bpf-next v2 1/3] bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than 4K Yonghong Song
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Yonghong Song @ 2025-06-11 17:15 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team,
Martin KaFai Lau
This small patch set tried to fix a few networking related test failure failures
due to 64K page size. Please see each individual patch for details.
Changelog:
v1 -> v2:
- v1: https://lore.kernel.org/bpf/20250608165534.1019914-1-yonghong.song@linux.dev/
- For xdp_adjust_tail, let kernel test_run can handle various page sizes for xdp progs.
- For two change_tail tests, make code easier to understand.
- Resolved a new test failure (xdp_do_redirect).
Yonghong Song (3):
bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than
4K
selftests/bpf: Fix two net related test failures with 64K page size
selftests/bpf: Fix xdp_do_redirect failure with 64KB page size
net/bpf/test_run.c | 2 +-
.../bpf/prog_tests/xdp_adjust_tail.c | 95 +++++++++++++++++--
.../bpf/prog_tests/xdp_do_redirect.c | 13 ++-
.../bpf/progs/test_sockmap_change_tail.c | 5 +-
.../selftests/bpf/progs/test_tc_change_tail.c | 5 +-
.../bpf/progs/test_xdp_adjust_tail_grow.c | 8 +-
6 files changed, 115 insertions(+), 13 deletions(-)
--
2.47.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH bpf-next v2 1/3] bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than 4K
2025-06-11 17:15 [PATCH bpf-next v2 0/3] bpf: Fix a few test failures with 64K page size Yonghong Song
@ 2025-06-11 17:15 ` Yonghong Song
2025-06-11 19:24 ` Alexei Starovoitov
2025-06-11 17:15 ` [PATCH bpf-next v2 2/3] selftests/bpf: Fix two net related test failures with 64K page size Yonghong Song
2025-06-11 17:15 ` [PATCH bpf-next v2 3/3] selftests/bpf: Fix xdp_do_redirect failure with 64KB " Yonghong Song
2 siblings, 1 reply; 8+ messages in thread
From: Yonghong Song @ 2025-06-11 17:15 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team,
Martin KaFai Lau
The bpf selftest xdp_adjust_tail/xdp_adjust_frags_tail_grow failed on
arm64 with 64KB page:
xdp_adjust_tail/xdp_adjust_frags_tail_grow:FAIL
In bpf_prog_test_run_xdp(), the xdp->frame_sz is set to 4K, but later on
when constructing frags, with 64K page size, the frag data_len could
be more than 4K. This will cause problems in bpf_xdp_frags_increase_tail().
To fix the failure, the xdp->frame_sz is set to be PAGE_SIZE so kernel
can test different page size properly. With the kernel change, the user
space and bpf prog needs adjustment. Currently, the MAX_SKB_FRAGS default
value is 17, so for 4K page, the maximum packet size will be less than 68K.
To test 64K page, a bigger maximum packet size than 68K is desired. So two
different functions are implemented for subtest xdp_adjust_frags_tail_grow.
Depending on different page size, different data input/output sizes are used
to adapt with different page size.
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
net/bpf/test_run.c | 2 +-
.../bpf/prog_tests/xdp_adjust_tail.c | 95 +++++++++++++++++--
.../bpf/progs/test_xdp_adjust_tail_grow.c | 8 +-
3 files changed, 96 insertions(+), 9 deletions(-)
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index aaf13a7d58ed..9728dbd4c66c 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -1255,7 +1255,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
headroom -= ctx->data;
}
- max_data_sz = 4096 - headroom - tailroom;
+ max_data_sz = PAGE_SIZE - headroom - tailroom;
if (size > max_data_sz) {
/* disallow live data mode for jumbo frames */
if (do_live)
diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
index e361129402a1..133bde28a489 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
@@ -37,21 +37,25 @@ static void test_xdp_adjust_tail_shrink(void)
bpf_object__close(obj);
}
-static void test_xdp_adjust_tail_grow(void)
+static void test_xdp_adjust_tail_grow(bool is_64k_pagesize)
{
const char *file = "./test_xdp_adjust_tail_grow.bpf.o";
struct bpf_object *obj;
- char buf[4096]; /* avoid segfault: large buf to hold grow results */
+ char buf[8192]; /* avoid segfault: large buf to hold grow results */
__u32 expect_sz;
int err, prog_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
- .data_size_in = sizeof(pkt_v4),
.data_out = buf,
.data_size_out = sizeof(buf),
.repeat = 1,
);
+ if (is_64k_pagesize)
+ topts.data_size_in = sizeof(pkt_v4) - 1;
+ else
+ topts.data_size_in = sizeof(pkt_v4);
+
err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
if (!ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
return;
@@ -208,7 +212,7 @@ static void test_xdp_adjust_frags_tail_shrink(void)
bpf_object__close(obj);
}
-static void test_xdp_adjust_frags_tail_grow(void)
+static void test_xdp_adjust_frags_tail_grow_4k(void)
{
const char *file = "./test_xdp_adjust_tail_grow.bpf.o";
__u32 exp_size;
@@ -279,16 +283,93 @@ static void test_xdp_adjust_frags_tail_grow(void)
bpf_object__close(obj);
}
+static void test_xdp_adjust_frags_tail_grow_64k(void)
+{
+ const char *file = "./test_xdp_adjust_tail_grow.bpf.o";
+ __u32 exp_size;
+ struct bpf_program *prog;
+ struct bpf_object *obj;
+ int err, i, prog_fd;
+ __u8 *buf;
+ LIBBPF_OPTS(bpf_test_run_opts, topts);
+
+ obj = bpf_object__open(file);
+ if (libbpf_get_error(obj))
+ return;
+
+ prog = bpf_object__next_program(obj, NULL);
+ if (bpf_object__load(obj))
+ goto out;
+
+ prog_fd = bpf_program__fd(prog);
+
+ buf = malloc(262144);
+ if (!ASSERT_OK_PTR(buf, "alloc buf 256Kb"))
+ goto out;
+
+ /* Test case add 10 bytes to last frag */
+ memset(buf, 1, 262144);
+ exp_size = 90000 + 10;
+
+ topts.data_in = buf;
+ topts.data_out = buf;
+ topts.data_size_in = 90000;
+ topts.data_size_out = 262144;
+ err = bpf_prog_test_run_opts(prog_fd, &topts);
+
+ ASSERT_OK(err, "90Kb+10b");
+ ASSERT_EQ(topts.retval, XDP_TX, "90Kb+10b retval");
+ ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size");
+
+ for (i = 0; i < 90000; i++) {
+ if (buf[i] != 1)
+ ASSERT_EQ(buf[i], 1, "90Kb+10b-old");
+ }
+
+ for (i = 90000; i < 90010; i++) {
+ if (buf[i] != 0)
+ ASSERT_EQ(buf[i], 0, "90Kb+10b-new");
+ }
+
+ for (i = 90010; i < 262144; i++) {
+ if (buf[i] != 1)
+ ASSERT_EQ(buf[i], 1, "90Kb+10b-untouched");
+ }
+
+ /* Test a too large grow */
+ memset(buf, 1, 262144);
+ exp_size = 90001;
+
+ topts.data_in = topts.data_out = buf;
+ topts.data_size_in = 90001;
+ topts.data_size_out = 262144;
+ err = bpf_prog_test_run_opts(prog_fd, &topts);
+
+ ASSERT_OK(err, "90Kb+10b");
+ ASSERT_EQ(topts.retval, XDP_DROP, "90Kb+10b retval");
+ ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size");
+
+ free(buf);
+out:
+ bpf_object__close(obj);
+}
+
void test_xdp_adjust_tail(void)
{
+ int page_size = getpagesize();
+
if (test__start_subtest("xdp_adjust_tail_shrink"))
test_xdp_adjust_tail_shrink();
if (test__start_subtest("xdp_adjust_tail_grow"))
- test_xdp_adjust_tail_grow();
+ test_xdp_adjust_tail_grow(page_size == 65536);
if (test__start_subtest("xdp_adjust_tail_grow2"))
test_xdp_adjust_tail_grow2();
if (test__start_subtest("xdp_adjust_frags_tail_shrink"))
test_xdp_adjust_frags_tail_shrink();
- if (test__start_subtest("xdp_adjust_frags_tail_grow"))
- test_xdp_adjust_frags_tail_grow();
+ if (test__start_subtest("xdp_adjust_frags_tail_grow")) {
+ if (page_size == 65536)
+ test_xdp_adjust_frags_tail_grow_64k();
+ else
+ test_xdp_adjust_frags_tail_grow_4k();
+ }
}
diff --git a/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c b/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c
index dc74d8cf9e3f..93d55a2ca340 100644
--- a/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c
+++ b/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c
@@ -19,7 +19,9 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp)
/* Data length determine test case */
if (data_len == 54) { /* sizeof(pkt_v4) */
- offset = 4096; /* test too large offset */
+ offset = 4096; /* test too large offset, 4k page size */
+ } else if (data_len == 53) { /* sizeof(pkt_v4) - 1 */
+ offset = 65536; /* test too large offset, 64k page size */
} else if (data_len == 74) { /* sizeof(pkt_v6) */
offset = 40;
} else if (data_len == 64) {
@@ -31,6 +33,10 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp)
offset = 10;
} else if (data_len == 9001) {
offset = 4096;
+ } else if (data_len == 90000) {
+ offset = 10;
+ } else if (data_len == 90001) {
+ offset = 65536;
} else {
return XDP_ABORTED; /* No matching test */
}
--
2.47.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next v2 2/3] selftests/bpf: Fix two net related test failures with 64K page size
2025-06-11 17:15 [PATCH bpf-next v2 0/3] bpf: Fix a few test failures with 64K page size Yonghong Song
2025-06-11 17:15 ` [PATCH bpf-next v2 1/3] bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than 4K Yonghong Song
@ 2025-06-11 17:15 ` Yonghong Song
2025-06-11 19:21 ` Alexei Starovoitov
2025-06-11 17:15 ` [PATCH bpf-next v2 3/3] selftests/bpf: Fix xdp_do_redirect failure with 64KB " Yonghong Song
2 siblings, 1 reply; 8+ messages in thread
From: Yonghong Song @ 2025-06-11 17:15 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team,
Martin KaFai Lau
When running BPF selftests on arm64 with a 64K page size, I encountered
the following two test failures:
sockmap_basic/sockmap skb_verdict change tail:FAIL
tc_change_tail:FAIL
With further debugging, I identified the root cause in the following
kernel code within __bpf_skb_change_tail():
u32 max_len = BPF_SKB_MAX_LEN;
u32 min_len = __bpf_skb_min_len(skb);
int ret;
if (unlikely(flags || new_len > max_len || new_len < min_len))
return -EINVAL;
With a 4K page size, new_len = 65535 and max_len = 16064, the function
returns -EINVAL. However, With a 64K page size, max_len increases to
261824, allowing execution to proceed further in the function. This is
because BPF_SKB_MAX_LEN scales with the page size and larger page sizes
result in higher max_len values.
Updating the new_len parameter in both tests from 65535 to 256K (0x40000)
resolves the failures.
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c | 5 ++++-
tools/testing/selftests/bpf/progs/test_tc_change_tail.c | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c b/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c
index 2796dd8545eb..e4554ef05441 100644
--- a/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c
+++ b/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c
@@ -3,6 +3,9 @@
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
+#define PAGE_SIZE 65536 /* make it work on 64K page arches */
+#define BPF_SKB_MAX_LEN (PAGE_SIZE << 2)
+
struct {
__uint(type, BPF_MAP_TYPE_SOCKMAP);
__uint(max_entries, 1);
@@ -31,7 +34,7 @@ int prog_skb_verdict(struct __sk_buff *skb)
change_tail_ret = bpf_skb_change_tail(skb, skb->len + 1, 0);
return SK_PASS;
} else if (data[0] == 'E') { /* Error */
- change_tail_ret = bpf_skb_change_tail(skb, 65535, 0);
+ change_tail_ret = bpf_skb_change_tail(skb, BPF_SKB_MAX_LEN, 0);
return SK_PASS;
}
return SK_PASS;
diff --git a/tools/testing/selftests/bpf/progs/test_tc_change_tail.c b/tools/testing/selftests/bpf/progs/test_tc_change_tail.c
index 28edafe803f0..47670bbd1766 100644
--- a/tools/testing/selftests/bpf/progs/test_tc_change_tail.c
+++ b/tools/testing/selftests/bpf/progs/test_tc_change_tail.c
@@ -7,6 +7,9 @@
#include <linux/udp.h>
#include <linux/pkt_cls.h>
+#define PAGE_SIZE 65536 /* make it work on 64K page arches */
+#define BPF_SKB_MAX_LEN (PAGE_SIZE << 2)
+
long change_tail_ret = 1;
static __always_inline struct iphdr *parse_ip_header(struct __sk_buff *skb, int *ip_proto)
@@ -94,7 +97,7 @@ int change_tail(struct __sk_buff *skb)
bpf_skb_change_tail(skb, len, 0);
return TCX_PASS;
} else if (payload[0] == 'E') { /* Error */
- change_tail_ret = bpf_skb_change_tail(skb, 65535, 0);
+ change_tail_ret = bpf_skb_change_tail(skb, BPF_SKB_MAX_LEN, 0);
return TCX_PASS;
} else if (payload[0] == 'Z') { /* Zero */
change_tail_ret = bpf_skb_change_tail(skb, 0, 0);
--
2.47.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next v2 3/3] selftests/bpf: Fix xdp_do_redirect failure with 64KB page size
2025-06-11 17:15 [PATCH bpf-next v2 0/3] bpf: Fix a few test failures with 64K page size Yonghong Song
2025-06-11 17:15 ` [PATCH bpf-next v2 1/3] bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than 4K Yonghong Song
2025-06-11 17:15 ` [PATCH bpf-next v2 2/3] selftests/bpf: Fix two net related test failures with 64K page size Yonghong Song
@ 2025-06-11 17:15 ` Yonghong Song
2 siblings, 0 replies; 8+ messages in thread
From: Yonghong Song @ 2025-06-11 17:15 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team,
Martin KaFai Lau
On arm64 with 64KB page size, the selftest xdp_do_redirect failed like
below:
...
test_xdp_do_redirect:PASS:pkt_count_tc 0 nsec
test_max_pkt_size:PASS:prog_run_max_size 0 nsec
test_max_pkt_size:FAIL:prog_run_too_big unexpected prog_run_too_big: actual -28 != expected -22
With 64KB page size, the xdp frame size will be much bigger so
the existing test will fail.
Adjust various parameters so the test can also work on 64K page size.
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
.../selftests/bpf/prog_tests/xdp_do_redirect.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c b/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
index 7dac044664ac..dd34b0cc4b4e 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
@@ -66,16 +66,25 @@ static int attach_tc_prog(struct bpf_tc_hook *hook, int fd)
#else
#define MAX_PKT_SIZE 3408
#endif
+
+#define PAGE_SIZE_4K 4096
+#define PAGE_SIZE_64K 65536
+
static void test_max_pkt_size(int fd)
{
- char data[MAX_PKT_SIZE + 1] = {};
+ char data[PAGE_SIZE_64K + 1] = {};
int err;
DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts,
.data_in = &data,
- .data_size_in = MAX_PKT_SIZE,
.flags = BPF_F_TEST_XDP_LIVE_FRAMES,
.repeat = 1,
);
+
+ if (getpagesize() == PAGE_SIZE_64K)
+ opts.data_size_in = MAX_PKT_SIZE + PAGE_SIZE_64K - PAGE_SIZE_4K;
+ else
+ opts.data_size_in = MAX_PKT_SIZE;
+
err = bpf_prog_test_run_opts(fd, &opts);
ASSERT_OK(err, "prog_run_max_size");
--
2.47.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 2/3] selftests/bpf: Fix two net related test failures with 64K page size
2025-06-11 17:15 ` [PATCH bpf-next v2 2/3] selftests/bpf: Fix two net related test failures with 64K page size Yonghong Song
@ 2025-06-11 19:21 ` Alexei Starovoitov
2025-06-12 1:59 ` Yonghong Song
0 siblings, 1 reply; 8+ messages in thread
From: Alexei Starovoitov @ 2025-06-11 19:21 UTC (permalink / raw)
To: Yonghong Song
Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Kernel Team, Martin KaFai Lau
On Wed, Jun 11, 2025 at 10:15 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>
> When running BPF selftests on arm64 with a 64K page size, I encountered
> the following two test failures:
> sockmap_basic/sockmap skb_verdict change tail:FAIL
> tc_change_tail:FAIL
>
> With further debugging, I identified the root cause in the following
> kernel code within __bpf_skb_change_tail():
>
> u32 max_len = BPF_SKB_MAX_LEN;
> u32 min_len = __bpf_skb_min_len(skb);
> int ret;
>
> if (unlikely(flags || new_len > max_len || new_len < min_len))
> return -EINVAL;
>
> With a 4K page size, new_len = 65535 and max_len = 16064, the function
> returns -EINVAL. However, With a 64K page size, max_len increases to
> 261824, allowing execution to proceed further in the function. This is
> because BPF_SKB_MAX_LEN scales with the page size and larger page sizes
> result in higher max_len values.
>
> Updating the new_len parameter in both tests from 65535 to 256K (0x40000)
> resolves the failures.
>
> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
> ---
> tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c | 5 ++++-
> tools/testing/selftests/bpf/progs/test_tc_change_tail.c | 5 ++++-
> 2 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c b/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c
> index 2796dd8545eb..e4554ef05441 100644
> --- a/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c
> +++ b/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c
> @@ -3,6 +3,9 @@
> #include <linux/bpf.h>
> #include <bpf/bpf_helpers.h>
>
> +#define PAGE_SIZE 65536 /* make it work on 64K page arches */
> +#define BPF_SKB_MAX_LEN (PAGE_SIZE << 2)
> +
> struct {
> __uint(type, BPF_MAP_TYPE_SOCKMAP);
> __uint(max_entries, 1);
> @@ -31,7 +34,7 @@ int prog_skb_verdict(struct __sk_buff *skb)
> change_tail_ret = bpf_skb_change_tail(skb, skb->len + 1, 0);
> return SK_PASS;
> } else if (data[0] == 'E') { /* Error */
> - change_tail_ret = bpf_skb_change_tail(skb, 65535, 0);
> + change_tail_ret = bpf_skb_change_tail(skb, BPF_SKB_MAX_LEN, 0);
> return SK_PASS;
> }
> return SK_PASS;
> diff --git a/tools/testing/selftests/bpf/progs/test_tc_change_tail.c b/tools/testing/selftests/bpf/progs/test_tc_change_tail.c
> index 28edafe803f0..47670bbd1766 100644
> --- a/tools/testing/selftests/bpf/progs/test_tc_change_tail.c
> +++ b/tools/testing/selftests/bpf/progs/test_tc_change_tail.c
> @@ -7,6 +7,9 @@
> #include <linux/udp.h>
> #include <linux/pkt_cls.h>
>
> +#define PAGE_SIZE 65536 /* make it work on 64K page arches */
> +#define BPF_SKB_MAX_LEN (PAGE_SIZE << 2)
If you want it to match the kernel then let's use actual page size?
See bpf_arena_common.h and
#ifndef PAGE_SIZE
#define PAGE_SIZE __PAGE_SIZE
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 1/3] bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than 4K
2025-06-11 17:15 ` [PATCH bpf-next v2 1/3] bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than 4K Yonghong Song
@ 2025-06-11 19:24 ` Alexei Starovoitov
2025-06-12 1:53 ` Yonghong Song
0 siblings, 1 reply; 8+ messages in thread
From: Alexei Starovoitov @ 2025-06-11 19:24 UTC (permalink / raw)
To: Yonghong Song
Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Kernel Team, Martin KaFai Lau
On Wed, Jun 11, 2025 at 10:15 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>
> The bpf selftest xdp_adjust_tail/xdp_adjust_frags_tail_grow failed on
> arm64 with 64KB page:
> xdp_adjust_tail/xdp_adjust_frags_tail_grow:FAIL
>
> In bpf_prog_test_run_xdp(), the xdp->frame_sz is set to 4K, but later on
> when constructing frags, with 64K page size, the frag data_len could
> be more than 4K. This will cause problems in bpf_xdp_frags_increase_tail().
>
> To fix the failure, the xdp->frame_sz is set to be PAGE_SIZE so kernel
> can test different page size properly. With the kernel change, the user
> space and bpf prog needs adjustment. Currently, the MAX_SKB_FRAGS default
> value is 17, so for 4K page, the maximum packet size will be less than 68K.
> To test 64K page, a bigger maximum packet size than 68K is desired. So two
> different functions are implemented for subtest xdp_adjust_frags_tail_grow.
> Depending on different page size, different data input/output sizes are used
> to adapt with different page size.
>
> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
> ---
> net/bpf/test_run.c | 2 +-
> .../bpf/prog_tests/xdp_adjust_tail.c | 95 +++++++++++++++++--
> .../bpf/progs/test_xdp_adjust_tail_grow.c | 8 +-
> 3 files changed, 96 insertions(+), 9 deletions(-)
>
> diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
> index aaf13a7d58ed..9728dbd4c66c 100644
> --- a/net/bpf/test_run.c
> +++ b/net/bpf/test_run.c
> @@ -1255,7 +1255,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
> headroom -= ctx->data;
> }
>
> - max_data_sz = 4096 - headroom - tailroom;
> + max_data_sz = PAGE_SIZE - headroom - tailroom;
> if (size > max_data_sz) {
> /* disallow live data mode for jumbo frames */
> if (do_live)
> diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
> index e361129402a1..133bde28a489 100644
> --- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
> +++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
> @@ -37,21 +37,25 @@ static void test_xdp_adjust_tail_shrink(void)
> bpf_object__close(obj);
> }
>
> -static void test_xdp_adjust_tail_grow(void)
> +static void test_xdp_adjust_tail_grow(bool is_64k_pagesize)
> {
> const char *file = "./test_xdp_adjust_tail_grow.bpf.o";
> struct bpf_object *obj;
> - char buf[4096]; /* avoid segfault: large buf to hold grow results */
> + char buf[8192]; /* avoid segfault: large buf to hold grow results */
> __u32 expect_sz;
> int err, prog_fd;
> LIBBPF_OPTS(bpf_test_run_opts, topts,
> .data_in = &pkt_v4,
> - .data_size_in = sizeof(pkt_v4),
> .data_out = buf,
> .data_size_out = sizeof(buf),
> .repeat = 1,
> );
>
> + if (is_64k_pagesize)
> + topts.data_size_in = sizeof(pkt_v4) - 1;
> + else
> + topts.data_size_in = sizeof(pkt_v4);
Please add a comment that magic data size is a special
signal to bpf prog:
> if (data_len == 54) { /* sizeof(pkt_v4) */
> - offset = 4096; /* test too large offset */
> + offset = 4096; /* test too large offset, 4k page size */
> + } else if (data_len == 53) { /* sizeof(pkt_v4) - 1 */
> + offset = 65536; /* test too large offset, 64k page size */
> } else if (data_len == 74) { /* sizeof(pkt_v6) */
> offset = 40;
and comment about 90000, 90001 sizes.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 1/3] bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than 4K
2025-06-11 19:24 ` Alexei Starovoitov
@ 2025-06-12 1:53 ` Yonghong Song
0 siblings, 0 replies; 8+ messages in thread
From: Yonghong Song @ 2025-06-12 1:53 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Kernel Team, Martin KaFai Lau
On 6/11/25 12:24 PM, Alexei Starovoitov wrote:
> On Wed, Jun 11, 2025 at 10:15 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>> The bpf selftest xdp_adjust_tail/xdp_adjust_frags_tail_grow failed on
>> arm64 with 64KB page:
>> xdp_adjust_tail/xdp_adjust_frags_tail_grow:FAIL
>>
>> In bpf_prog_test_run_xdp(), the xdp->frame_sz is set to 4K, but later on
>> when constructing frags, with 64K page size, the frag data_len could
>> be more than 4K. This will cause problems in bpf_xdp_frags_increase_tail().
>>
>> To fix the failure, the xdp->frame_sz is set to be PAGE_SIZE so kernel
>> can test different page size properly. With the kernel change, the user
>> space and bpf prog needs adjustment. Currently, the MAX_SKB_FRAGS default
>> value is 17, so for 4K page, the maximum packet size will be less than 68K.
>> To test 64K page, a bigger maximum packet size than 68K is desired. So two
>> different functions are implemented for subtest xdp_adjust_frags_tail_grow.
>> Depending on different page size, different data input/output sizes are used
>> to adapt with different page size.
>>
>> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
>> ---
>> net/bpf/test_run.c | 2 +-
>> .../bpf/prog_tests/xdp_adjust_tail.c | 95 +++++++++++++++++--
>> .../bpf/progs/test_xdp_adjust_tail_grow.c | 8 +-
>> 3 files changed, 96 insertions(+), 9 deletions(-)
>>
>> diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
>> index aaf13a7d58ed..9728dbd4c66c 100644
>> --- a/net/bpf/test_run.c
>> +++ b/net/bpf/test_run.c
>> @@ -1255,7 +1255,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
>> headroom -= ctx->data;
>> }
>>
>> - max_data_sz = 4096 - headroom - tailroom;
>> + max_data_sz = PAGE_SIZE - headroom - tailroom;
>> if (size > max_data_sz) {
>> /* disallow live data mode for jumbo frames */
>> if (do_live)
>> diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
>> index e361129402a1..133bde28a489 100644
>> --- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
>> +++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
>> @@ -37,21 +37,25 @@ static void test_xdp_adjust_tail_shrink(void)
>> bpf_object__close(obj);
>> }
>>
>> -static void test_xdp_adjust_tail_grow(void)
>> +static void test_xdp_adjust_tail_grow(bool is_64k_pagesize)
>> {
>> const char *file = "./test_xdp_adjust_tail_grow.bpf.o";
>> struct bpf_object *obj;
>> - char buf[4096]; /* avoid segfault: large buf to hold grow results */
>> + char buf[8192]; /* avoid segfault: large buf to hold grow results */
>> __u32 expect_sz;
>> int err, prog_fd;
>> LIBBPF_OPTS(bpf_test_run_opts, topts,
>> .data_in = &pkt_v4,
>> - .data_size_in = sizeof(pkt_v4),
>> .data_out = buf,
>> .data_size_out = sizeof(buf),
>> .repeat = 1,
>> );
>>
>> + if (is_64k_pagesize)
>> + topts.data_size_in = sizeof(pkt_v4) - 1;
>> + else
>> + topts.data_size_in = sizeof(pkt_v4);
> Please add a comment that magic data size is a special
> signal to bpf prog:
Ok, will add a comment to explain this.
>
>> if (data_len == 54) { /* sizeof(pkt_v4) */
>> - offset = 4096; /* test too large offset */
>> + offset = 4096; /* test too large offset, 4k page size */
>> + } else if (data_len == 53) { /* sizeof(pkt_v4) - 1 */
>> + offset = 65536; /* test too large offset, 64k page size */
>> } else if (data_len == 74) { /* sizeof(pkt_v6) */
>> offset = 40;
> and comment about 90000, 90001 sizes.
Ack as well.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v2 2/3] selftests/bpf: Fix two net related test failures with 64K page size
2025-06-11 19:21 ` Alexei Starovoitov
@ 2025-06-12 1:59 ` Yonghong Song
0 siblings, 0 replies; 8+ messages in thread
From: Yonghong Song @ 2025-06-12 1:59 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Kernel Team, Martin KaFai Lau
On 6/11/25 12:21 PM, Alexei Starovoitov wrote:
> On Wed, Jun 11, 2025 at 10:15 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>> When running BPF selftests on arm64 with a 64K page size, I encountered
>> the following two test failures:
>> sockmap_basic/sockmap skb_verdict change tail:FAIL
>> tc_change_tail:FAIL
>>
>> With further debugging, I identified the root cause in the following
>> kernel code within __bpf_skb_change_tail():
>>
>> u32 max_len = BPF_SKB_MAX_LEN;
>> u32 min_len = __bpf_skb_min_len(skb);
>> int ret;
>>
>> if (unlikely(flags || new_len > max_len || new_len < min_len))
>> return -EINVAL;
>>
>> With a 4K page size, new_len = 65535 and max_len = 16064, the function
>> returns -EINVAL. However, With a 64K page size, max_len increases to
>> 261824, allowing execution to proceed further in the function. This is
>> because BPF_SKB_MAX_LEN scales with the page size and larger page sizes
>> result in higher max_len values.
>>
>> Updating the new_len parameter in both tests from 65535 to 256K (0x40000)
>> resolves the failures.
>>
>> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
>> ---
>> tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c | 5 ++++-
>> tools/testing/selftests/bpf/progs/test_tc_change_tail.c | 5 ++++-
>> 2 files changed, 8 insertions(+), 2 deletions(-)
>>
>> diff --git a/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c b/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c
>> index 2796dd8545eb..e4554ef05441 100644
>> --- a/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c
>> +++ b/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c
>> @@ -3,6 +3,9 @@
>> #include <linux/bpf.h>
>> #include <bpf/bpf_helpers.h>
>>
>> +#define PAGE_SIZE 65536 /* make it work on 64K page arches */
>> +#define BPF_SKB_MAX_LEN (PAGE_SIZE << 2)
>> +
>> struct {
>> __uint(type, BPF_MAP_TYPE_SOCKMAP);
>> __uint(max_entries, 1);
>> @@ -31,7 +34,7 @@ int prog_skb_verdict(struct __sk_buff *skb)
>> change_tail_ret = bpf_skb_change_tail(skb, skb->len + 1, 0);
>> return SK_PASS;
>> } else if (data[0] == 'E') { /* Error */
>> - change_tail_ret = bpf_skb_change_tail(skb, 65535, 0);
>> + change_tail_ret = bpf_skb_change_tail(skb, BPF_SKB_MAX_LEN, 0);
>> return SK_PASS;
>> }
>> return SK_PASS;
>> diff --git a/tools/testing/selftests/bpf/progs/test_tc_change_tail.c b/tools/testing/selftests/bpf/progs/test_tc_change_tail.c
>> index 28edafe803f0..47670bbd1766 100644
>> --- a/tools/testing/selftests/bpf/progs/test_tc_change_tail.c
>> +++ b/tools/testing/selftests/bpf/progs/test_tc_change_tail.c
>> @@ -7,6 +7,9 @@
>> #include <linux/udp.h>
>> #include <linux/pkt_cls.h>
>>
>> +#define PAGE_SIZE 65536 /* make it work on 64K page arches */
>> +#define BPF_SKB_MAX_LEN (PAGE_SIZE << 2)
> If you want it to match the kernel then let's use actual page size?
> See bpf_arena_common.h and
> #ifndef PAGE_SIZE
> #define PAGE_SIZE __PAGE_SIZE
LGTM. This will allow to use actual page size...
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-06-12 1:59 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-11 17:15 [PATCH bpf-next v2 0/3] bpf: Fix a few test failures with 64K page size Yonghong Song
2025-06-11 17:15 ` [PATCH bpf-next v2 1/3] bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than 4K Yonghong Song
2025-06-11 19:24 ` Alexei Starovoitov
2025-06-12 1:53 ` Yonghong Song
2025-06-11 17:15 ` [PATCH bpf-next v2 2/3] selftests/bpf: Fix two net related test failures with 64K page size Yonghong Song
2025-06-11 19:21 ` Alexei Starovoitov
2025-06-12 1:59 ` Yonghong Song
2025-06-11 17:15 ` [PATCH bpf-next v2 3/3] selftests/bpf: Fix xdp_do_redirect failure with 64KB " Yonghong Song
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).