Skip to content

Commit 9b1d9e0

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(). Reviewed-by: Maciej Fijalkowski <[email protected]> Signed-off-by: Bastien Curutchet (eBPF Foundation) <[email protected]>
1 parent 77f1525 commit 9b1d9e0

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
@@ -132,24 +132,26 @@ static void umem_reset_alloc(struct xsk_umem_info *umem)
132132
umem->next_buffer = 0;
133133
}
134134

135-
static void enable_busy_poll(struct xsk_socket_info *xsk)
135+
static int enable_busy_poll(struct xsk_socket_info *xsk)
136136
{
137137
int sock_opt;
138138

139139
sock_opt = 1;
140140
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_PREFER_BUSY_POLL,
141141
(void *)&sock_opt, sizeof(sock_opt)) < 0)
142-
exit_with_error(errno);
142+
return -errno;
143143

144144
sock_opt = 20;
145145
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_BUSY_POLL,
146146
(void *)&sock_opt, sizeof(sock_opt)) < 0)
147-
exit_with_error(errno);
147+
return -errno;
148148

149149
sock_opt = xsk->batch_size;
150150
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_BUSY_POLL_BUDGET,
151151
(void *)&sock_opt, sizeof(sock_opt)) < 0)
152-
exit_with_error(errno);
152+
return -errno;
153+
154+
return 0;
153155
}
154156

155157
int xsk_configure_socket(struct xsk_socket_info *xsk, struct xsk_umem_info *umem,
@@ -759,7 +761,7 @@ static bool is_metadata_correct(struct pkt *pkt, void *buffer, u64 addr)
759761
return true;
760762
}
761763

762-
static bool is_adjust_tail_supported(struct xsk_xdp_progs *skel_rx)
764+
static int is_adjust_tail_supported(struct xsk_xdp_progs *skel_rx, bool *supported)
763765
{
764766
struct bpf_map *data_map;
765767
int adjust_value = 0;
@@ -769,19 +771,21 @@ static bool is_adjust_tail_supported(struct xsk_xdp_progs *skel_rx)
769771
data_map = bpf_object__find_map_by_name(skel_rx->obj, "xsk_xdp_.bss");
770772
if (!data_map || !bpf_map__is_internal(data_map)) {
771773
ksft_print_msg("Error: could not find bss section of XDP program\n");
772-
exit_with_error(errno);
774+
return -EINVAL;
773775
}
774776

775777
ret = bpf_map_lookup_elem(bpf_map__fd(data_map), &key, &adjust_value);
776778
if (ret) {
777779
ksft_print_msg("Error: bpf_map_lookup_elem failed with error %d\n", ret);
778-
exit_with_error(errno);
780+
return ret;
779781
}
780782

781783
/* Set the 'adjust_value' variable to -EOPNOTSUPP in the XDP program if the adjust_tail
782784
* helper is not supported. Skip the adjust_tail test case in this scenario.
783785
*/
784-
return adjust_value != -EOPNOTSUPP;
786+
*supported = adjust_value != -EOPNOTSUPP;
787+
788+
return 0;
785789
}
786790

787791
static bool is_frag_valid(struct xsk_umem_info *umem, u64 addr, u32 len, u32 expected_pkt_nb,
@@ -1433,7 +1437,7 @@ static int validate_tx_invalid_descs(struct ifobject *ifobject)
14331437
return TEST_PASS;
14341438
}
14351439

1436-
static void xsk_configure(struct test_spec *test, struct ifobject *ifobject,
1440+
static int xsk_configure(struct test_spec *test, struct ifobject *ifobject,
14371441
struct xsk_umem_info *umem, bool tx)
14381442
{
14391443
int i, ret;
@@ -1450,24 +1454,34 @@ static void xsk_configure(struct test_spec *test, struct ifobject *ifobject,
14501454

14511455
/* Retry if it fails as xsk_socket__create() is asynchronous */
14521456
if (ctr >= SOCK_RECONF_CTR)
1453-
exit_with_error(-ret);
1457+
return ret;
14541458
usleep(USLEEP_MAX);
14551459
}
1456-
if (ifobject->busy_poll)
1457-
enable_busy_poll(&ifobject->xsk_arr[i]);
1460+
if (ifobject->busy_poll) {
1461+
ret = enable_busy_poll(&ifobject->xsk_arr[i]);
1462+
if (ret)
1463+
return ret;
1464+
}
14581465
}
1466+
1467+
return 0;
14591468
}
14601469

1461-
static void thread_common_ops_tx(struct test_spec *test, struct ifobject *ifobject)
1470+
static int thread_common_ops_tx(struct test_spec *test, struct ifobject *ifobject)
14621471
{
1463-
xsk_configure(test, ifobject, test->ifobj_rx->umem, true);
1472+
int ret = xsk_configure(test, ifobject, test->ifobj_rx->umem, true);
1473+
1474+
if (ret)
1475+
return ret;
14641476
ifobject->xsk = &ifobject->xsk_arr[0];
14651477
ifobject->xskmap = test->ifobj_rx->xskmap;
14661478
memcpy(ifobject->umem, test->ifobj_rx->umem, sizeof(struct xsk_umem_info));
14671479
ifobject->umem->base_addr = 0;
1480+
1481+
return 0;
14681482
}
14691483

