include/asm-generic/rwonce.h

Source file repositories/reference/linux-study-clean/include/asm-generic/rwonce.h

File Facts

System
Linux kernel
Corpus path
include/asm-generic/rwonce.h
Extension
.h
Size
3205 bytes
Lines
99
Domain
Repository Root And Misc
Bucket
include
Inferred role
Repository Root And Misc: implementation source
Status
source implementation candidate

Why This File Exists

Top-level or miscellaneous repository surface. Use this as map coverage unless a later manual pass promotes the file into a deeper subsystem dossier.

Dependency Surface

Detected Declarations

Annotated Snippet

#ifndef __ASM_GENERIC_RWONCE_H
#define __ASM_GENERIC_RWONCE_H

#ifndef __ASSEMBLY__

#include <linux/compiler_types.h>
#include <linux/kasan-checks.h>
#include <linux/kcsan-checks.h>

/*
 * Yes, this permits 64-bit accesses on 32-bit architectures. These will
 * actually be atomic in some cases (namely Armv7 + LPAE), but for others we
 * rely on the access being split into 2x32-bit accesses for a 32-bit quantity
 * (e.g. a virtual address) and a strong prevailing wind.
 */
#define compiletime_assert_rwonce_type(t)					\
	compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long),	\
		"Unsupported access size for {READ,WRITE}_ONCE().")

/*
 * Use __READ_ONCE() instead of READ_ONCE() if you do not require any
 * atomicity. Note that this may result in tears!
 */
#ifndef __READ_ONCE
#define __READ_ONCE(x)	(*(const volatile __unqual_scalar_typeof(x) *)&(x))
#endif

#define READ_ONCE(x)							\
({									\
	compiletime_assert_rwonce_type(x);				\
	__READ_ONCE(x);							\
})

#define __WRITE_ONCE(x, val)						\
do {									\
	*(volatile typeof(x) *)&(x) = (val);				\
} while (0)

#define WRITE_ONCE(x, val)						\
do {									\
	compiletime_assert_rwonce_type(x);				\
	__WRITE_ONCE(x, val);						\
} while (0)

static __no_sanitize_or_inline
unsigned long __read_once_word_nocheck(const void *addr)
{
	return __READ_ONCE(*(unsigned long *)addr);
}

/*
 * Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need to load a
 * word from memory atomically but without telling KASAN/KCSAN. This is
 * usually used by unwinding code when walking the stack of a running process.
 */
#define READ_ONCE_NOCHECK(x)						\
({									\
	compiletime_assert(sizeof(x) == sizeof(unsigned long),		\
		"Unsupported access size for READ_ONCE_NOCHECK().");	\
	(typeof(x))__read_once_word_nocheck(&(x));			\
})

static __no_sanitize_or_inline
unsigned long read_word_at_a_time(const void *addr)
{
	/* open-coded instrument_read(addr, 1) */
	kasan_check_read(addr, 1);
	kcsan_check_read(addr, 1);

	/*
	 * This load can race with concurrent stores to out-of-bounds memory,
	 * but READ_ONCE() can't be used because it requires higher alignment
	 * than plain loads in arm64 builds with LTO.
	 */
	return *(unsigned long *)addr;
}

#endif /* __ASSEMBLY__ */
#endif	/* __ASM_GENERIC_RWONCE_H */

Annotation

Implementation Notes