selftests/bpf: Convert xdp_hw_metadata to XDP_USE_NEED_WAKEUP
authorStanislav Fomichev <sdf@google.com>
Mon, 27 Nov 2023 19:03:18 +0000 (11:03 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 29 Nov 2023 22:59:41 +0000 (14:59 -0800)
This is the recommended way to run AF_XDP, so let's use it in the test.

Also, some unrelated changes to now blow up the log too much:
- change default mode to zerocopy and add -c to use copy mode
- small fixes for the flags/sizes/prints
- add print_tstamp_delta to print timestamp + reference

Signed-off-by: Stanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/r/20231127190319.1190813-13-sdf@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/xdp_hw_metadata.c

index c3ba40d0b9de4617eea41095d1a69fee2a872a98..4484b17c7a56f7334a225c34ca1ecef9110d996c 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "xdp_metadata.h"
 
-#define UMEM_NUM 16
+#define UMEM_NUM 256
 #define UMEM_FRAME_SIZE XSK_UMEM__DEFAULT_FRAME_SIZE
 #define UMEM_SIZE (UMEM_FRAME_SIZE * UMEM_NUM)
 #define XDP_FLAGS (XDP_FLAGS_DRV_MODE | XDP_FLAGS_REPLACE)
@@ -48,7 +48,7 @@ struct xsk {
 };
 
 struct xdp_hw_metadata *bpf_obj;
-__u16 bind_flags = XDP_COPY;
+__u16 bind_flags = XDP_USE_NEED_WAKEUP | XDP_ZEROCOPY;
 struct xsk *rx_xsk;
 const char *ifname;
 int ifindex;
@@ -68,7 +68,7 @@ static int open_xsk(int ifindex, struct xsk *xsk, __u32 queue_id)
                .fill_size = XSK_RING_PROD__DEFAULT_NUM_DESCS,
                .comp_size = XSK_RING_CONS__DEFAULT_NUM_DESCS,
                .frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE,
-               .flags = XDP_UMEM_UNALIGNED_CHUNK_FLAG,
+               .flags = XSK_UMEM__DEFAULT_FLAGS,
        };
        __u32 idx;
        u64 addr;
@@ -110,7 +110,7 @@ static int open_xsk(int ifindex, struct xsk *xsk, __u32 queue_id)
        for (i = 0; i < UMEM_NUM / 2; i++) {
                addr = (UMEM_NUM / 2 + i) * UMEM_FRAME_SIZE;
                printf("%p: rx_desc[%d] -> %lx\n", xsk, i, addr);
-               *xsk_ring_prod__fill_addr(&xsk->fill, i) = addr;
+               *xsk_ring_prod__fill_addr(&xsk->fill, idx + i) = addr;
        }
        xsk_ring_prod__submit(&xsk->fill, ret);
 
@@ -131,12 +131,22 @@ static void refill_rx(struct xsk *xsk, __u64 addr)
        __u32 idx;
 
        if (xsk_ring_prod__reserve(&xsk->fill, 1, &idx) == 1) {
-               printf("%p: complete idx=%u addr=%llx\n", xsk, idx, addr);
+               printf("%p: complete rx idx=%u addr=%llx\n", xsk, idx, addr);
                *xsk_ring_prod__fill_addr(&xsk->fill, idx) = addr;
                xsk_ring_prod__submit(&xsk->fill, 1);
        }
 }
 
+static int kick_tx(struct xsk *xsk)
+{
+       return sendto(xsk_socket__fd(xsk->socket), NULL, 0, MSG_DONTWAIT, NULL, 0);
+}
+
+static int kick_rx(struct xsk *xsk)
+{
+       return recvfrom(xsk_socket__fd(xsk->socket), NULL, 0, MSG_DONTWAIT, NULL, NULL);
+}
+
 #define NANOSEC_PER_SEC 1000000000 /* 10^9 */
 static __u64 gettime(clockid_t clock_id)
 {
@@ -152,6 +162,17 @@ static __u64 gettime(clockid_t clock_id)
        return (__u64) t.tv_sec * NANOSEC_PER_SEC + t.tv_nsec;
 }
 
