Commit 9445f8c7 authored by Maciej Fijalkowski's avatar Maciej Fijalkowski Committed by Alexei Starovoitov

selftests: xsk: Refactor teardown/bidi test cases and testapp_validate

Currently, there is a testapp_sockets() that acts like a wrapper around
testapp_validate() and it is called for bidi and teardown test types.
Other test types call testapp_validate() directly.

Split testapp_sockets() onto two separate functions so a bunch of bidi
specific logic can be moved there and out of testapp_validate() itself.

Introduce function pointer to ifobject struct which will be used for
assigning the Rx/Tx function that is assigned to worker thread. Let's
also have a global ifobject Rx/Tx pointers so it's easier to swap the
vectors on a second run of a bi-directional test. Thread creation now is
easey to follow.

switching_notify variable is useless, info about vector switch can be
printed based on bidi_pass state.

Last but not least, init/destroy synchronization variables only once,
not per each test.
Signed-off-by: default avatarMaciej Fijalkowski <maciej.fijalkowski@intel.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20210329224316.17793-12-maciej.fijalkowski@intel.com
parent 99f9bcb6
......@@ -896,26 +896,10 @@ static void testapp_validate(void)
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, THREAD_STACK);
if ((test_type == TEST_TYPE_BIDI) && bidi_pass) {
pthread_init_mutex();
if (!switching_notify) {
print_verbose("Switching Tx/Rx vectors\n");
switching_notify++;
}
}
pthread_mutex_lock(&sync_mutex);
/*Spawn RX thread */
if (!bidi || !bidi_pass) {
if (pthread_create(&t0, &attr, worker_testapp_validate_rx, ifdict[1]))
exit_with_error(errno);
} else if (bidi && bidi_pass) {
/*switch Tx/Rx vectors */
ifdict[0]->fv.vector = rx;
if (pthread_create(&t0, &attr, worker_testapp_validate_rx, ifdict[0]))
exit_with_error(errno);
}
pthread_create(&t0, &attr, ifdict_rx->func_ptr, ifdict_rx);
if (clock_gettime(CLOCK_REALTIME, &max_wait))
exit_with_error(errno);
......@@ -927,15 +911,7 @@ static void testapp_validate(void)
pthread_mutex_unlock(&sync_mutex);
/*Spawn TX thread */
if (!bidi || !bidi_pass) {
if (pthread_create(&t1, &attr, worker_testapp_validate_tx, ifdict[0]))
exit_with_error(errno);
} else if (bidi && bidi_pass) {
/*switch Tx/Rx vectors */
ifdict[1]->fv.vector = tx;
if (pthread_create(&t1, &attr, worker_testapp_validate_tx, ifdict[1]))
exit_with_error(errno);
}
pthread_create(&t1, &attr, ifdict_tx->func_ptr, ifdict_tx);
pthread_join(t1, NULL);
pthread_join(t0, NULL);
......@@ -953,18 +929,53 @@ static void testapp_validate(void)
print_ksft_result();
}
static void testapp_sockets(void)
static void testapp_teardown(void)
{
int i;
for (i = 0; i < MAX_TEARDOWN_ITER; i++) {
pkt_counter = 0;
prev_pkt = -1;
sigvar = 0;
print_verbose("Creating socket\n");
testapp_validate();
}
print_ksft_result();
}
static void swap_vectors(struct ifobject *ifobj1, struct ifobject *ifobj2)
{
void *(*tmp_func_ptr)(void *) = ifobj1->func_ptr;
enum fvector tmp_vector = ifobj1->fv.vector;
ifobj1->func_ptr = ifobj2->func_ptr;
ifobj1->fv.vector = ifobj2->fv.vector;
ifobj2->func_ptr = tmp_func_ptr;
ifobj2->fv.vector = tmp_vector;
ifdict_tx = ifobj1;
ifdict_rx = ifobj2;
}
static void testapp_bidi(void)
{
for (int i = 0; i < ((test_type == TEST_TYPE_TEARDOWN) ? MAX_TEARDOWN_ITER : MAX_BIDI_ITER);
i++) {
for (int i = 0; i < MAX_BIDI_ITER; i++) {
pkt_counter = 0;
prev_pkt = -1;
sigvar = 0;
print_verbose("Creating socket\n");
testapp_validate();
test_type == TEST_TYPE_BIDI ? bidi_pass++ : bidi_pass;
if (!bidi_pass) {
print_verbose("Switching Tx/Rx vectors\n");
swap_vectors(ifdict[1], ifdict[0]);
}
bidi_pass++;
}
swap_vectors(ifdict[0], ifdict[1]);
print_ksft_result();
}
......@@ -997,7 +1008,7 @@ static void testapp_stats(void)
static void init_iface(struct ifobject *ifobj, const char *dst_mac,
const char *src_mac, const char *dst_ip,
const char *src_ip, const u16 dst_port,
const u16 src_port)
const u16 src_port, enum fvector vector)
{
struct in_addr ip;
......@@ -1012,6 +1023,16 @@ static void init_iface(struct ifobject *ifobj, const char *dst_mac,
ifobj->dst_port = dst_port;
ifobj->src_port = src_port;
if (vector == tx) {
ifobj->fv.vector = tx;
ifobj->func_ptr = worker_testapp_validate_tx;
ifdict_tx = ifobj;
} else {
ifobj->fv.vector = rx;
ifobj->func_ptr = worker_testapp_validate_rx;
ifdict_rx = ifobj;
}
}
static void run_pkt_test(int mode, int type)
......@@ -1021,11 +1042,8 @@ static void run_pkt_test(int mode, int type)
/* reset defaults after potential previous test */
xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
pkt_counter = 0;
switching_notify = 0;
bidi_pass = 0;
prev_pkt = -1;
ifdict[0]->fv.vector = tx;
ifdict[1]->fv.vector = rx;
sigvar = 0;
stat_test_type = -1;
rxqsize = XSK_RING_CONS__DEFAULT_NUM_DESCS;
......@@ -1042,16 +1060,20 @@ static void run_pkt_test(int mode, int type)
break;
}
pthread_init_mutex();
if (test_type == TEST_TYPE_STATS)
switch (test_type) {
case TEST_TYPE_STATS:
testapp_stats();
else if ((test_type != TEST_TYPE_TEARDOWN) && (test_type != TEST_TYPE_BIDI))
break;
case TEST_TYPE_TEARDOWN:
testapp_teardown();
break;
case TEST_TYPE_BIDI:
testapp_bidi();
break;
default:
testapp_validate();
else
testapp_sockets();
pthread_destroy_mutex();
break;
}
}
int main(int argc, char **argv)
......@@ -1076,14 +1098,13 @@ int main(int argc, char **argv)
num_frames = ++opt_pkt_count;
ifdict[0]->fv.vector = tx;
init_iface(ifdict[0], MAC1, MAC2, IP1, IP2, UDP_PORT1, UDP_PORT2);
ifdict[1]->fv.vector = rx;
init_iface(ifdict[1], MAC2, MAC1, IP2, IP1, UDP_PORT2, UDP_PORT1);
init_iface(ifdict[0], MAC1, MAC2, IP1, IP2, UDP_PORT1, UDP_PORT2, tx);
init_iface(ifdict[1], MAC2, MAC1, IP2, IP1, UDP_PORT2, UDP_PORT1, rx);
ksft_set_plan(TEST_MODE_MAX * TEST_TYPE_MAX);
pthread_init_mutex();
for (i = 0; i < TEST_MODE_MAX; i++) {
for (j = 0; j < TEST_TYPE_MAX; j++)
run_pkt_test(i, j);
......@@ -1095,6 +1116,8 @@ int main(int argc, char **argv)
free(ifdict[i]);
}
pthread_destroy_mutex();
ksft_exit_pass();
return 0;
......
......@@ -77,7 +77,6 @@ enum STAT_TEST_TYPES {
static int configured_mode = TEST_MODE_UNCONFIGURED;
static u8 debug_pkt_dump;
static u32 num_frames;
static u8 switching_notify;
static u8 bidi_pass;
static int test_type;
......@@ -126,22 +125,25 @@ struct generic_data {
};
struct ifobject {
int ns_fd;
int ifdict_index;
char ifname[MAX_INTERFACE_NAME_CHARS];
char nsname[MAX_INTERFACES_NAMESPACE_CHARS];
struct flow_vector fv;
struct xsk_socket_info *xsk;
struct xsk_umem_info *umem;
u8 dst_mac[ETH_ALEN];
u8 src_mac[ETH_ALEN];
void *(*func_ptr)(void *arg);
struct flow_vector fv;
int ns_fd;
int ifdict_index;
u32 dst_ip;
u32 src_ip;
u16 src_port;
u16 dst_port;
u8 dst_mac[ETH_ALEN];
u8 src_mac[ETH_ALEN];
};
static struct ifobject *ifdict[MAX_INTERFACES];
static struct ifobject *ifdict_rx;
static struct ifobject *ifdict_tx;
/*threads*/
atomic_int spinning_rx;
......
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