selftests: xsk: Refactor teardown/bidi test cases and testapp_validate
authorMaciej Fijalkowski <maciej.fijalkowski@intel.com>
Mon, 29 Mar 2021 22:43:10 +0000 (00:43 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 30 Mar 2021 16:24:39 +0000 (09:24 -0700)
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
tools/testing/selftests/bpf/xdpxceiver.c
tools/testing/selftests/bpf/xdpxceiver.h

index 9f7ee9a38752e23f29dc2ed2a18ae38cc80f4e55..c0ebca8f55f8adfe3ce1311b30b428f10314edd7 100644 (file)
@@ -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;
index 483be41229c67222bfab936f4c6873c1c49a23c9..3945746900afc1018b9fc87ac1c39fabab60e801 100644 (file)
@@ -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;