git: cdd95034d6f4 - main - iflib: unify prefetching

From: Andrew Gallatin <gallatin_at_FreeBSD.org>
Date: Mon, 12 Oct 2026 21:27:36 UTC
The branch main has been updated by gallatin:

URL: https://cgit.FreeBSD.org/src/commit/?id=cdd95034d6f4b5a7abe7d21b2b1a568fa5e906a0

commit cdd95034d6f4b5a7abe7d21b2b1a568fa5e906a0
Author:     Andrew Gallatin <gallatin@FreeBSD.org>
AuthorDate: 2026-10-12 19:50:15 +0000
Commit:     Andrew Gallatin <gallatin@FreeBSD.org>
CommitDate: 2026-10-12 21:27:26 +0000

    iflib: unify prefetching
    
    This change makes all prefetching use the iflib prefetch wrappers, rather
    than using prefetch() in some places and __builtin_prefetch() in others.
    
    Note that __builtin_prefetch() does not work in the kernel on amd64 as clang
    disables it when -mnosse is specified, so we must use the asm directives there,
    and builtin_prefetch() elsewhere.
    
    This change enables prefetching on non-x86 (notably arm64), and it enables
    prefetching in netmap that has been there since day one, but which has never worked.
    
    This is a no-op on non-netmap amd64 and i386
    
    Differential Revision: https://reviews.freebsd.org/D60602
    Reviewed by: glebius, kbowling
    Sponsored by: Netflix
---
 sys/net/iflib.c | 58 +++++++++++++++++++++++++--------------------------------
 1 file changed, 25 insertions(+), 33 deletions(-)

diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index 358e2f03aded..9ca08eaee6e8 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -912,6 +912,25 @@ iflib_num_tx_descs(if_ctx_t ctx)
 	return (scctx->isc_ntxd[first_txq]);
 }
 
+static inline void
+prefetch(void *x)
+{
+#if defined(__i386__) || defined(__amd64__)
+	__asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x));
+#else
+	__builtin_prefetch(x);
+#endif
+}
+
+static inline void
+prefetch2cachelines(void *x)
+{
+	prefetch(x);
+#if (CACHE_LINE_SIZE < 128)
+	prefetch((char *)x + CACHE_LINE_SIZE);
+#endif
+}
+
 #ifdef DEV_NETMAP
 #include <sys/selinfo.h>
 #include <net/netmap.h>
@@ -1194,9 +1213,9 @@ iflib_netmap_txsync(struct netmap_kring *kring, int flags)
 		pi.ipi_qsidx = kring->ring_id;
 		nic_i = netmap_idx_k2n(kring, nm_i);
 
-		__builtin_prefetch(&ring->slot[nm_i]);
-		__builtin_prefetch(&txq->ift_sds.ifsd_m[nic_i]);
-		__builtin_prefetch(&txq->ift_sds.ifsd_map[nic_i]);
+		prefetch(&ring->slot[nm_i]);
+		prefetch(&txq->ift_sds.ifsd_m[nic_i]);
+		prefetch(&txq->ift_sds.ifsd_map[nic_i]);
 
 		while (nm_i != head) {
 			struct netmap_slot *slot = &ring->slot[nm_i];
@@ -1244,9 +1263,9 @@ iflib_netmap_txsync(struct netmap_kring *kring, int flags)
 			}
 
 			/* prefetch for next round */
-			__builtin_prefetch(&ring->slot[nm_i + 1]);
-			__builtin_prefetch(&txq->ift_sds.ifsd_m[nic_i + 1]);
-			__builtin_prefetch(&txq->ift_sds.ifsd_map[nic_i + 1]);
+			prefetch(&ring->slot[nm_i + 1]);
+			prefetch(&txq->ift_sds.ifsd_m[nic_i + 1]);
+			prefetch(&txq->ift_sds.ifsd_map[nic_i + 1]);
 
 			NM_CHECK_ADDR_LEN_OFF(na, len, offset);
 
@@ -1548,33 +1567,6 @@ iflib_netmap_timer(void *arg)
 #define netmap_rx_irq(ifp, qid, budget) (0)
 #endif
 
-#if defined(__i386__) || defined(__amd64__)
-static __inline void
-prefetch(void *x)
-{
-	__asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x));
-}
-
-static __inline void
-prefetch2cachelines(void *x)
-{
-	__asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x));
-#if (CACHE_LINE_SIZE < 128)
-	__asm volatile("prefetcht0 %0" :: "m" (*(((unsigned long *)x) + CACHE_LINE_SIZE / (sizeof(unsigned long)))));
-#endif
-}
-#else
-static __inline void
-prefetch(void *x)
-{
-}
-
-static __inline void
-prefetch2cachelines(void *x)
-{
-}
-#endif
-
 static void
 iru_init(if_rxd_update_t iru, iflib_rxq_t rxq, uint8_t flid)
 {