+static void print_tstamp_delta(const char *name, const char *refname,
+                              __u64 tstamp, __u64 reference)
+{
+       __s64 delta = (__s64)reference - (__s64)tstamp;
+
+       printf("%s:   %llu (sec:%0.4f) delta to %s sec:%0.4f (%0.3f usec)\n",
+              name, tstamp, (double)tstamp / NANOSEC_PER_SEC, refname,
+              (double)delta / NANOSEC_PER_SEC,
+              (double)delta / 1000);
+}
+
 static void verify_xdp_metadata(void *data, clockid_t clock_id)
 {
        struct xdp_meta *meta;
@@ -167,22 +188,13 @@ static void verify_xdp_metadata(void *data, clockid_t clock_id)
        printf("rx_timestamp:  %llu (sec:%0.4f)\n", meta->rx_timestamp,
               (double)meta->rx_timestamp / NANOSEC_PER_SEC);
        if (meta->rx_timestamp) {
-               __u64 usr_clock = gettime(clock_id);
-               __u64 xdp_clock = meta->xdp_timestamp;
-               __s64 delta_X = xdp_clock - meta->rx_timestamp;
-               __s64 delta_X2U = usr_clock - xdp_clock;
-
-               printf("XDP RX-time:   %llu (sec:%0.4f) delta sec:%0.4f (%0.3f usec)\n",
-                      xdp_clock, (double)xdp_clock / NANOSEC_PER_SEC,
-                      (double)delta_X / NANOSEC_PER_SEC,
-                      (double)delta_X / 1000);
-
-               printf("AF_XDP time:   %llu (sec:%0.4f) delta sec:%0.4f (%0.3f usec)\n",
-                      usr_clock, (double)usr_clock / NANOSEC_PER_SEC,
-                      (double)delta_X2U / NANOSEC_PER_SEC,
-                      (double)delta_X2U / 1000);
-       }
+               __u64 ref_tstamp = gettime(clock_id);
 
+               print_tstamp_delta("HW RX-time", "User RX-time",
+                                  meta->rx_timestamp, ref_tstamp);
+               print_tstamp_delta("XDP RX-time", "User RX-time",
+                                  meta->xdp_timestamp, ref_tstamp);
+       }
 }
 
 static void verify_skb_metadata(int fd)
@@ -252,6 +264,13 @@ static int verify_metadata(struct xsk *rx_xsk, int rxq, int server_fd, clockid_t
 
        while (true) {
                errno = 0;
+
+               for (i = 0; i < rxq; i++) {
+                       ret = kick_rx(&rx_xsk[i]);
+                       if (ret)
+                               printf("kick_rx ret=%d\n", ret);
+               }
+
                ret = poll(fds, rxq + 1, 1000);
                printf("poll: %d (%d) skip=%llu fail=%llu redir=%llu\n",
                       ret, errno, bpf_obj->bss->pkts_skip,
@@ -420,8 +439,9 @@ static void print_usage(void)
 {
        const char *usage =
                "Usage: xdp_hw_metadata [OPTIONS] [IFNAME]\n"
-               "  -m    Enable multi-buffer XDP for larger MTU\n"
+               "  -c    Run in copy mode (zerocopy is default)\n"
                "  -h    Display this help and exit\n\n"
+               "  -m    Enable multi-buffer XDP for larger MTU\n"
                "Generate test packets on the other machine with:\n"
                "  echo -n xdp | nc -u -q1 <dst_ip> 9091\n";
 
@@ -432,14 +452,19 @@ static void read_args(int argc, char *argv[])
 {
        int opt;
 
-       while ((opt = getopt(argc, argv, "mh")) != -1) {
+       while ((opt = getopt(argc, argv, "chm")) != -1) {
                switch (opt) {
-               case 'm':
-                       bind_flags |= XDP_USE_SG;
+               case 'c':
+                       bind_flags &= ~XDP_USE_NEED_WAKEUP;
+                       bind_flags &= ~XDP_ZEROCOPY;
+                       bind_flags |= XDP_COPY;
                        break;
                case 'h':
                        print_usage();
                        exit(0);
+               case 'm':
+                       bind_flags |= XDP_USE_SG;
+                       break;
                case '?':
                        if (isprint(optopt))
                                fprintf(stderr, "Unknown option: -%c\n", optopt);