1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright 2023 Red Hat
9 #include <linux/cache.h>
12 * uds_prefetch_address() - Minimize cache-miss latency by attempting to move data into a CPU cache
13 * before it is accessed.
15 * @address: the address to fetch (may be invalid)
16 * @for_write: must be constant at compile time--false if for reading, true if for writing
18 static inline void uds_prefetch_address(const void *address
, bool for_write
)
21 * for_write won't be a constant if we are compiled with optimization turned off, in which
22 * case prefetching really doesn't matter. clang can't figure out that if for_write is a
23 * constant, it can be passed as the second, mandatorily constant argument to prefetch(),
24 * at least currently on llvm 12.
26 if (__builtin_constant_p(for_write
)) {
28 __builtin_prefetch(address
, true);
30 __builtin_prefetch(address
, false);
35 * uds_prefetch_range() - Minimize cache-miss latency by attempting to move a range of addresses
36 * into a CPU cache before they are accessed.
38 * @start: the starting address to fetch (may be invalid)
39 * @size: the number of bytes in the address range
40 * @for_write: must be constant at compile time--false if for reading, true if for writing
42 static inline void uds_prefetch_range(const void *start
, unsigned int size
,
46 * Count the number of cache lines to fetch, allowing for the address range to span an
47 * extra cache line boundary due to address alignment.
49 const char *address
= (const char *) start
;
50 unsigned int offset
= ((uintptr_t) address
% L1_CACHE_BYTES
);
51 unsigned int cache_lines
= (1 + ((size
+ offset
) / L1_CACHE_BYTES
));
53 while (cache_lines
-- > 0) {
54 uds_prefetch_address(address
, for_write
);
55 address
+= L1_CACHE_BYTES
;
59 #endif /* UDS_CPU_H */