From ed5af003e157c40b50f836de32219ab38b481346 Mon Sep 17 00:00:00 2001 From: yangchen Date: Fri, 27 Sep 2024 04:55:05 +0800 Subject: [PATCH] af_xdp: support recv multi-buffer --- drivers/net/af_xdp/rte_eth_af_xdp.c | 53 +++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/drivers/net/af_xdp/rte_eth_af_xdp.c b/drivers/net/af_xdp/rte_eth_af_xdp.c index e79a308..ddee40d 100644 --- a/drivers/net/af_xdp/rte_eth_af_xdp.c +++ b/drivers/net/af_xdp/rte_eth_af_xdp.c @@ -62,6 +62,15 @@ #define PF_XDP AF_XDP #endif +/* XDP_USE_SG and XDP_PKT_CONTD are defined in linux/if_xdp.h, but not present before kernel-6.x. */ +#ifndef XDP_USE_SG +#define XDP_USE_SG (1 << 4) +#endif + +#ifndef XDP_PKT_CONTD +#define XDP_PKT_CONTD (1 << 0) +#endif + RTE_LOG_REGISTER_DEFAULT(af_xdp_logtype, NOTICE); #define AF_XDP_LOG(level, fmt, args...) \ @@ -321,6 +330,10 @@ af_xdp_rx_zc(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) int i; struct rte_mbuf *fq_bufs[ETH_AF_XDP_RX_BATCH_SIZE]; struct rte_eth_dev *dev = &rte_eth_devices[rxq->port]; + bool new_packet = true; + struct rte_mbuf *cur_mbuf = NULL; + struct rte_mbuf *pre_mbuf = NULL; + uint16_t rcvd_pkts = 0; nb_pkts = xsk_ring_cons__peek(rx, nb_pkts, &idx_rx); @@ -358,27 +371,43 @@ af_xdp_rx_zc(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) uint64_t addr; uint32_t len; uint64_t offset; + bool eop = true; desc = xsk_ring_cons__rx_desc(rx, idx_rx++); addr = desc->addr; len = desc->len; + eop = !(desc->options & XDP_PKT_CONTD); offset = xsk_umem__extract_offset(addr); addr = xsk_umem__extract_addr(addr); - bufs[i] = (struct rte_mbuf *) - xsk_umem__get_data(umem->buffer, addr + - umem->mb_pool->header_size); - bufs[i]->data_off = offset - sizeof(struct rte_mbuf) - + cur_mbuf = (struct rte_mbuf *)xsk_umem__get_data(umem->buffer, + addr + umem->mb_pool->header_size); + cur_mbuf->data_off = offset - sizeof(struct rte_mbuf) - rte_pktmbuf_priv_size(umem->mb_pool) - umem->mb_pool->header_size; - bufs[i]->port = rxq->port; - - rte_pktmbuf_pkt_len(bufs[i]) = len; - rte_pktmbuf_data_len(bufs[i]) = len; + cur_mbuf->port = rxq->port; + cur_mbuf->next = NULL; + rte_pktmbuf_pkt_len(cur_mbuf) = len; + rte_pktmbuf_data_len(cur_mbuf) = len; rx_bytes += len; - } + if (new_packet) { + bufs[rcvd_pkts] = cur_mbuf; + bufs[rcvd_pkts]->nb_segs = 1; + rcvd_pkts++; + } else { + bufs[rcvd_pkts - 1]->nb_segs++; + bufs[rcvd_pkts - 1]->pkt_len += cur_mbuf->pkt_len; + pre_mbuf->next = cur_mbuf; + } + + if (!eop) { + pre_mbuf = cur_mbuf; + } + + new_packet = eop; + } xsk_ring_cons__release(rx, nb_pkts); (void)reserve_fill_queue(umem, nb_pkts, fq_bufs, fq); @@ -386,7 +415,7 @@ af_xdp_rx_zc(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) rxq->stats.rx_pkts += nb_pkts; rxq->stats.rx_bytes += rx_bytes; - return nb_pkts; + return rcvd_pkts; } #else static uint16_t @@ -1679,6 +1708,10 @@ xsk_configure(struct pmd_internals *internals, struct pkt_rx_queue *rxq, cfg.bind_flags |= XDP_USE_NEED_WAKEUP; #endif +#if defined(XDP_USE_SG) + cfg.bind_flags |= XDP_USE_SG; +#endif + /* Disable libbpf from loading XDP program */ if (internals->use_cni || internals->use_pinned_map) cfg.libbpf_flags |= XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD; -- 2.33.0