git: cdd95034d6f4 - main - iflib: unify prefetching
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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)
{