Skip to content

Commit 0e93df4

Browse files
author
Alexei Starovoitov
committed
Merge branch 'bpf-fix-a-few-test-failures-with-64k-page-size'
Yonghong Song says: ==================== bpf: Fix a few test failures with 64K page size Changelog: v2 -> v3: - v2: https://lore.kernel.org/bpf/[email protected]/ - Add additional comments for xdp_adjust_tail test. - Use actual kernel page size to set new_len for Patch 2 tests. v1 -> v2: - v1: https://lore.kernel.org/bpf/[email protected]/ - 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). ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents fa69325 + 44df9e0 commit 0e93df4

File tree

6 files changed

+122
-20
lines changed

6 files changed

+122
-20
lines changed

net/bpf/test_run.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
12551255
headroom -= ctx->data;
12561256
}
12571257

1258-
max_data_sz = 4096 - headroom - tailroom;
1258+
max_data_sz = PAGE_SIZE - headroom - tailroom;
12591259
if (size > max_data_sz) {
12601260
/* disallow live data mode for jumbo frames */
12611261
if (do_live)

tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,26 @@ static void test_xdp_adjust_tail_shrink(void)
3737
bpf_object__close(obj);
3838
}
3939

40-
static void test_xdp_adjust_tail_grow(void)
40+
static void test_xdp_adjust_tail_grow(bool is_64k_pagesize)
4141
{
4242
const char *file = "./test_xdp_adjust_tail_grow.bpf.o";
4343
struct bpf_object *obj;
44-
char buf[4096]; /* avoid segfault: large buf to hold grow results */
44+
char buf[8192]; /* avoid segfault: large buf to hold grow results */
4545
__u32 expect_sz;
4646
int err, prog_fd;
4747
LIBBPF_OPTS(bpf_test_run_opts, topts,
4848
.data_in = &pkt_v4,
49-
.data_size_in = sizeof(pkt_v4),
5049
.data_out = buf,
5150
.data_size_out = sizeof(buf),
5251
.repeat = 1,
5352
);
5453

54+
/* topts.data_size_in as a special signal to bpf prog */
55+
if (is_64k_pagesize)
56+
topts.data_size_in = sizeof(pkt_v4) - 1;
57+
else
58+
topts.data_size_in = sizeof(pkt_v4);
59+
5560
err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
5661
if (!ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
5762
return;
@@ -208,7 +213,7 @@ static void test_xdp_adjust_frags_tail_shrink(void)
208213
bpf_object__close(obj);
209214
}
210215

211-
static void test_xdp_adjust_frags_tail_grow(void)
216+
static void test_xdp_adjust_frags_tail_grow_4k(void)
212217
{
213218
const char *file = "./test_xdp_adjust_tail_grow.bpf.o";
214219
__u32 exp_size;
@@ -279,16 +284,93 @@ static void test_xdp_adjust_frags_tail_grow(void)
279284
bpf_object__close(obj);
280285
}
281286

287+
static void test_xdp_adjust_frags_tail_grow_64k(void)
288+
{
289+
const char *file = "./test_xdp_adjust_tail_grow.bpf.o";
290+
__u32 exp_size;
291+
struct bpf_program *prog;
292+
struct bpf_object *obj;
293+
int err, i, prog_fd;
294+
__u8 *buf;
295+
LIBBPF_OPTS(bpf_test_run_opts, topts);
296+
297+
obj = bpf_object__open(file);
298+
if (libbpf_get_error(obj))
299+
return;
300+
301+
prog = bpf_object__next_program(obj, NULL);
302+
if (bpf_object__load(obj))
303+
goto out;
304+
305+
prog_fd = bpf_program__fd(prog);
306+
307+
buf = malloc(262144);
308+
if (!ASSERT_OK_PTR(buf, "alloc buf 256Kb"))
309+
goto out;
310+
311+
/* Test case add 10 bytes to last frag */
312+
memset(buf, 1, 262144);
313+
exp_size = 90000 + 10;
314+
315+
topts.data_in = buf;
316+
topts.data_out = buf;
317+
topts.data_size_in = 90000;
318+
topts.data_size_out = 262144;
319+
err = bpf_prog_test_run_opts(prog_fd, &topts);
320+
321+
ASSERT_OK(err, "90Kb+10b");
322+
ASSERT_EQ(topts.retval, XDP_TX, "90Kb+10b retval");
323+
ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size");
324+
325+
for (i = 0; i < 90000; i++) {
326+
if (buf[i] != 1)
327+
ASSERT_EQ(buf[i], 1, "90Kb+10b-old");
328+
}
329+
330+
for (i = 90000; i < 90010; i++) {
331+
if (buf[i] != 0)
332+
ASSERT_EQ(buf[i], 0, "90Kb+10b-new");
333+
}
334+
335+
for (i = 90010; i < 262144; i++) {
336+
if (buf[i] != 1)
337+
ASSERT_EQ(buf[i], 1, "90Kb+10b-untouched");
338+
}
339+
340+
/* Test a too large grow */
341+
memset(buf, 1, 262144);
342+
exp_size = 90001;
343+
344+
topts.data_in = topts.data_out = buf;
345+
topts.data_size_in = 90001;
346+
topts.data_size_out = 262144;
347+
err = bpf_prog_test_run_opts(prog_fd, &topts);
348+
349+
ASSERT_OK(err, "90Kb+10b");
350+
ASSERT_EQ(topts.retval, XDP_DROP, "90Kb+10b retval");
351+
ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size");
352+
353+
free(buf);
354+
out:
355+
bpf_object__close(obj);
356+
}
357+
282358
void test_xdp_adjust_tail(void)
283359
{
360+
int page_size = getpagesize();
361+
284362
if (test__start_subtest("xdp_adjust_tail_shrink"))
285363
test_xdp_adjust_tail_shrink();
286364
if (test__start_subtest("xdp_adjust_tail_grow"))
287-
test_xdp_adjust_tail_grow();
365+
test_xdp_adjust_tail_grow(page_size == 65536);
288366
if (test__start_subtest("xdp_adjust_tail_grow2"))
289367
test_xdp_adjust_tail_grow2();
290368
if (test__start_subtest("xdp_adjust_frags_tail_shrink"))
291369
test_xdp_adjust_frags_tail_shrink();
292-
if (test__start_subtest("xdp_adjust_frags_tail_grow"))
293-
test_xdp_adjust_frags_tail_grow();
370+
if (test__start_subtest("xdp_adjust_frags_tail_grow")) {
371+
if (page_size == 65536)
372+
test_xdp_adjust_frags_tail_grow_64k();
373+
else
374+
test_xdp_adjust_frags_tail_grow_4k();
375+
}
294376
}

tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,25 @@ static int attach_tc_prog(struct bpf_tc_hook *hook, int fd)
6666
#else
6767
#define MAX_PKT_SIZE 3408
6868
#endif
69+
70+
#define PAGE_SIZE_4K 4096
71+
#define PAGE_SIZE_64K 65536
72+
6973
static void test_max_pkt_size(int fd)
7074
{
71-
char data[MAX_PKT_SIZE + 1] = {};
75+
char data[PAGE_SIZE_64K + 1] = {};
7276
int err;
7377
DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts,
7478
.data_in = &data,
75-
.data_size_in = MAX_PKT_SIZE,
7679
.flags = BPF_F_TEST_XDP_LIVE_FRAMES,
7780
.repeat = 1,
7881
);
82+
83+
if (getpagesize() == PAGE_SIZE_64K)
84+
opts.data_size_in = MAX_PKT_SIZE + PAGE_SIZE_64K - PAGE_SIZE_4K;
85+
else
86+
opts.data_size_in = MAX_PKT_SIZE;
87+
7988
err = bpf_prog_test_run_opts(fd, &opts);
8089
ASSERT_OK(err, "prog_run_max_size");
8190

tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
// SPDX-License-Identifier: GPL-2.0
22
/* Copyright (c) 2024 ByteDance */
3-
#include <linux/bpf.h>
3+
#include "vmlinux.h"
44
#include <bpf/bpf_helpers.h>
55

6+
#ifndef PAGE_SIZE
7+
#define PAGE_SIZE __PAGE_SIZE
8+
#endif
9+
#define BPF_SKB_MAX_LEN (PAGE_SIZE << 2)
10+
611
struct {
712
__uint(type, BPF_MAP_TYPE_SOCKMAP);
813
__uint(max_entries, 1);
@@ -31,7 +36,7 @@ int prog_skb_verdict(struct __sk_buff *skb)
3136
change_tail_ret = bpf_skb_change_tail(skb, skb->len + 1, 0);
3237
return SK_PASS;
3338
} else if (data[0] == 'E') { /* Error */
34-
change_tail_ret = bpf_skb_change_tail(skb, 65535, 0);
39+
change_tail_ret = bpf_skb_change_tail(skb, BPF_SKB_MAX_LEN, 0);
3540
return SK_PASS;
3641
}
3742
return SK_PASS;

tools/testing/selftests/bpf/progs/test_tc_change_tail.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// SPDX-License-Identifier: GPL-2.0
2-
#include <linux/bpf.h>
2+
#include "vmlinux.h"
33
#include <bpf/bpf_helpers.h>
4-
#include <linux/if_ether.h>
5-
#include <linux/in.h>
6-
#include <linux/ip.h>
7-
#include <linux/udp.h>
8-
#include <linux/pkt_cls.h>
4+
5+
#ifndef PAGE_SIZE
6+
#define PAGE_SIZE __PAGE_SIZE
7+
#endif
8+
#define BPF_SKB_MAX_LEN (PAGE_SIZE << 2)
99

1010
long change_tail_ret = 1;
1111

@@ -94,7 +94,7 @@ int change_tail(struct __sk_buff *skb)
9494
bpf_skb_change_tail(skb, len, 0);
9595
return TCX_PASS;
9696
} else if (payload[0] == 'E') { /* Error */
97-
change_tail_ret = bpf_skb_change_tail(skb, 65535, 0);
97+
change_tail_ret = bpf_skb_change_tail(skb, BPF_SKB_MAX_LEN, 0);
9898
return TCX_PASS;
9999
} else if (payload[0] == 'Z') { /* Zero */
100100
change_tail_ret = bpf_skb_change_tail(skb, 0, 0);

tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp)
1919
/* Data length determine test case */
2020

2121
if (data_len == 54) { /* sizeof(pkt_v4) */
22-
offset = 4096; /* test too large offset */
22+
offset = 4096; /* test too large offset, 4k page size */
23+
} else if (data_len == 53) { /* sizeof(pkt_v4) - 1 */
24+
offset = 65536; /* test too large offset, 64k page size */
2325
} else if (data_len == 74) { /* sizeof(pkt_v6) */
2426
offset = 40;
2527
} else if (data_len == 64) {
@@ -31,6 +33,10 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp)
3133
offset = 10;
3234
} else if (data_len == 9001) {
3335
offset = 4096;
36+
} else if (data_len == 90000) {
37+
offset = 10; /* test a small offset, 64k page size */
38+
} else if (data_len == 90001) {
39+
offset = 65536; /* test too large offset, 64k page size */
3440
} else {
3541
return XDP_ABORTED; /* No matching test */
3642
}

0 commit comments

Comments
 (0)