1470-
static void xsk_populate_fill_ring(struct xsk_umem_info *umem, struct pkt_stream *pkt_stream,
1484+
static int xsk_populate_fill_ring(struct xsk_umem_info *umem, struct pkt_stream *pkt_stream,
14711485
bool fill_up)
14721486
{
14731487
u32 rx_frame_size = umem->frame_size - XDP_PACKET_HEADROOM;
@@ -1481,7 +1495,7 @@ static void xsk_populate_fill_ring(struct xsk_umem_info *umem, struct pkt_stream
14811495

14821496
ret = xsk_ring_prod__reserve(&umem->fq, buffers_to_fill, &idx);
14831497
if (ret != buffers_to_fill)
1484-
exit_with_error(ENOSPC);
1498+
return -ENOSPC;
14851499

14861500
while (filled < buffers_to_fill) {
14871501
struct pkt *pkt = pkt_stream_get_next_rx_pkt(pkt_stream, &nb_pkts);
@@ -1509,9 +1523,11 @@ static void xsk_populate_fill_ring(struct xsk_umem_info *umem, struct pkt_stream
15091523

15101524
pkt_stream_reset(pkt_stream);
15111525
umem_reset_alloc(umem);
1526+
1527+
return 0;
15121528
}
15131529

1514-
static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
1530+
static int thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
15151531
{
15161532
LIBBPF_OPTS(bpf_xdp_query_opts, opts);
15171533
int mmap_flags;
@@ -1531,27 +1547,34 @@ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
15311547

15321548
bufs = mmap(NULL, umem_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
15331549
if (bufs == MAP_FAILED)
1534-
exit_with_error(errno);
1550+
return -errno;
15351551

15361552
ret = xsk_configure_umem(ifobject, ifobject->umem, bufs, umem_sz);
15371553
if (ret)
1538-
exit_with_error(-ret);
1554+
return ret;
15391555

1540-
xsk_configure(test, ifobject, ifobject->umem, false);
1556+
ret = xsk_configure(test, ifobject, ifobject->umem, false);
1557+
if (ret)
1558+
return ret;
15411559

15421560
ifobject->xsk = &ifobject->xsk_arr[0];
15431561

15441562
if (!ifobject->rx_on)
1545-
return;
1563+
return 0;
15461564

1547-
xsk_populate_fill_ring(ifobject->umem, ifobject->xsk->pkt_stream, ifobject->use_fill_ring);
1565+
ret = xsk_populate_fill_ring(ifobject->umem, ifobject->xsk->pkt_stream,
1566+
ifobject->use_fill_ring);
1567+
if (ret)
1568+
return ret;
15481569

15491570
for (i = 0; i < test->nb_sockets; i++) {
15501571
ifobject->xsk = &ifobject->xsk_arr[i];
15511572
ret = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk->xsk, i);
15521573
if (ret)
1553-
exit_with_error(errno);
1574+
return ret;
15541575
}
1576+
1577+
return 0;
15551578
}
15561579

15571580
void *worker_testapp_validate_tx(void *arg)
@@ -1561,10 +1584,17 @@ void *worker_testapp_validate_tx(void *arg)
15611584
int err;
15621585

15631586
if (test->current_step == 1) {
1564-
if (!ifobject->shared_umem)
1565-
thread_common_ops(test, ifobject);
1566-
else
1567-
thread_common_ops_tx(test, ifobject);
1587+
if (!ifobject->shared_umem) {
1588+
if (thread_common_ops(test, ifobject)) {
1589+
test->fail = true;
1590+
pthread_exit(NULL);
1591+
}
1592+
} else {
1593+
if (thread_common_ops_tx(test, ifobject)) {
1594+
test->fail = true;
1595+
pthread_exit(NULL);
1596+
}
1597+
}
15681598
}
15691599

15701600
err = send_pkts(test, ifobject);
@@ -1584,29 +1614,41 @@ void *worker_testapp_validate_rx(void *arg)
15841614
int err;
15851615

15861616
if (test->current_step == 1) {
1587-
thread_common_ops(test, ifobject);
1617+
err = thread_common_ops(test, ifobject);
15881618
} else {
15891619
xsk_clear_xskmap(ifobject->xskmap);
15901620
err = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk->xsk, 0);
1591-
if (err) {
1621+
if (err)
15921622
ksft_print_msg("Error: Failed to update xskmap, error %s\n",
15931623
strerror(-err));
1594-
exit_with_error(-err);
1595-
}
15961624
}
15971625

15981626
pthread_barrier_wait(&barr);
15991627

1628+
/* We leave only now in case of error to avoid getting stuck in the barrier */
1629+
if (err) {
1630+
test->fail = true;
1631+
pthread_exit(NULL);
1632+
}
1633+
16001634
err = receive_pkts(test);
16011635

16021636
if (!err && ifobject->validation_func)
16031637
err = ifobject->validation_func(ifobject);
16041638

16051639
if (err) {
1606-
if (test->adjust_tail && !is_adjust_tail_supported(ifobject->xdp_progs))
1607-
test->adjust_tail_support = false;
1608-
else
1640+
if (!test->adjust_tail) {
16091641
test->fail = true;
1642+
} else {
1643+
bool supported;
1644+
1645+
if (is_adjust_tail_supported(ifobject->xdp_progs, &supported))
1646+
test->fail = true;
1647+
if (!supported)
1648+
test->adjust_tail_support = false;
1649+
else
1650+
test->fail = true;
1651+
}
16101652
}
16111653

16121654
pthread_exit(NULL);

0 commit comments

Comments
 (0)