Skip to content

Commit 08398c7

Browse files
bastien-curutchetKernel Patches Daemon
authored andcommitted
selftests/bpf: test_xsk: Don't exit immediately when workers fail
TX and RX workers can fail in many places. These failures trigger a call to exit_with_error() which exits the program immediately. It prevents the following tests from running and isn't compliant with the CI. Add return value to functions that can fail. Handle failures more smoothly through report_failure(). Signed-off-by: Bastien Curutchet (eBPF Foundation) <[email protected]>
1 parent 960adf3 commit 08398c7

File tree

1 file changed

+76
-34
lines changed

1 file changed

+76
-34
lines changed

tools/testing/selftests/bpf/test_xsk.c

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -142,24 +142,26 @@ static void umem_reset_alloc(struct xsk_umem_info *umem)
142142
umem->next_buffer = 0;
143143
}
144144

145-
static void enable_busy_poll(struct xsk_socket_info *xsk)
145+
static int enable_busy_poll(struct xsk_socket_info *xsk)
146146
{
147147
int sock_opt;
148148

149149
sock_opt = 1;
150150
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_PREFER_BUSY_POLL,
151151
(void *)&sock_opt, sizeof(sock_opt)) < 0)
152-
exit_with_error(errno);
152+
return -errno;
153153

154154
sock_opt = 20;
155155
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_BUSY_POLL,
156156
(void *)&sock_opt, sizeof(sock_opt)) < 0)
157-
exit_with_error(errno);
157+
return -errno;
158158

159159
sock_opt = xsk->batch_size;
160160
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_BUSY_POLL_BUDGET,
161161
(void *)&sock_opt, sizeof(sock_opt)) < 0)
162-
exit_with_error(errno);
162+
return -errno;
163+
164+
return 0;
163165
}
164166

165167
int xsk_configure_socket(struct xsk_socket_info *xsk, struct xsk_umem_info *umem,
@@ -769,7 +771,7 @@ static bool is_metadata_correct(struct pkt *pkt, void *buffer, u64 addr)
769771
return true;
770772
}
771773

772-
static bool is_adjust_tail_supported(struct xsk_xdp_progs *skel_rx)
774+
static int is_adjust_tail_supported(struct xsk_xdp_progs *skel_rx, bool *supported)
773775
{
774776
struct bpf_map *data_map;
775777
int adjust_value = 0;
@@ -779,19 +781,21 @@ static bool is_adjust_tail_supported(struct xsk_xdp_progs *skel_rx)
779781
data_map = bpf_object__find_map_by_name(skel_rx->obj, "xsk_xdp_.bss");
780782
if (!data_map || !bpf_map__is_internal(data_map)) {
781783
ksft_print_msg("Error: could not find bss section of XDP program\n");
782-
exit_with_error(errno);
784+
return -EINVAL;
783785
}
784786

785787
ret = bpf_map_lookup_elem(bpf_map__fd(data_map), &key, &adjust_value);
786788
if (ret) {
787789
ksft_print_msg("Error: bpf_map_lookup_elem failed with error %d\n", ret);
788-
exit_with_error(errno);
790+
return ret;
789791
}
790792

791793
/* Set the 'adjust_value' variable to -EOPNOTSUPP in the XDP program if the adjust_tail
792794
* helper is not supported. Skip the adjust_tail test case in this scenario.
793795
*/
794-
return adjust_value != -EOPNOTSUPP;
796+
*supported = adjust_value != -EOPNOTSUPP;
797+
798+
return 0;
795799
}
796800

797801
static bool is_frag_valid(struct xsk_umem_info *umem, u64 addr, u32 len, u32 expected_pkt_nb,
@@ -1443,7 +1447,7 @@ static int validate_tx_invalid_descs(struct ifobject *ifobject)
14431447
return TEST_PASS;
14441448
}
14451449

1446-
static void xsk_configure(struct test_spec *test, struct ifobject *ifobject,
1450+
static int xsk_configure(struct test_spec *test, struct ifobject *ifobject,
14471451
struct xsk_umem_info *umem, bool tx)
14481452
{
14491453
int i, ret;
@@ -1460,24 +1464,34 @@ static void xsk_configure(struct test_spec *test, struct ifobject *ifobject,
14601464

14611465
/* Retry if it fails as xsk_socket__create() is asynchronous */
14621466
if (ctr >= SOCK_RECONF_CTR)
1463-
exit_with_error(-ret);
1467+
return ret;
14641468
usleep(USLEEP_MAX);
14651469
}
1466-
if (ifobject->busy_poll)
1467-
enable_busy_poll(&ifobject->xsk_arr[i]);
1470+
if (ifobject->busy_poll) {
1471+
ret = enable_busy_poll(&ifobject->xsk_arr[i]);
1472+
if (ret)
1473+
return ret;
1474+
}
14681475
}
1476+
1477+
return 0;
14691478
}
14701479

1471-
static void thread_common_ops_tx(struct test_spec *test, struct ifobject *ifobject)
1480+
static int thread_common_ops_tx(struct test_spec *test, struct ifobject *ifobject)
14721481
{
1473-
xsk_configure(test, ifobject, test->ifobj_rx->umem, true);
1482+
int ret = xsk_configure(test, ifobject, test->ifobj_rx->umem, true);
1483+
1484+
if (ret)
1485+
return ret;
14741486
ifobject->xsk = &ifobject->xsk_arr[0];
14751487
ifobject->xskmap = test->ifobj_rx->xskmap;
14761488
memcpy(ifobject->umem, test->ifobj_rx->umem, sizeof(struct xsk_umem_info));
14771489
ifobject->umem->base_addr = 0;
1490+
1491+
return 0;
14781492
}
14791493

