Commit 776021e0 authored by Tushar Vyavahare's avatar Tushar Vyavahare Committed by Daniel Borkmann

selftests/xsk: Introduce set_ring_size function with a retry mechanism for...

selftests/xsk: Introduce set_ring_size function with a retry mechanism for handling AF_XDP socket closures

Introduce a new function, set_ring_size(), to manage asynchronous AF_XDP
socket closure. Retry set_hw_ring_size up to SOCK_RECONF_CTR times if it
fails due to an active AF_XDP socket. Return an error immediately for
non-EBUSY errors. This enhances robustness against asynchronous AF_XDP
socket closures during ring size changes.
Signed-off-by: default avatarTushar Vyavahare <tushar.vyavahare@intel.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarMagnus Karlsson <magnus.karlsson@intel.com>
Link: https://lore.kernel.org/bpf/20240402114529.545475-6-tushar.vyavahare@intel.com
parent bee3a7b0
...@@ -695,7 +695,7 @@ $(OUTPUT)/test_verifier: test_verifier.c verifier/tests.h $(BPFOBJ) | $(OUTPUT) ...@@ -695,7 +695,7 @@ $(OUTPUT)/test_verifier: test_verifier.c verifier/tests.h $(BPFOBJ) | $(OUTPUT)
# Include find_bit.c to compile xskxceiver. # Include find_bit.c to compile xskxceiver.
EXTRA_SRC := $(TOOLSDIR)/lib/find_bit.c EXTRA_SRC := $(TOOLSDIR)/lib/find_bit.c
$(OUTPUT)/xskxceiver: $(EXTRA_SRC) xskxceiver.c xskxceiver.h $(OUTPUT)/xsk.o $(OUTPUT)/xsk_xdp_progs.skel.h $(BPFOBJ) | $(OUTPUT) $(OUTPUT)/xskxceiver: $(EXTRA_SRC) xskxceiver.c xskxceiver.h $(OUTPUT)/network_helpers.o $(OUTPUT)/xsk.o $(OUTPUT)/xsk_xdp_progs.skel.h $(BPFOBJ) | $(OUTPUT)
$(call msg,BINARY,,$@) $(call msg,BINARY,,$@)
$(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@ $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
#include <linux/mman.h> #include <linux/mman.h>
#include <linux/netdev.h> #include <linux/netdev.h>
#include <linux/bitmap.h> #include <linux/bitmap.h>
#include <linux/ethtool.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <net/if.h> #include <net/if.h>
#include <locale.h> #include <locale.h>
...@@ -105,11 +106,15 @@ ...@@ -105,11 +106,15 @@
#include "../kselftest.h" #include "../kselftest.h"
#include "xsk_xdp_common.h" #include "xsk_xdp_common.h"
#include <network_helpers.h>
static bool opt_verbose; static bool opt_verbose;
static bool opt_print_tests; static bool opt_print_tests;
static enum test_mode opt_mode = TEST_MODE_ALL; static enum test_mode opt_mode = TEST_MODE_ALL;
static u32 opt_run_test = RUN_ALL_TESTS; static u32 opt_run_test = RUN_ALL_TESTS;
void test__fail(void) { /* for network_helpers.c */ }
static void __exit_with_error(int error, const char *file, const char *func, int line) static void __exit_with_error(int error, const char *file, const char *func, int line)
{ {
ksft_test_result_fail("[%s:%s:%i]: ERROR: %d/\"%s\"\n", file, func, line, error, ksft_test_result_fail("[%s:%s:%i]: ERROR: %d/\"%s\"\n", file, func, line, error,
...@@ -409,6 +414,33 @@ static void parse_command_line(struct ifobject *ifobj_tx, struct ifobject *ifobj ...@@ -409,6 +414,33 @@ static void parse_command_line(struct ifobject *ifobj_tx, struct ifobject *ifobj
} }
} }
static int set_ring_size(struct ifobject *ifobj)
{
int ret;
u32 ctr = 0;
while (ctr++ < SOCK_RECONF_CTR) {
ret = set_hw_ring_size(ifobj->ifname, &ifobj->ring);
if (!ret)
break;
/* Retry if it fails */
if (ctr >= SOCK_RECONF_CTR || errno != EBUSY)
return -errno;
usleep(USLEEP_MAX);
}
return ret;
}
static int hw_ring_size_reset(struct ifobject *ifobj)
{
ifobj->ring.tx_pending = ifobj->set_ring.default_tx;
ifobj->ring.rx_pending = ifobj->set_ring.default_rx;
return set_ring_size(ifobj);
}
static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx, static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
struct ifobject *ifobj_rx) struct ifobject *ifobj_rx)
{ {
...@@ -452,12 +484,16 @@ static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx, ...@@ -452,12 +484,16 @@ static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
} }
} }
if (ifobj_tx->hw_ring_size_supp)
hw_ring_size_reset(ifobj_tx);
test->ifobj_tx = ifobj_tx; test->ifobj_tx = ifobj_tx;
test->ifobj_rx = ifobj_rx; test->ifobj_rx = ifobj_rx;
test->current_step = 0; test->current_step = 0;
test->total_steps = 1; test->total_steps = 1;
test->nb_sockets = 1; test->nb_sockets = 1;
test->fail = false; test->fail = false;
test->set_ring = false;
test->mtu = MAX_ETH_PKT_SIZE; test->mtu = MAX_ETH_PKT_SIZE;
test->xdp_prog_rx = ifobj_rx->xdp_progs->progs.xsk_def_prog; test->xdp_prog_rx = ifobj_rx->xdp_progs->progs.xsk_def_prog;
test->xskmap_rx = ifobj_rx->xdp_progs->maps.xsk; test->xskmap_rx = ifobj_rx->xdp_progs->maps.xsk;
...@@ -1862,6 +1898,14 @@ static int testapp_validate_traffic(struct test_spec *test) ...@@ -1862,6 +1898,14 @@ static int testapp_validate_traffic(struct test_spec *test)
return TEST_SKIP; return TEST_SKIP;
} }
if (test->set_ring) {
if (ifobj_tx->hw_ring_size_supp)
return set_ring_size(ifobj_tx);
ksft_test_result_skip("Changing HW ring size not supported.\n");
return TEST_SKIP;
}
xsk_attach_xdp_progs(test, ifobj_rx, ifobj_tx); xsk_attach_xdp_progs(test, ifobj_rx, ifobj_tx);
return __testapp_validate_traffic(test, ifobj_rx, ifobj_tx); return __testapp_validate_traffic(test, ifobj_rx, ifobj_tx);
} }
...@@ -2479,7 +2523,7 @@ static const struct test_spec tests[] = { ...@@ -2479,7 +2523,7 @@ static const struct test_spec tests[] = {
{.name = "ALIGNED_INV_DESC_MULTI_BUFF", .test_func = testapp_aligned_inv_desc_mb}, {.name = "ALIGNED_INV_DESC_MULTI_BUFF", .test_func = testapp_aligned_inv_desc_mb},
{.name = "UNALIGNED_INV_DESC_MULTI_BUFF", .test_func = testapp_unaligned_inv_desc_mb}, {.name = "UNALIGNED_INV_DESC_MULTI_BUFF", .test_func = testapp_unaligned_inv_desc_mb},
{.name = "TOO_MANY_FRAGS", .test_func = testapp_too_many_frags}, {.name = "TOO_MANY_FRAGS", .test_func = testapp_too_many_frags},
}; };
static void print_tests(void) static void print_tests(void)
{ {
...@@ -2499,6 +2543,7 @@ int main(int argc, char **argv) ...@@ -2499,6 +2543,7 @@ int main(int argc, char **argv)
int modes = TEST_MODE_SKB + 1; int modes = TEST_MODE_SKB + 1;
struct test_spec test; struct test_spec test;
bool shared_netdev; bool shared_netdev;
int ret;
/* Use libbpf 1.0 API mode */ /* Use libbpf 1.0 API mode */
libbpf_set_strict_mode(LIBBPF_STRICT_ALL); libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
...@@ -2536,6 +2581,13 @@ int main(int argc, char **argv) ...@@ -2536,6 +2581,13 @@ int main(int argc, char **argv)
modes++; modes++;
} }
ret = get_hw_ring_size(ifobj_tx->ifname, &ifobj_tx->ring);
if (!ret) {
ifobj_tx->hw_ring_size_supp = true;
ifobj_tx->set_ring.default_tx = ifobj_tx->ring.tx_pending;
ifobj_tx->set_ring.default_rx = ifobj_tx->ring.rx_pending;
}
init_iface(ifobj_rx, worker_testapp_validate_rx); init_iface(ifobj_rx, worker_testapp_validate_rx);
init_iface(ifobj_tx, worker_testapp_validate_tx); init_iface(ifobj_tx, worker_testapp_validate_tx);
...@@ -2583,6 +2635,9 @@ int main(int argc, char **argv) ...@@ -2583,6 +2635,9 @@ int main(int argc, char **argv)
} }
} }
if (ifobj_tx->hw_ring_size_supp)
hw_ring_size_reset(ifobj_tx);
pkt_stream_delete(tx_pkt_stream_default); pkt_stream_delete(tx_pkt_stream_default);
pkt_stream_delete(rx_pkt_stream_default); pkt_stream_delete(rx_pkt_stream_default);
xsk_unload_xdp_programs(ifobj_tx); xsk_unload_xdp_programs(ifobj_tx);
......
...@@ -114,6 +114,11 @@ struct pkt_stream { ...@@ -114,6 +114,11 @@ struct pkt_stream {
bool verbatim; bool verbatim;
}; };
struct set_hw_ring {
u32 default_tx;
u32 default_rx;
};
struct ifobject; struct ifobject;
struct test_spec; struct test_spec;
typedef int (*validation_func_t)(struct ifobject *ifobj); typedef int (*validation_func_t)(struct ifobject *ifobj);
...@@ -130,6 +135,8 @@ struct ifobject { ...@@ -130,6 +135,8 @@ struct ifobject {
struct xsk_xdp_progs *xdp_progs; struct xsk_xdp_progs *xdp_progs;
struct bpf_map *xskmap; struct bpf_map *xskmap;
struct bpf_program *xdp_prog; struct bpf_program *xdp_prog;
struct ethtool_ringparam ring;
struct set_hw_ring set_ring;
enum test_mode mode; enum test_mode mode;
int ifindex; int ifindex;
int mtu; int mtu;
...@@ -146,6 +153,7 @@ struct ifobject { ...@@ -146,6 +153,7 @@ struct ifobject {
bool unaligned_supp; bool unaligned_supp;
bool multi_buff_supp; bool multi_buff_supp;
bool multi_buff_zc_supp; bool multi_buff_zc_supp;
bool hw_ring_size_supp;
}; };
struct test_spec { struct test_spec {
...@@ -163,6 +171,7 @@ struct test_spec { ...@@ -163,6 +171,7 @@ struct test_spec {
u16 current_step; u16 current_step;
u16 nb_sockets; u16 nb_sockets;
bool fail; bool fail;
bool set_ring;
enum test_mode mode; enum test_mode mode;
char name[MAX_TEST_NAME_SIZE]; char name[MAX_TEST_NAME_SIZE];
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment