24

Can somebody explain the usage of WRITE_ONCE and READ_ONCE?

And internally WRITE_ONCE uses a volatile qualifier. Why?

How does WRITE_ONCE and READ_ONCE solve cache coherency problem?

Difference between *(volatile __u8_alias_t *) p and (volatile __u8_alias_t *) *p ?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Sai
  • 351
  • 2
  • 5
  • 12
    I suggest to read [Documentation/memory-barriers.txt](https://www.kernel.org/doc/Documentation/memory-barriers.txt). It contains also example of usage of such macros. These macros are actually compiler-only barriers, so they do nothing with "cache coherency". And difference between expressions is a type of `p` and of the result. This is completely unrelated to the other part of the question. (Prefer to ask a **single question** in the question post). – Tsyvarev May 29 '18 at 18:11
  • It's about consistency. Last question is obviously about *pointer to the data* vs. *data itself by given pointer*. – 0andriy May 29 '18 at 20:49
  • @Tsyvarev the question about cache coherency comes *from* memory-barriers.txt. – Michael Foukarakis May 30 '18 at 08:12
  • @MichaelFoukarakis: You, probably, mean phrase "READ_ONCE() and WRITE_ONCE() provide cache coherence for accesses from multiple CPUs to a single variable.". Not sure what this phrase actually means, implementation of `READ_ONCE` uses `smp_read_barrier_depends()` which is non-empty only on Alpha. Implementation of `WRITE_ONCE` doesn't use CPU barriers at all. – Tsyvarev May 30 '18 at 08:45
  • @Tsyvarev .....If the size of the accessed data type exceeds the "word size" of the machine (e.g., 32 bits or 64 bits) READ_ONCE() and WRITE_ONCE() will fall back to memcpy and print a compile-time warning. memcpy is wrapped around barrier. – RaGa__M Apr 03 '19 at 12:14
  • @Explorer_N: According to the implementation (in [include/linux/compiler.h](https://elixir.bootlin.com/linux/v5.0.5/source/include/linux/compiler.h)), `__read_once_size` and `__read_once_size` actually use `memcpy` as a fallback, but that `memcpy` is wrapped with `barrier()` calls. That calls provide **compiler barrier** only and has nothing common with the processor's cache coherency. – Tsyvarev Apr 03 '19 at 13:17
  • Linux runs on machines with coherent shared memory. Therefore `volatile` is about equivalent to `atomic_load_explicit(&var, memory_order_relaxed)`. See my answer on [When to use volatile with multi threading?](https://stackoverflow.com/a/58535118) – Peter Cordes Jun 29 '20 at 06:04
  • Does this answer your question? [When to use volatile with multi threading?](https://stackoverflow.com/questions/4557979/when-to-use-volatile-with-multi-threading) – Peter Cordes Jun 29 '20 at 06:04

0 Answers0