On 6/11/25 12:21 PM, Alexei Starovoitov wrote:
On Wed, Jun 11, 2025 at 10:15 AM Yonghong Song <yonghong.song@xxxxxxxxx> 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@xxxxxxxxx>
---
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...