Commit 12b4b796 authored by Stanislav Fomichev's avatar Stanislav Fomichev Committed by Alexei Starovoitov

selftests/bpf: Convert xdp_hw_metadata to XDP_USE_NEED_WAKEUP

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: default avatarStanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/r/20231127190319.1190813-13-sdf@google.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 40808a23
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include "xdp_metadata.h" #include "xdp_metadata.h"
#define UMEM_NUM 16 #define UMEM_NUM 256
#define UMEM_FRAME_SIZE XSK_UMEM__DEFAULT_FRAME_SIZE #define UMEM_FRAME_SIZE XSK_UMEM__DEFAULT_FRAME_SIZE
#define UMEM_SIZE (UMEM_FRAME_SIZE * UMEM_NUM) #define UMEM_SIZE (UMEM_FRAME_SIZE * UMEM_NUM)
#define XDP_FLAGS (XDP_FLAGS_DRV_MODE | XDP_FLAGS_REPLACE) #define XDP_FLAGS (XDP_FLAGS_DRV_MODE | XDP_FLAGS_REPLACE)
...@@ -48,7 +48,7 @@ struct xsk { ...@@ -48,7 +48,7 @@ struct xsk {
}; };
struct xdp_hw_metadata *bpf_obj; struct xdp_hw_metadata *bpf_obj;
__u16 bind_flags = XDP_COPY; __u16 bind_flags = XDP_USE_NEED_WAKEUP | XDP_ZEROCOPY;
struct xsk *rx_xsk; struct xsk *rx_xsk;
const char *ifname; const char *ifname;
int ifindex; int ifindex;
...@@ -68,7 +68,7 @@ static int open_xsk(int ifindex, struct xsk *xsk, __u32 queue_id) ...@@ -68,7 +68,7 @@ static int open_xsk(int ifindex, struct xsk *xsk, __u32 queue_id)
.fill_size = XSK_RING_PROD__DEFAULT_NUM_DESCS, .fill_size = XSK_RING_PROD__DEFAULT_NUM_DESCS,
.comp_size = XSK_RING_CONS__DEFAULT_NUM_DESCS, .comp_size = XSK_RING_CONS__DEFAULT_NUM_DESCS,
.frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE, .frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE,
.flags = XDP_UMEM_UNALIGNED_CHUNK_FLAG, .flags = XSK_UMEM__DEFAULT_FLAGS,
}; };
__u32 idx; __u32 idx;
u64 addr; u64 addr;
...@@ -110,7 +110,7 @@ static int open_xsk(int ifindex, struct xsk *xsk, __u32 queue_id) ...@@ -110,7 +110,7 @@ static int open_xsk(int ifindex, struct xsk *xsk, __u32 queue_id)
for (i = 0; i < UMEM_NUM / 2; i++) { for (i = 0; i < UMEM_NUM / 2; i++) {
addr = (UMEM_NUM / 2 + i) * UMEM_FRAME_SIZE; addr = (UMEM_NUM / 2 + i) * UMEM_FRAME_SIZE;
printf("%p: rx_desc[%d] -> %lx\n", xsk, i, addr); 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); xsk_ring_prod__submit(&xsk->fill, ret);
...@@ -131,12 +131,22 @@ static void refill_rx(struct xsk *xsk, __u64 addr) ...@@ -131,12 +131,22 @@ static void refill_rx(struct xsk *xsk, __u64 addr)
__u32 idx; __u32 idx;
if (xsk_ring_prod__reserve(&xsk->fill, 1, &idx) == 1) { 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__fill_addr(&xsk->fill, idx) = addr;
xsk_ring_prod__submit(&xsk->fill, 1); 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 */ #define NANOSEC_PER_SEC 1000000000 /* 10^9 */
static __u64 gettime(clockid_t clock_id) static __u64 gettime(clockid_t clock_id)
{ {
...@@ -152,6 +162,17 @@ 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; 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) static void verify_xdp_metadata(void *data, clockid_t clock_id)
{ {
struct xdp_meta *meta; struct xdp_meta *meta;
...@@ -167,22 +188,13 @@ static void verify_xdp_metadata(void *data, clockid_t clock_id) ...@@ -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, printf("rx_timestamp: %llu (sec:%0.4f)\n", meta->rx_timestamp,
(double)meta->rx_timestamp / NANOSEC_PER_SEC); (double)meta->rx_timestamp / NANOSEC_PER_SEC);
if (meta->rx_timestamp) { if (meta->rx_timestamp) {
__u64 usr_clock = gettime(clock_id); __u64 ref_tstamp = 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);
}
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) 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 ...@@ -252,6 +264,13 @@ static int verify_metadata(struct xsk *rx_xsk, int rxq, int server_fd, clockid_t
while (true) { while (true) {
errno = 0; 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); ret = poll(fds, rxq + 1, 1000);
printf("poll: %d (%d) skip=%llu fail=%llu redir=%llu\n", printf("poll: %d (%d) skip=%llu fail=%llu redir=%llu\n",
ret, errno, bpf_obj->bss->pkts_skip, ret, errno, bpf_obj->bss->pkts_skip,
...@@ -420,8 +439,9 @@ static void print_usage(void) ...@@ -420,8 +439,9 @@ static void print_usage(void)
{ {
const char *usage = const char *usage =
"Usage: xdp_hw_metadata [OPTIONS] [IFNAME]\n" "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" " -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" "Generate test packets on the other machine with:\n"
" echo -n xdp | nc -u -q1 <dst_ip> 9091\n"; " echo -n xdp | nc -u -q1 <dst_ip> 9091\n";
...@@ -432,14 +452,19 @@ static void read_args(int argc, char *argv[]) ...@@ -432,14 +452,19 @@ static void read_args(int argc, char *argv[])
{ {
int opt; int opt;
while ((opt = getopt(argc, argv, "mh")) != -1) { while ((opt = getopt(argc, argv, "chm")) != -1) {
switch (opt) { switch (opt) {
case 'm': case 'c':
bind_flags |= XDP_USE_SG; bind_flags &= ~XDP_USE_NEED_WAKEUP;
bind_flags &= ~XDP_ZEROCOPY;
bind_flags |= XDP_COPY;
break; break;
case 'h': case 'h':
print_usage(); print_usage();
exit(0); exit(0);
case 'm':
bind_flags |= XDP_USE_SG;
break;
case '?': case '?':
if (isprint(optopt)) if (isprint(optopt))
fprintf(stderr, "Unknown option: -%c\n", optopt); fprintf(stderr, "Unknown option: -%c\n", optopt);
......
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