drivers/md/dm-vdo/cpu.h

Source file repositories/reference/linux-study-clean/drivers/md/dm-vdo/cpu.h

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-vdo/cpu.h
Extension
.h
Size
1932 bytes
Lines
60
Domain
Driver Families
Bucket
drivers/md
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

#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 */

Annotation

Implementation Notes