lkmm: Update documentation

Changes
 -------
 
 * Cross-references, typos, broken URLs (Akira Yokosawa)
 * Clarify SRCU explanation (Uladzislau Rezki)
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCgAxFiEEbK7UrM+RBIrCoViJnr8S83LZ+4wFAmgzV8QTHHBhdWxtY2tA
 a2VybmVsLm9yZwAKCRCevxLzctn7jMZkD/9aspJ+8yAQPVSGPSZNN6Z0524A/n4A
 FIFKbD1Rm0QGH4QxfK6qhh5L6IouMAJL1GT0Y7Wg5tq/WOUU+ALGuPEmoD9424RL
 BzDO8wSKlswLTzPQ1rkcDdGgbqMxP9CMU7AAxbWsH8qHG95VVwODpHjoidNTODFo
 jfCmsB4vNb+LkEP7Cw2BseRX3FHOoRoWmfKF20aHyXEkCTS6SaLHZ+JydLuqdVzG
 XflasW/5kCmfFjPVyT0ferrvc7adGQ4yGdwufIapM/LVurGmttnYL4w9eJSVAs1n
 tZ/6AEN18Lrnb5x78ZEZjm/CKHO03GZgJTSw8rs6voWRXbN1E89Rd4fyhZIgACPj
 tQkF34hNmNMQKyyab+tpCmLjrJTiWaYMp5TpQWhr2agvLZqJZf6i9oDsXTq/TArT
 uKgrrzjAVlUfX6fcJHASxyCjFoh4KYuAJVTHszzCvG5crp7Fg0Wz7q5D+oM7UDwZ
 jPdMgFMJXJTvFFxBzQTcoeDLI74cIpCzmj0dCZONUoliEISuSciz+Iyv3HzFtF9M
 vRp6PZBr9fT3YWqs6qwYkqT351+12uCigMei5kK/GkQkCDDvUk+dzv/BG9YUIeBb
 Xq3UDLeJ+ACtYJAn/MCQw01TXEe7uc54xGL+hgoxC642myM1Kvu1wd7le1kPt+cK
 djMqbbrrPAdpFg==
 =DRxd
 -----END PGP SIGNATURE-----

Merge tag 'lkmm.2025.05.25a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu

Pull lkmm updates from Paul McKenney:
 "Update LKMM documentation:

   - Cross-references, typos, broken URLs (Akira Yokosawa)

   - Clarify SRCU explanation (Uladzislau Rezki)"

* tag 'lkmm.2025.05.25a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu:
  tools/memory-model/Documentation: Fix SRCU section in explanation.txt
  tools/memory-model: docs/references: Remove broken link to imgtec.com
  tools/memory-model: docs/ordering: Fix trivial typos
  tools/memory-model: docs/simple.txt: Fix trivial typos
  tools/memory-model: docs/README: Update introduction of locking.txt
This commit is contained in:
Linus Torvalds 2025-05-27 11:17:45 -07:00
commit 95bf3760eb
7 changed files with 29 additions and 18 deletions

View File

@ -23,8 +23,11 @@ o You are familiar with the Linux-kernel concurrency primitives
that you need, and just want to get started with LKMM litmus
tests: litmus-tests.txt
o You would like to access lock-protected shared variables without
having their corresponding locks held: locking.txt
o You need to locklessly access shared variables that are otherwise
protected by a lock: locking.txt
This locking.txt file expands on the "Locking" section in
recipes.txt, but is self-contained.
o You are familiar with Linux-kernel concurrency, and would
like a detailed intuitive understanding of LKMM, including

View File

@ -1896,7 +1896,7 @@ following respects:
3. The srcu_down_read() and srcu_up_read() primitives work
exactly like srcu_read_lock() and srcu_read_unlock(), except
that matching calls don't have to execute on the same CPU.
that matching calls don't have to execute within the same context.
(The names are meant to be suggestive of operations on
semaphores.) Since the matching is determined by the domain
pointer and index value, these primitives make it possible for

View File

@ -1,3 +1,8 @@
[!] Note:
This file expands on the "Locking" section of recipes.txt,
focusing on locklessly accessing shared variables that are
otherwise protected by a lock.
Locking
=======

View File

