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