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: Maciej Fijalkowski <maciej.fijalkowski@intel.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20210329224316.17793-12-maciej.fijalkowski@intel.com
This commit is contained in:
parent
99f9bcb657
commit
9445f8c765
@ -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,21 +929,56 @@ static void testapp_validate(void)
|
||||
print_ksft_result();
|
||||
}
|
||||
|
||||
static void testapp_sockets(void)
|
||||
static void testapp_teardown(void)
|
||||
{
|
||||
for (int i = 0; i < ((test_type == TEST_TYPE_TEARDOWN) ? MAX_TEARDOWN_ITER : MAX_BIDI_ITER);
|
||||
i++) {
|
||||
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();
|
||||
test_type == TEST_TYPE_BIDI ? bidi_pass++ : bidi_pass;
|
||||
}
|
||||
|
||||
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 < MAX_BIDI_ITER; i++) {
|
||||
pkt_counter = 0;
|
||||
prev_pkt = -1;
|
||||
sigvar = 0;
|
||||
print_verbose("Creating socket\n");
|
||||
testapp_validate();
|
||||
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();
|
||||
}
|
||||
|
||||
static void testapp_stats(void)
|
||||
{
|
||||
for (int i = 0; i < STAT_TEST_TYPE_MAX; i++) {
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user