mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-23 07:23:12 +02:00
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:
commit
95bf3760eb
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
=======
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user