selftests/xsk: add test for too many frags
authorMagnus Karlsson <magnus.karlsson@intel.com>
Wed, 19 Jul 2023 13:24:20 +0000 (15:24 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 19 Jul 2023 16:56:51 +0000 (09:56 -0700)
Add a test that will exercise maximum number of supported fragments.
This number depends on mode of the test - for SKB and DRV it will be 18
whereas for ZC this is defined by a value from NETDEV_A_DEV_XDP_ZC_MAX_SEGS
netlink attribute.

Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com> # made use of new netlink attribute
Link: https://lore.kernel.org/r/20230719132421.584801-24-maciej.fijalkowski@intel.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/xskxceiver.c
tools/testing/selftests/bpf/xskxceiver.h

index 4767d09d68934dc63a96cee5a35da085b445ec60..3ff43670664013e9f5f19b58af78d6f8f3346628 100644 (file)
@@ -1982,6 +1982,48 @@ static int testapp_poll_rxq_tmout(struct test_spec *test)
        return testapp_validate_traffic_single_thread(test, test->ifobj_rx);
 }
 
+static int testapp_too_many_frags(struct test_spec *test)
+{
+       struct pkt pkts[2 * XSK_DESC__MAX_SKB_FRAGS + 2] = {};
+       u32 max_frags, i;
+
+       test_spec_set_name(test, "TOO_MANY_FRAGS");
+       if (test->mode == TEST_MODE_ZC)
+               max_frags = test->ifobj_tx->xdp_zc_max_segs;
+       else
+               max_frags = XSK_DESC__MAX_SKB_FRAGS;
+
+       test->mtu = MAX_ETH_JUMBO_SIZE;
+
+       /* Valid packet for synch */
+       pkts[0].len = MIN_PKT_SIZE;
+       pkts[0].valid = true;
+
+       /* One valid packet with the max amount of frags */
+       for (i = 1; i < max_frags + 1; i++) {
+               pkts[i].len = MIN_PKT_SIZE;
+               pkts[i].options = XDP_PKT_CONTD;
+               pkts[i].valid = true;
+       }
+       pkts[max_frags].options = 0;
+
+       /* An invalid packet with the max amount of frags but signals packet
+        * continues on the last frag
+        */
+       for (i = max_frags + 1; i < 2 * max_frags + 1; i++) {
+               pkts[i].len = MIN_PKT_SIZE;
+               pkts[i].options = XDP_PKT_CONTD;
+               pkts[i].valid = false;
+       }
+
+       /* Valid packet for synch */
+       pkts[2 * max_frags + 1].len = MIN_PKT_SIZE;
+       pkts[2 * max_frags + 1].valid = true;
+
+       pkt_stream_generate_custom(test, pkts, 2 * max_frags + 2);
+       return testapp_validate_traffic(test);
+}
+
 static int xsk_load_xdp_programs(struct ifobject *ifobj)
 {
        ifobj->xdp_progs = xsk_xdp_progs__open_and_load();
@@ -2039,9 +2081,14 @@ static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *
        }
        if (query_opts.feature_flags & NETDEV_XDP_ACT_RX_SG)
                ifobj->multi_buff_supp = true;
-       if (query_opts.feature_flags & NETDEV_XDP_ACT_XSK_ZEROCOPY)
-               if (query_opts.xdp_zc_max_segs > 1)
+       if (query_opts.feature_flags & NETDEV_XDP_ACT_XSK_ZEROCOPY) {
+               if (query_opts.xdp_zc_max_segs > 1) {
                        ifobj->multi_buff_zc_supp = true;
+                       ifobj->xdp_zc_max_segs = query_opts.xdp_zc_max_segs;
+               } else {
+                       ifobj->xdp_zc_max_segs = 0;
+               }
+       }
 }
 
 static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_type type)
@@ -2170,6 +2217,9 @@ static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_
                test->mtu = MAX_ETH_JUMBO_SIZE;
                ret = testapp_xdp_metadata_count(test);
                break;
+       case TEST_TYPE_TOO_MANY_FRAGS:
+               ret = testapp_too_many_frags(test);
+               break;
        default:
                break;
        }
index 9e1f66e0a3b665def71d1116791fe3cef1d99c34..233b66cef64a59369dae5f35fdfdc72d2b9a9170 100644 (file)
@@ -53,6 +53,7 @@
 #define XSK_UMEM__LARGE_FRAME_SIZE (3 * 1024)
 #define XSK_UMEM__MAX_FRAME_SIZE (4 * 1024)
 #define XSK_DESC__INVALID_OPTION (0xffff)
+#define XSK_DESC__MAX_SKB_FRAGS 18
 #define HUGEPAGE_SIZE (2 * 1024 * 1024)
 #define PKT_DUMP_NB_TO_PRINT 16
 
@@ -93,6 +94,7 @@ enum test_type {
        TEST_TYPE_UNALIGNED_MB,
        TEST_TYPE_ALIGNED_INV_DESC_MB,
        TEST_TYPE_UNALIGNED_INV_DESC_MB,
+       TEST_TYPE_TOO_MANY_FRAGS,
        TEST_TYPE_MAX
 };
 
@@ -155,6 +157,7 @@ struct ifobject {
        int ifindex;
        int mtu;
        u32 bind_flags;
+       u32 xdp_zc_max_segs;
        bool tx_on;
        bool rx_on;
        bool use_poll;