@@ -4,6 +4,7 @@
#include <bpf/xsk.h>
#include <linux/version.h>
+#include <poll.h>
#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE && \
defined(RTE_LIBRTE_AF_XDP_PMD_SHARED_UMEM)
@@ -41,10 +42,22 @@ create_shared_socket(struct xsk_socket **xsk_ptr __rte_unused,
#endif
#ifdef XDP_USE_NEED_WAKEUP
-static int
-rx_syscall_needed(struct xsk_ring_prod *q, uint32_t busy_budget)
+static void
+rx_syscall_handler(struct xsk_ring_prod *q, uint32_t busy_budget,
+ struct pollfd *fds, struct xsk_socket *xsk)
{
- return xsk_ring_prod__needs_wakeup(q) | busy_budget;
+ /* we can assume a kernel >= 5.11 is in use if busy polling is enabled
+ * and thus we can safely use the recvfrom() syscall which is only
+ * supported for AF_XDP sockets in kernels >= 5.11.
+ */
+ if (busy_budget) {
+ (void)recvfrom(xsk_socket__fd(xsk), NULL, 0,
+ MSG_DONTWAIT, NULL, NULL);
+ return;
+ }
+
+ if (xsk_ring_prod__needs_wakeup(q))
+ (void)poll(fds, 1, 1000);
}
static int
tx_syscall_needed(struct xsk_ring_prod *q)
@@ -52,10 +65,13 @@ tx_syscall_needed(struct xsk_ring_prod *q)
return xsk_ring_prod__needs_wakeup(q);
}
#else
-static int
-rx_syscall_needed(struct xsk_ring_prod *q __rte_unused, uint32_t busy_budget)
+static void
+rx_syscall_handler(struct xsk_ring_prod *q __rte_unused, uint32_t busy_budget,
+ struct pollfd *fds __rte_unused, struct xsk_socket *xsk)
{
- return busy_budget;
+ if (busy_budget)
+ (void)recvfrom(xsk_socket__fd(xsk), NULL, 0,
+ MSG_DONTWAIT, NULL, NULL);
}
static int
tx_syscall_needed(struct xsk_ring_prod *q __rte_unused)
@@ -5,7 +5,6 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
-#include <poll.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/socket.h>
@@ -273,10 +272,8 @@ af_xdp_rx_zc(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
nb_pkts = xsk_ring_cons__peek(rx, nb_pkts, &idx_rx);
if (nb_pkts == 0) {
- if (rx_syscall_needed(&rxq->fq, rxq->busy_budget))
- (void)recvfrom(xsk_socket__fd(rxq->xsk), NULL, 0,
- MSG_DONTWAIT, NULL, NULL);
-
+ rx_syscall_handler(&rxq->fq, rxq->busy_budget, &rxq->fds[0],
+ rxq->xsk);
return 0;
}
@@ -346,8 +343,7 @@ af_xdp_rx_cp(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
if (nb_pkts == 0) {
#if defined(XDP_USE_NEED_WAKEUP)
if (xsk_ring_prod__needs_wakeup(fq))
- (void)recvfrom(xsk_socket__fd(rxq->xsk), NULL, 0,
- MSG_DONTWAIT, NULL, NULL);
+ (void)poll(rxq->fds, 1, 1000);
#endif
return 0;
}