diff --git a/drivers/net/af_xdp/compat.h b/drivers/net/af_xdp/compat.h index 9de9454885..52fd447b69 100644 --- a/drivers/net/af_xdp/compat.h +++ b/drivers/net/af_xdp/compat.h @@ -4,6 +4,7 @@ #include #include +#include #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) diff --git a/drivers/net/af_xdp/rte_eth_af_xdp.c b/drivers/net/af_xdp/rte_eth_af_xdp.c index 8c6cd224a8..0c91a40c4a 100644 --- a/drivers/net/af_xdp/rte_eth_af_xdp.c +++ b/drivers/net/af_xdp/rte_eth_af_xdp.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -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; }