Skip to content

Commit 202c5b9

Browse files
Yonghong Songgregkh
authored andcommitted
bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than 4K
[ Upstream commit 4fc012d ] 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> Link: https://lore.kernel.org/r/20250612035032.2207498-1-yonghong.song@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org> Stable-dep-of: e558cca ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 5c64774 commit 202c5b9

3 files changed

Lines changed: 97 additions & 9 deletions

File tree

net/bpf/test_run.c

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

1251-
max_data_sz = 4096 - headroom - tailroom;
1251+
max_data_sz = PAGE_SIZE - headroom - tailroom;
12521252
if (size > max_data_sz) {
12531253
/* disallow live data mode for jumbo frames */
12541254
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;
@@ -206,7 +211,7 @@ static void test_xdp_adjust_frags_tail_shrink(void)
206211
bpf_object__close(obj);
207212
}
208213

209-
static void test_xdp_adjust_frags_tail_grow(void)
214+
static void test_xdp_adjust_frags_tail_grow_4k(void)
210215
{
211216
const char *file = "./test_xdp_adjust_tail_grow.bpf.o";
212217
__u32 exp_size;
@@ -271,16 +276,93 @@ static void test_xdp_adjust_frags_tail_grow(void)
271276
bpf_object__close(obj);
272277
}
273278

279+
static void test_xdp_adjust_frags_tail_grow_64k(void)
280+
{
281+
const char *file = "./test_xdp_adjust_tail_grow.bpf.o";
282+
__u32 exp_size;
283+
struct bpf_program *prog;
284+
struct bpf_object *obj;
285+
int err, i, prog_fd;
286+
__u8 *buf;
287+
LIBBPF_OPTS(bpf_test_run_opts, topts);
288+
289+
obj = bpf_object__open(file);
290+
if (libbpf_get_error(obj))
291+
return;
292+
293+
prog = bpf_object__next_program(obj, NULL);
294+
if (bpf_object__load(obj))
295+
goto out;
296+
297+
prog_fd = bpf_program__fd(prog);
298+
299+
buf = malloc(262144);
300+
if (!ASSERT_OK_PTR(buf, "alloc buf 256Kb"))
301+
goto out;
302+
303+
/* Test case add 10 bytes to last frag */
304+
memset(buf, 1, 262144);
305+
exp_size = 90000 + 10;
306+
307+
topts.data_in = buf;
308+
topts.data_out = buf;
309+
topts.data_size_in = 90000;
310+
topts.data_size_out = 262144;
311+
err = bpf_prog_test_run_opts(prog_fd, &topts);
312+
313+
ASSERT_OK(err, "90Kb+10b");
314+
ASSERT_EQ(topts.retval, XDP_TX, "90Kb+10b retval");
315+
ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size");
316+
317+
for (i = 0; i < 90000; i++) {
318+
if (buf[i] != 1)
319+
ASSERT_EQ(buf[i], 1, "90Kb+10b-old");
320+
}
321+
322+
for (i = 90000; i < 90010; i++) {
323+
if (buf[i] != 0)
324+
ASSERT_EQ(buf[i], 0, "90Kb+10b-new");
325+
}
326+
327+
for (i = 90010; i < 262144; i++) {
328+
if (buf[i] != 1)
329+
ASSERT_EQ(buf[i], 1, "90Kb+10b-untouched");
330+
}
331+
332+
/* Test a too large grow */
333+
memset(buf, 1, 262144);
334+
exp_size = 90001;
335+
336+
topts.data_in = topts.data_out = buf;
337+
topts.data_size_in = 90001;
338+
topts.data_size_out = 262144;
339+
err = bpf_prog_test_run_opts(prog_fd, &topts);
340+
341+
ASSERT_OK(err, "90Kb+10b");
342+
ASSERT_EQ(topts.retval, XDP_DROP, "90Kb+10b retval");
343+
ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size");
344+
345+
free(buf);
346+
out:
347+
bpf_object__close(obj);
348+
}
349+
274350
void test_xdp_adjust_tail(void)
275351
{
352+
int page_size = getpagesize();
353+
276354
if (test__start_subtest("xdp_adjust_tail_shrink"))
277355
test_xdp_adjust_tail_shrink();
278356
if (test__start_subtest("xdp_adjust_tail_grow"))
279-
test_xdp_adjust_tail_grow();
357+
test_xdp_adjust_tail_grow(page_size == 65536);
280358
if (test__start_subtest("xdp_adjust_tail_grow2"))
281359
test_xdp_adjust_tail_grow2();
282360
if (test__start_subtest("xdp_adjust_frags_tail_shrink"))
283361
test_xdp_adjust_frags_tail_shrink();
284-
if (test__start_subtest("xdp_adjust_frags_tail_grow"))
285-
test_xdp_adjust_frags_tail_grow();
362+
if (test__start_subtest("xdp_adjust_frags_tail_grow")) {
363+
if (page_size == 65536)
364+
test_xdp_adjust_frags_tail_grow_64k();
365+
else
366+
test_xdp_adjust_frags_tail_grow_4k();
367+
}
286368
}

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
@@ -17,7 +17,9 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp)
1717
/* Data length determine test case */
1818

1919
if (data_len == 54) { /* sizeof(pkt_v4) */
20-
offset = 4096; /* test too large offset */
20+
offset = 4096; /* test too large offset, 4k page size */
21+
} else if (data_len == 53) { /* sizeof(pkt_v4) - 1 */
22+
offset = 65536; /* test too large offset, 64k page size */
2123
} else if (data_len == 74) { /* sizeof(pkt_v6) */
2224
offset = 40;
2325
} else if (data_len == 64) {
@@ -29,6 +31,10 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp)
2931
offset = 10;
3032
} else if (data_len == 9001) {
3133
offset = 4096;
34+
} else if (data_len == 90000) {
35+
offset = 10; /* test a small offset, 64k page size */
36+
} else if (data_len == 90001) {
37+
offset = 65536; /* test too large offset, 64k page size */
3238
} else {
3339
return XDP_ABORTED; /* No matching test */
3440
}

0 commit comments

Comments
 (0)