Skip to content

Commit 4fc012d

Browse files
Yonghong SongAlexei Starovoitov
authored andcommitted
bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than 4K
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent fa69325 commit 4fc012d

File tree

3 files changed

+97
-9
lines changed

3 files changed

+97
-9
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/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)