Skip to content

Commit 19d5a53

Browse files
bastien-curutchetKernel Patches Daemon
authored andcommitted
selftests/bpf: test_xsk: Don't exit immediately on allocation failures
If any allocation in the pkt_stream_*() helpers fail, exit_with_error() is called. This terminates the program immediately. It prevents the following tests from running and isn't compliant with the CI. Return NULL in case of allocation failure. Return TEST_FAILURE when something goes wrong in the packet generation. Clean up the resources if a failure happens between two steps of a test. Signed-off-by: Bastien Curutchet (eBPF Foundation) <[email protected]>
1 parent 73ed5a9 commit 19d5a53

File tree

1 file changed

+101
-35
lines changed

1 file changed

+101
-35
lines changed

tools/testing/selftests/bpf/test_xsk.c

Lines changed: 101 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ static struct pkt_stream *__pkt_stream_generate(u32 nb_pkts, u32 pkt_len, u32 nb
489489

490490
pkt_stream = __pkt_stream_alloc(nb_pkts);
491491
if (!pkt_stream)
492-
exit_with_error(ENOMEM);
492+
return NULL;
493493

494494
pkt_stream->nb_pkts = nb_pkts;
495495
pkt_stream->max_pkt_len = pkt_len;
@@ -513,37 +513,56 @@ static struct pkt_stream *pkt_stream_clone(struct pkt_stream *pkt_stream)
513513
return pkt_stream_generate(pkt_stream->nb_pkts, pkt_stream->pkts[0].len);
514514
}
515515

516-
static void pkt_stream_replace_ifobject(struct ifobject *ifobj, u32 nb_pkts, u32 pkt_len)
516+
static int pkt_stream_replace_ifobject(struct ifobject *ifobj, u32 nb_pkts, u32 pkt_len)
517517
{
518518
ifobj->xsk->pkt_stream = pkt_stream_generate(nb_pkts, pkt_len);
519+
520+
if (!ifobj->xsk->pkt_stream)
521+
return -ENOMEM;
522+
523+
return 0;
519524
}
520525

521-
static void pkt_stream_replace(struct test_spec *test, u32 nb_pkts, u32 pkt_len)
526+
static int pkt_stream_replace(struct test_spec *test, u32 nb_pkts, u32 pkt_len)
522527
{
523-
pkt_stream_replace_ifobject(test->ifobj_tx, nb_pkts, pkt_len);
524-
pkt_stream_replace_ifobject(test->ifobj_rx, nb_pkts, pkt_len);
528+
int ret;
529+
530+
ret = pkt_stream_replace_ifobject(test->ifobj_tx, nb_pkts, pkt_len);
531+
if (ret)
532+
return ret;
533+
534+
return pkt_stream_replace_ifobject(test->ifobj_rx, nb_pkts, pkt_len);
525535
}
526536

527-
static void __pkt_stream_replace_half(struct ifobject *ifobj, u32 pkt_len,
537+
static int __pkt_stream_replace_half(struct ifobject *ifobj, u32 pkt_len,
528538
int offset)
529539
{
530540
struct pkt_stream *pkt_stream;
531541
u32 i;
532542

533543
pkt_stream = pkt_stream_clone(ifobj->xsk->pkt_stream);
544+
if (!pkt_stream)
545+
return -ENOMEM;
546+
534547
for (i = 1; i < ifobj->xsk->pkt_stream->nb_pkts; i += 2)
535548
pkt_stream_pkt_set(pkt_stream, &pkt_stream->pkts[i], offset, pkt_len);
536549

537550
ifobj->xsk->pkt_stream = pkt_stream;
551+
552+
return 0;
538553
}
539554

540-
static void pkt_stream_replace_half(struct test_spec *test, u32 pkt_len, int offset)
555+
static int pkt_stream_replace_half(struct test_spec *test, u32 pkt_len, int offset)
541556
{
542-
__pkt_stream_replace_half(test->ifobj_tx, pkt_len, offset);
543-
__pkt_stream_replace_half(test->ifobj_rx, pkt_len, offset);
557+
int ret = __pkt_stream_replace_half(test->ifobj_tx, pkt_len, offset);
558+
559+
if (ret)
560+
return ret;
561+
562+
return __pkt_stream_replace_half(test->ifobj_rx, pkt_len, offset);
544563
}
545564

546-
static void pkt_stream_receive_half(struct test_spec *test)
565+
static int pkt_stream_receive_half(struct test_spec *test)
547566
{
548567
struct pkt_stream *pkt_stream = test->ifobj_tx->xsk->pkt_stream;
549568
u32 i;
@@ -557,14 +576,19 @@ static void pkt_stream_receive_half(struct test_spec *test)
557576

558577
test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(pkt_stream->nb_pkts,
559578
pkt_stream->pkts[0].len);
579+
if (!test->ifobj_rx->xsk->pkt_stream)
580+
return -ENOMEM;
581+
560582
pkt_stream = test->ifobj_rx->xsk->pkt_stream;
561583
for (i = 1; i < pkt_stream->nb_pkts; i += 2)
562584
pkt_stream->pkts[i].valid = false;
563585

564586
pkt_stream->nb_valid_entries /= 2;
587+
588+
return 0;
565589
}
566590

567-
static void pkt_stream_even_odd_sequence(struct test_spec *test)
591+
static int pkt_stream_even_odd_sequence(struct test_spec *test)
568592
{
569593
struct pkt_stream *pkt_stream;
570594
u32 i;
@@ -573,13 +597,19 @@ static void pkt_stream_even_odd_sequence(struct test_spec *test)
573597
pkt_stream = test->ifobj_tx->xsk_arr[i].pkt_stream;
574598
pkt_stream = __pkt_stream_generate(pkt_stream->nb_pkts / 2,
575599
pkt_stream->pkts[0].len, i, 2);
600+
if (!pkt_stream)
601+
return -ENOMEM;
576602
test->ifobj_tx->xsk_arr[i].pkt_stream = pkt_stream;
577603

578604
pkt_stream = test->ifobj_rx->xsk_arr[i].pkt_stream;
579605
pkt_stream = __pkt_stream_generate(pkt_stream->nb_pkts / 2,
580606
pkt_stream->pkts[0].len, i, 2);
607+
if (!pkt_stream)
608+
return -ENOMEM;
581609
test->ifobj_rx->xsk_arr[i].pkt_stream = pkt_stream;
582610
}
611+
612+
return 0;
583613
}
584614

