selftests/bpf: Fix two net related test failures with 64K page size
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 based on actual kernel
page size resolved both failures.
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/r/20250612035037.2207911-1-yonghong.song@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Alexei Starovoitov
parent
4fc012daf9
commit
96fcf7e7a7
@@ -1,8 +1,13 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2024 ByteDance */
|
||||
#include <linux/bpf.h>
|
||||
#include "vmlinux.h"
|
||||
#include <bpf/bpf_helpers.h>
|
||||
|
||||
#ifndef PAGE_SIZE
|
||||
#define PAGE_SIZE __PAGE_SIZE
|
||||
#endif
|
||||
#define BPF_SKB_MAX_LEN (PAGE_SIZE << 2)
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_SOCKMAP);
|
||||
__uint(max_entries, 1);
|
||||
@@ -31,7 +36,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;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/bpf.h>
|
||||
#include "vmlinux.h"
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/pkt_cls.h>
|
||||
|
||||
#ifndef PAGE_SIZE
|
||||
#define PAGE_SIZE __PAGE_SIZE
|
||||
#endif
|
||||
#define BPF_SKB_MAX_LEN (PAGE_SIZE << 2)
|
||||
|
||||
long change_tail_ret = 1;
|
||||
|
||||
@@ -94,7 +94,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);
|
||||
|
||||
Reference in New Issue
Block a user