@ -223,7 +223,7 @@ The Linux kernel's compiler barrier is barrier(). This primitive
prohibits compiler code-motion optimizations that might move memory
references across the point in the code containing the barrier(), but
does not constrain hardware memory ordering. For example, this can be
used to prevent to compiler from moving code across an infinite loop:
used to prevent the compiler from moving code across an infinite loop:
WRITE_ONCE(x, 1);
while (dontstop)
@ -274,7 +274,7 @@ different pieces of the concurrent algorithm. The variable stored to
by the smp_store_release(), in this case "y", will normally be used in
an acquire operation in other parts of the concurrent algorithm.
To see the performance advantages, suppose that the above example read
To see the performance advantages, suppose that the above example reads
from "x" instead of writing to it. Then an smp_wmb() could not guarantee
ordering, and an smp_mb() would be needed instead:
@ -394,17 +394,17 @@ from the value returned by the rcu_dereference() or srcu_dereference()
to that subsequent memory access.
A call to rcu_dereference() for a given RCU-protected pointer is
usually paired with a call to a call to rcu_assign_pointer() for that
same pointer in much the same way that a call to smp_load_acquire() is
paired with a call to smp_store_release(). Calls to rcu_dereference()
and rcu_assign_pointer are often buried in other APIs, for example,
usually paired with a call to rcu_assign_pointer() for that same pointer
in much the same way that a call to smp_load_acquire() is paired with
a call to smp_store_release(). Calls to rcu_dereference() and
rcu_assign_pointer() are often buried in other APIs, for example,
the RCU list API members defined in include/linux/rculist.h. For more
information, please see the docbook headers in that file, the most
recent LWN article on the RCU API (https://lwn.net/Articles/777036/),
recent LWN article on the RCU API (https://lwn.net/Articles/988638/),
and of course the material in Documentation/RCU.
If the pointer value is manipulated between the rcu_dereference()
that returned it and a later dereference(), please read
that returned it and a later rcu_dereference(), please read
Documentation/RCU/rcu_dereference.rst. It can also be quite helpful to
review uses in the Linux kernel.
@ -457,7 +457,7 @@ described earlier in this document.
These operations come in three categories:
o Marked writes, such as WRITE_ONCE() and atomic_set(). These
primitives required the compiler to emit the corresponding store
primitives require the compiler to emit the corresponding store
instructions in the expected execution order, thus suppressing
a number of destructive optimizations. However, they provide no
hardware ordering guarantees, and in fact many CPUs will happily
@ -465,7 +465,7 @@ o Marked writes, such as WRITE_ONCE() and atomic_set(). These
operations, unless these operations are to the same variable.
o Marked reads, such as READ_ONCE() and atomic_read(). These
primitives required the compiler to emit the corresponding load
primitives require the compiler to emit the corresponding load
instructions in the expected execution order, thus suppressing
a number of destructive optimizations. However, they provide no
hardware ordering guarantees, and in fact many CPUs will happily
@ -506,7 +506,7 @@ of the old value and the new value.
Unmarked C-language accesses are unordered, and are also subject to
any number of compiler optimizations, many of which can break your
concurrent code. It is possible to used unmarked C-language accesses for
concurrent code. It is possible to use unmarked C-language accesses for
shared variables that are subject to concurrent access, but great care
is required on an ongoing basis. The compiler-constraining barrier()
primitive can be helpful, as can the various ordering primitives discussed

View File

@ -61,6 +61,10 @@ usual) some things to be careful of:
Locking
-------
[!] Note:
locking.txt expands on this section, providing more detail on
locklessly accessing lock-protected shared variables.
Locking is well-known and straightforward, at least if you don't think
about it too hard. And the basic rule is indeed quite simple: Any CPU that
has acquired a given lock sees any changes previously seen or made by any

View File

@ -46,8 +46,7 @@ o ARM Ltd. (Ed.). 2014. "ARM Architecture Reference Manual (ARMv8,
o Imagination Technologies, LTD. 2015. "MIPS(R) Architecture
For Programmers, Volume II-A: The MIPS64(R) Instruction,
Set Reference Manual". Imagination Technologies,
LTD. https://imgtec.com/?do-download=4302.
Set Reference Manual". Imagination Technologies, LTD.
o Shaked Flur, Kathryn E. Gray, Christopher Pulte, Susmit
Sarkar, Ali Sezgin, Luc Maranget, Will Deacon, and Peter

View File

@ -134,7 +134,7 @@ Packaged primitives: Sequence locking
Lockless programming is considered by many to be more difficult than
lock-based programming, but there are a few lockless design patterns that
have been built out into an API. One of these APIs is sequence locking.
Although this APIs can be used in extremely complex ways, there are simple
Although this API can be used in extremely complex ways, there are simple
and effective ways of using it that avoid the need to pay attention to
memory ordering.
@ -205,7 +205,7 @@ If you want to keep things simple, use the initialization and read-out
operations from the previous section only when there are no racing
accesses. Otherwise, use only fully ordered operations when accessing
or modifying the variable. This approach guarantees that code prior
to a given access to that variable will be seen by all CPUs has having
to a given access to that variable will be seen by all CPUs as having
happened before any code following any later access to that same variable.
Please note that per-CPU functions are not atomic operations and