585615
static void release_even_odd_sequence(struct test_spec *test)
@@ -638,7 +668,7 @@ static struct pkt_stream *__pkt_stream_generate_custom(struct ifobject *ifobj, s
638668

639669
pkt_stream = __pkt_stream_alloc(nb_frames);
640670
if (!pkt_stream)
641-
exit_with_error(ENOMEM);
671+
return NULL;
642672

643673
for (i = 0; i < nb_frames; i++) {
644674
struct pkt *pkt = &pkt_stream->pkts[pkt_nb];
@@ -681,15 +711,21 @@ static struct pkt_stream *__pkt_stream_generate_custom(struct ifobject *ifobj, s
681711
return pkt_stream;
682712
}
683713

684-
static void pkt_stream_generate_custom(struct test_spec *test, struct pkt *pkts, u32 nb_pkts)
714+
static int pkt_stream_generate_custom(struct test_spec *test, struct pkt *pkts, u32 nb_pkts)
685715
{
686716
struct pkt_stream *pkt_stream;
687717

688718
pkt_stream = __pkt_stream_generate_custom(test->ifobj_tx, pkts, nb_pkts, true);
719+
if (!pkt_stream)
720+
return -ENOMEM;
689721
test->ifobj_tx->xsk->pkt_stream = pkt_stream;
690722

691723
pkt_stream = __pkt_stream_generate_custom(test->ifobj_rx, pkts, nb_pkts, false);
724+
if (!pkt_stream)
725+
return -ENOMEM;
692726
test->ifobj_rx->xsk->pkt_stream = pkt_stream;
727+
728+
return 0;
693729
}
694730

695731
static void pkt_print_data(u32 *data, u32 cnt)
@@ -1951,24 +1987,28 @@ int testapp_stats_rx_dropped(struct test_spec *test)
19511987
return TEST_SKIP;
19521988
}
19531989

1954-
pkt_stream_replace_half(test, MIN_PKT_SIZE * 4, 0);
1990+
if (pkt_stream_replace_half(test, MIN_PKT_SIZE * 4, 0))
1991+
return TEST_FAILURE;
19551992
test->ifobj_rx->umem->frame_headroom = test->ifobj_rx->umem->frame_size -
19561993
XDP_PACKET_HEADROOM - MIN_PKT_SIZE * 3;
1957-
pkt_stream_receive_half(test);
1994+
if (pkt_stream_receive_half(test))
1995+
return TEST_FAILURE;
19581996
test->ifobj_rx->validation_func = validate_rx_dropped;
19591997
return testapp_validate_traffic(test);
19601998
}
19611999

19622000
int testapp_stats_tx_invalid_descs(struct test_spec *test)
19632001
{
1964-
pkt_stream_replace_half(test, XSK_UMEM__INVALID_FRAME_SIZE, 0);
2002+
if (pkt_stream_replace_half(test, XSK_UMEM__INVALID_FRAME_SIZE, 0))
2003+
return TEST_FAILURE;
19652004
test->ifobj_tx->validation_func = validate_tx_invalid_descs;
19662005
return testapp_validate_traffic(test);
19672006
}
19682007

