pkt_stream_even_odd_sequence() replaces each socket stream as it is generated. If a later allocation fails, the earlier replacement streams are already published in xsk_arr while the original streams for those slots are lost. Both testapp_xdp_shared_umem() and run_shared_umem_test() return immediately on that error, without calling release_even_odd_sequence(). This leaks the already-published replacement streams and leaves the socket arrays with a partially replaced stream set. Generate all TX and RX streams in temporary arrays and publish them only after every allocation succeeds. On failure, free the temporary streams and leave xsk_arr unchanged. Signed-off-by: Magnus Karlsson Signed-off-by: Tushar Vyavahare --- .../selftests/bpf/prog_tests/test_xsk.c | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c index 54143fc757e1..ae6a091b6485 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c +++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c @@ -602,26 +602,41 @@ static int pkt_stream_receive_half(struct test_spec *test) static int pkt_stream_even_odd_sequence(struct test_spec *test) { + struct pkt_stream *tx_streams[MAX_SOCKETS] = {}; + struct pkt_stream *rx_streams[MAX_SOCKETS] = {}; struct pkt_stream *pkt_stream; u32 i; for (i = 0; i < test->nb_sockets; i++) { pkt_stream = test->ifobj_tx->xsk_arr[i].pkt_stream; - pkt_stream = __pkt_stream_generate(pkt_stream->nb_pkts / 2, - pkt_stream->pkts[0].len, i, 2); - if (!pkt_stream) - return -ENOMEM; - test->ifobj_tx->xsk_arr[i].pkt_stream = pkt_stream; + tx_streams[i] = __pkt_stream_generate(pkt_stream->nb_pkts / 2, + pkt_stream->pkts[0].len, i, 2); + if (!tx_streams[i]) + goto err; pkt_stream = test->ifobj_rx->xsk_arr[i].pkt_stream; - pkt_stream = __pkt_stream_generate(pkt_stream->nb_pkts / 2, - pkt_stream->pkts[0].len, i, 2); - if (!pkt_stream) - return -ENOMEM; - test->ifobj_rx->xsk_arr[i].pkt_stream = pkt_stream; + rx_streams[i] = __pkt_stream_generate(pkt_stream->nb_pkts / 2, + pkt_stream->pkts[0].len, i, 2); + if (!rx_streams[i]) + goto err; + } + + for (i = 0; i < test->nb_sockets; i++) { + test->ifobj_tx->xsk_arr[i].pkt_stream = tx_streams[i]; + test->ifobj_rx->xsk_arr[i].pkt_stream = rx_streams[i]; } return 0; + +err: + for (i = 0; i < test->nb_sockets; i++) { + if (tx_streams[i]) + pkt_stream_delete(tx_streams[i]); + if (rx_streams[i]) + pkt_stream_delete(rx_streams[i]); + } + + return -ENOMEM; } static int pkt_stream_len_seq(struct test_spec *test, u32 short_len, u32 long_len) -- 2.43.0