READ_ONCE(), WRITE_ONCE(), but not for Rust [LWN subscriber-only content]
READ_ONCE()
WRITE_ONCE()
READ_ONCE()
Theandmacros are heavily used within the kernel; there are nearly 8,000 call sites for. They are key to the implementation of many lockless algorithms and can be necessary for some types of device-memory access. So one might think that, as the amount of Rust code in the kernel increases, there would be a place for Rust versions of these macros as well. The truth of the matter, though, is that the Rust community seems to want to take a different approach to concurrent data access.
An understanding of READ_ONCE() and WRITE_ONCE() is important for kernel developers who will be dealing with any sort of concurrent access to data. So, naturally, they are almost entirely absent from the kernel's documentation. A description of sorts can be found at the top of include/asm-generic/rwonce.h :
Prevent the compiler from merging or refetching reads or writes. The compiler is also forbidden from reordering successive instances of READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some particular ordering. One way to make the compiler aware of ordering is to put the two invocations of READ_ONCE or WRITE_ONCE in different C statements.
In other words, a READ_ONCE() call will force the compiler to read from the indicated location exactly one time, with no optimization tricks that would cause the read to be either elided or repeated; WRITE_ONCE() will force a write under those terms. They will also ensure that the access is atomic; if one task reads a location with READ_ONCE() while another is writing that location, the read will return the value as it existed either before or after the write, but not some random combination of the two. These macros, other than as described above, impose no ordering constraints on the compiler or the CPU, making them different from macros like smp_load_acquire() , which have stronger ordering requirements.
Nobody covers the Linux kernel like LWN; be in the know with a one-month trial subscription, no credit card needed.
The READ_ONCE() and WRITE_ONCE() macros were added for the 3.18 release in 2014. WRITE_ONCE() was initially called ASSIGN_ONCE() , but that name was changed during the 3.19 development cycle.
... continue reading