19692008
int testapp_stats_rx_full(struct test_spec *test)
19702009
{
1971-
pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
2010+
if (pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE))
2011+
return TEST_FAILURE;
19722012
pkt_stream_delete(test->ifobj_rx->xsk->pkt_stream);
19732013
test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
19742014

@@ -1980,7 +2020,8 @@ int testapp_stats_rx_full(struct test_spec *test)
19802020

19812021
int testapp_stats_fill_empty(struct test_spec *test)
19822022
{
1983-
pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
2023+
if (pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE))
2024+
return TEST_FAILURE;
19842025
pkt_stream_delete(test->ifobj_rx->xsk->pkt_stream);
19852026
test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
19862027

@@ -1994,7 +2035,8 @@ int testapp_send_receive_unaligned(struct test_spec *test)
19942035
test->ifobj_tx->umem->unaligned_mode = true;
19952036
test->ifobj_rx->umem->unaligned_mode = true;
19962037
/* Let half of the packets straddle a 4K buffer boundary */
1997-
pkt_stream_replace_half(test, MIN_PKT_SIZE, -MIN_PKT_SIZE / 2);
2038+
if (pkt_stream_replace_half(test, MIN_PKT_SIZE, -MIN_PKT_SIZE / 2))
2039+
return TEST_FAILURE;
19982040

19992041
return testapp_validate_traffic(test);
20002042
}
@@ -2004,22 +2046,25 @@ int testapp_send_receive_unaligned_mb(struct test_spec *test)
20042046
test->mtu = MAX_ETH_JUMBO_SIZE;
20052047
test->ifobj_tx->umem->unaligned_mode = true;
20062048
test->ifobj_rx->umem->unaligned_mode = true;
2007-
pkt_stream_replace(test, DEFAULT_PKT_CNT, MAX_ETH_JUMBO_SIZE);
2049+
if (pkt_stream_replace(test, DEFAULT_PKT_CNT, MAX_ETH_JUMBO_SIZE))
2050+
return TEST_FAILURE;
20082051
return testapp_validate_traffic(test);
20092052
}
20102053

20112054
int testapp_single_pkt(struct test_spec *test)
20122055
{
20132056
struct pkt pkts[] = {{0, MIN_PKT_SIZE, 0, true}};
20142057

2015-
pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
2058+
if (pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts)))
2059+
return TEST_FAILURE;
20162060
return testapp_validate_traffic(test);
20172061
}
20182062

20192063
int testapp_send_receive_mb(struct test_spec *test)
20202064
{
20212065
test->mtu = MAX_ETH_JUMBO_SIZE;
2022-
pkt_stream_replace(test, DEFAULT_PKT_CNT, MAX_ETH_JUMBO_SIZE);
2066+
if (pkt_stream_replace(test, DEFAULT_PKT_CNT, MAX_ETH_JUMBO_SIZE))
2067+
return TEST_FAILURE;
20232068

20242069
return testapp_validate_traffic(test);
20252070
}
@@ -2060,7 +2105,8 @@ int testapp_invalid_desc_mb(struct test_spec *test)
20602105
}
20612106

20622107
test->mtu = MAX_ETH_JUMBO_SIZE;
2063-
pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
2108+
if (pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts)))
2109+
return TEST_FAILURE;
20642110
return testapp_validate_traffic(test);
20652111
}
20662112

@@ -2105,7 +2151,8 @@ int testapp_invalid_desc(struct test_spec *test)
21052151
pkts[6].offset += umem_size;
21062152
}
21072153

2108-
pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
2154+
if (pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts)))
2155+
return TEST_FAILURE;
21092156
return testapp_validate_traffic(test);
21102157
}
21112158

@@ -2117,7 +2164,8 @@ int testapp_xdp_drop(struct test_spec *test)
21172164
test_spec_set_xdp_prog(test, skel_rx->progs.xsk_xdp_drop, skel_tx->progs.xsk_xdp_drop,
21182165
skel_rx->maps.xsk, skel_tx->maps.xsk);
21192166

2120-
pkt_stream_receive_half(test);
2167+
if (pkt_stream_receive_half(test))
2168+
return TEST_FAILURE;
21212169
return testapp_validate_traffic(test);
21222170
}
21232171

@@ -2149,7 +2197,8 @@ int testapp_xdp_shared_umem(struct test_spec *test)
21492197
skel_tx->progs.xsk_xdp_shared_umem,
21502198
skel_rx->maps.xsk, skel_tx->maps.xsk);
21512199

2152-
pkt_stream_even_odd_sequence(test);
2200+
if (pkt_stream_even_odd_sequence(test))
2201+
return TEST_FAILURE;
21532202

21542203
ret = testapp_validate_traffic(test);
21552204

