AF_XDP-interaction: Try preferred busy-polling trick

The apply_setsockopt() was taken from samples/bpf/xdpsock_user.c

Testing with --zero-copy this unfortunately doesn't solve
the issue of 8 packets bulks when requesting 4.
Notice this test was with driver igc and chip i225.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
This commit is contained in:
Jesper Dangaard Brouer
2021-12-13 23:01:09 +01:00
parent 842c707c4e
commit 3685d5ea93

View File

@ -32,6 +32,16 @@
#include <linux/icmpv6.h> #include <linux/icmpv6.h>
#include <linux/udp.h> #include <linux/udp.h>
#include <linux/socket.h>
#ifndef SO_PREFER_BUSY_POLL
#define SO_PREFER_BUSY_POLL 69
#endif
#ifndef SO_BUSY_POLL_BUDGET
#define SO_BUSY_POLL_BUDGET 70
#endif
#include <bpf/btf.h> /* provided by libbpf */ #include <bpf/btf.h> /* provided by libbpf */
#include "common_params.h" #include "common_params.h"
@ -92,6 +102,16 @@ struct xsk_container {
int num; /* Number of xsk_sockets configured */ int num; /* Number of xsk_sockets configured */
}; };
static void __exit_with_error(int error, const char *file, const char *func,
int line)
{
fprintf(stderr, "%s:%s:%i: errno: %d/\"%s\"\n", file, func,
line, error, strerror(error));
exit(EXIT_FAILURE);
}
#define exit_with_error(error) __exit_with_error(error, __FILE__, __func__, __LINE__)
/** /**
* BTF setup XDP-hints * BTF setup XDP-hints
* ------------------- * -------------------
@ -332,6 +352,30 @@ static void mem_init_umem_frame_allocator(struct mem_frame_allocator *mem,
mem->umem_frame_free = nr_frames; mem->umem_frame_free = nr_frames;
} }
static void apply_setsockopt(struct xsk_socket_info *xsk, bool opt_busy_poll,
int opt_batch_size)
{
int sock_opt;
if (!opt_busy_poll)
return;
sock_opt = 1;
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_PREFER_BUSY_POLL,
(void *)&sock_opt, sizeof(sock_opt)) < 0)
exit_with_error(errno);
sock_opt = 20;
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_BUSY_POLL,
(void *)&sock_opt, sizeof(sock_opt)) < 0)
exit_with_error(errno);
sock_opt = opt_batch_size;
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_BUSY_POLL_BUDGET,
(void *)&sock_opt, sizeof(sock_opt)) < 0)
exit_with_error(errno);
}
static struct xsk_umem_info *configure_xsk_umem(void *buffer, uint64_t size, static struct xsk_umem_info *configure_xsk_umem(void *buffer, uint64_t size,
uint32_t frame_size, uint32_t nr_frames) uint32_t frame_size, uint32_t nr_frames)
{ {
@ -451,6 +495,9 @@ static struct xsk_socket_info *xsk_configure_socket(struct config *cfg,
/* Due to XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD manually update map */ /* Due to XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD manually update map */
// xsk_socket__update_xskmap(xsk_info->xsk, xsks_map_fd); // xsk_socket__update_xskmap(xsk_info->xsk, xsks_map_fd);
apply_setsockopt(xsk_info, true, RX_BATCH_SIZE);
return xsk_info; return xsk_info;
error_exit: error_exit:
@ -994,6 +1041,9 @@ static void handle_receive_packets(struct xsk_socket_info *xsk)
unsigned int rcvd, i; unsigned int rcvd, i;
uint32_t idx_rx = 0; uint32_t idx_rx = 0;
// FIXME: Needed when in NAPI busy_poll mode?
recvfrom(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, NULL);
rcvd = xsk_ring_cons__peek(&xsk->rx, RX_BATCH_SIZE, &idx_rx); rcvd = xsk_ring_cons__peek(&xsk->rx, RX_BATCH_SIZE, &idx_rx);
if (!rcvd) if (!rcvd)
return; return;