1480-
static void xsk_populate_fill_ring(struct xsk_umem_info *umem, struct pkt_stream *pkt_stream,
1494+
static int xsk_populate_fill_ring(struct xsk_umem_info *umem, struct pkt_stream *pkt_stream,
14811495
bool fill_up)
14821496
{
14831497
u32 rx_frame_size = umem->frame_size - XDP_PACKET_HEADROOM;
@@ -1491,7 +1505,7 @@ static void xsk_populate_fill_ring(struct xsk_umem_info *umem, struct pkt_stream
14911505

14921506
ret = xsk_ring_prod__reserve(&umem->fq, buffers_to_fill, &idx);
14931507
if (ret != buffers_to_fill)
1494-
exit_with_error(ENOSPC);
1508+
return -ENOSPC;
14951509

14961510
while (filled < buffers_to_fill) {
14971511
struct pkt *pkt = pkt_stream_get_next_rx_pkt(pkt_stream, &nb_pkts);
@@ -1519,9 +1533,11 @@ static void xsk_populate_fill_ring(struct xsk_umem_info *umem, struct pkt_stream
15191533

15201534
pkt_stream_reset(pkt_stream);
15211535
umem_reset_alloc(umem);
1536+
1537+
return 0;
15221538
}
15231539

1524-
static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
1540+
static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
15251541
{
15261542
LIBBPF_OPTS(bpf_xdp_query_opts, opts);
15271543
int mmap_flags;
@@ -1541,27 +1557,34 @@ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
15411557

15421558
bufs = mmap(NULL, umem_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
15431559
if (bufs == MAP_FAILED)
1544-
exit_with_error(errno);
1560+
return -errno;
15451561

15461562
ret = xsk_configure_umem(ifobject, ifobject->umem, bufs, umem_sz);
15471563
if (ret)
1548-
exit_with_error(-ret);
1564+
return ret;
15491565

1550-
xsk_configure(test, ifobject, ifobject->umem, false);
1566+
ret = xsk_configure(test, ifobject, ifobject->umem, false);
1567+
if (ret)
1568+
return ret;
15511569

15521570
ifobject->xsk = &ifobject->xsk_arr[0];
15531571

15541572
if (!ifobject->rx_on)
1555-
return;
1573+
return 0;
15561574

1557-
xsk_populate_fill_ring(ifobject->umem, ifobject->xsk->pkt_stream, ifobject->use_fill_ring);
1575+
ret = xsk_populate_fill_ring(ifobject->umem, ifobject->xsk->pkt_stream,
1576+
ifobject->use_fill_ring);
1577+
if (ret)
1578+
return ret;
15581579

15591580
for (i = 0; i < test->nb_sockets; i++) {
15601581
ifobject->xsk = &ifobject->xsk_arr[i];
15611582
ret = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk->xsk, i);
15621583
if (ret)
1563-
exit_with_error(errno);
1584+
return ret;
15641585
}
1586+
1587+
return 0;
15651588
}
15661589

15671590
void *worker_testapp_validate_tx(void *arg)
@@ -1571,10 +1594,17 @@ void *worker_testapp_validate_tx(void *arg)
15711594
int err;
15721595

15731596
if (test->current_step == 1) {
1574-
if (!ifobject->shared_umem)
1575-
thread_common_ops(test, ifobject);
1576-
else
1577-
thread_common_ops_tx(test, ifobject);
1597+
if (!ifobject->shared_umem) {
1598+
if (thread_common_ops(test, ifobject)) {
1599+
report_failure(test);
1600+
pthread_exit(NULL);
1601+
}
1602+
} else {
1603+
if (thread_common_ops_tx(test, ifobject)) {
1604+
report_failure(test);
1605+
pthread_exit(NULL);
1606+
}
1607+
}
15781608
}
15791609

15801610
err = send_pkts(test, ifobject);
@@ -1594,29 +1624,41 @@ void *worker_testapp_validate_rx(void *arg)
15941624
int err;
15951625

15961626
if (test->current_step == 1) {
1597-
thread_common_ops(test, ifobject);
1627+
err = thread_common_ops(test, ifobject);
15981628
} else {
15991629
xsk_clear_xskmap(ifobject->xskmap);
16001630
err = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk->xsk, 0);
1601-
if (err) {
1631+
if (err)
16021632
ksft_print_msg("Error: Failed to update xskmap, error %s\n",
16031633
strerror(-err));
1604-
exit_with_error(-err);
1605-
}
16061634
}
16071635

16081636
pthread_barrier_wait(&barr);
16091637

1638+
/* We leave only now in case of error to avoid getting stuck in the barrier */
1639+
if (err) {
1640+
report_failure(test);
1641+
pthread_exit(NULL);
1642+
}
1643+
16101644
err = receive_pkts(test);
16111645

16121646
if (!err && ifobject->validation_func)
16131647
err = ifobject->validation_func(ifobject);
16141648

16151649
if (err) {
1616-
if (test->adjust_tail && !is_adjust_tail_supported(ifobject->xdp_progs))
1617-
test->adjust_tail_support = false;
1618-
else
1650+
if (!test->adjust_tail) {
16191651
report_failure(test);
1652+
} else {
1653+
bool supported;
1654+
1655+
if (is_adjust_tail_supported(ifobject->xdp_progs, &supported))
1656+
report_failure(test);
1657+
if (!supported)
1658+
test->adjust_tail_support = false;
1659+
else
1660+
report_failure(test);
1661+
}
16201662
}
16211663

16221664
pthread_exit(NULL);

0 commit comments

Comments
 (0)