@@ -2163,7 +2212,8 @@ int testapp_poll_txq_tmout(struct test_spec *test)
21632212
test->ifobj_tx->use_poll = true;
21642213
/* create invalid frame by set umem frame_size and pkt length equal to 2048 */
21652214
test->ifobj_tx->umem->frame_size = 2048;
2166-
pkt_stream_replace(test, 2 * DEFAULT_PKT_CNT, 2048);
2215+
if (pkt_stream_replace(test, 2 * DEFAULT_PKT_CNT, 2048))
2216+
return TEST_FAILURE;
21672217
return testapp_validate_traffic_single_thread(test, test->ifobj_tx);
21682218
}
21692219

@@ -2177,7 +2227,7 @@ int testapp_too_many_frags(struct test_spec *test)
21772227
{
21782228
struct pkt *pkts;
21792229
u32 max_frags, i;
2180-
int ret;
2230+
int ret = TEST_FAILURE;
21812231

21822232
if (test->mode == TEST_MODE_ZC) {
21832233
max_frags = test->ifobj_tx->xdp_zc_max_segs;
@@ -2221,9 +2271,12 @@ int testapp_too_many_frags(struct test_spec *test)
22212271
pkts[2 * max_frags + 1].len = MIN_PKT_SIZE;
22222272
pkts[2 * max_frags + 1].valid = true;
22232273

2224-
pkt_stream_generate_custom(test, pkts, 2 * max_frags + 2);
2225-
ret = testapp_validate_traffic(test);
2274+
if (pkt_stream_generate_custom(test, pkts, 2 * max_frags + 2)) {
2275+
free(pkts);
2276+
return TEST_FAILURE;
2277+
}
22262278

2279+
ret = testapp_validate_traffic(test);
22272280
free(pkts);
22282281
return ret;
22292282
}
@@ -2297,7 +2350,8 @@ int testapp_send_receive_2k_frame(struct test_spec *test)
22972350
{
22982351
test->ifobj_tx->umem->frame_size = 2048;
22992352
test->ifobj_rx->umem->frame_size = 2048;
2300-
pkt_stream_replace(test, DEFAULT_PKT_CNT, MIN_PKT_SIZE);
2353+
if (pkt_stream_replace(test, DEFAULT_PKT_CNT, MIN_PKT_SIZE))
2354+
return TEST_FAILURE;
23012355
return testapp_validate_traffic(test);
23022356
}
23032357

@@ -2419,7 +2473,13 @@ int testapp_hw_sw_max_ring_size(struct test_spec *test)
24192473
*/
24202474
test->ifobj_tx->xsk->batch_size = test->ifobj_tx->ring.tx_max_pending - 8;
24212475
test->ifobj_rx->xsk->batch_size = test->ifobj_tx->ring.tx_max_pending - 8;
2422-
pkt_stream_replace(test, max_descs, MIN_PKT_SIZE);
2476+
if (pkt_stream_replace(test, max_descs, MIN_PKT_SIZE)) {
2477+
clean_sockets(test, test->ifobj_tx);
2478+
clean_sockets(test, test->ifobj_rx);
2479+
clean_umem(test, test->ifobj_rx, test->ifobj_tx);
2480+
return TEST_FAILURE;
2481+
}
2482+
24232483
return testapp_validate_traffic(test);
24242484
}
24252485

@@ -2445,8 +2505,13 @@ static int testapp_adjust_tail(struct test_spec *test, u32 value, u32 pkt_len)
24452505
test->adjust_tail = true;
24462506
test->total_steps = 1;
24472507

2448-
pkt_stream_replace_ifobject(test->ifobj_tx, DEFAULT_BATCH_SIZE, pkt_len);
2449-
pkt_stream_replace_ifobject(test->ifobj_rx, DEFAULT_BATCH_SIZE, pkt_len + value);
2508+
ret = pkt_stream_replace_ifobject(test->ifobj_tx, DEFAULT_BATCH_SIZE, pkt_len);
2509+
if (ret)
2510+
return TEST_FAILURE;
2511+
2512+
ret = pkt_stream_replace_ifobject(test->ifobj_rx, DEFAULT_BATCH_SIZE, pkt_len + value);
2513+
if (ret)
2514+
return TEST_FAILURE;
24502515

24512516
ret = testapp_xdp_adjust_tail(test, value);
24522517
if (ret)
@@ -2498,7 +2563,8 @@ int testapp_tx_queue_consumer(struct test_spec *test)
24982563
}
24992564

25002565
nr_packets = MAX_TX_BUDGET_DEFAULT + 1;
2501-
pkt_stream_replace(test, nr_packets, MIN_PKT_SIZE);
2566+
if (pkt_stream_replace(test, nr_packets, MIN_PKT_SIZE))
2567+
return TEST_FAILURE;
25022568
test->ifobj_tx->xsk->batch_size = nr_packets;
25032569
test->ifobj_tx->xsk->check_consumer = true;
25042570

0 commit comments

Comments
 (0)