forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
7.3 KiB
178 lines
7.3 KiB
This document contains brief definitions of LKMM-related terms. Like most |
|
glossaries, it is not intended to be read front to back (except perhaps |
|
as a way of confirming a diagnosis of OCD), but rather to be searched |
|
for specific terms. |
|
|
|
|
|
Address Dependency: When the address of a later memory access is computed |
|
based on the value returned by an earlier load, an "address |
|
dependency" extends from that load extending to the later access. |
|
Address dependencies are quite common in RCU read-side critical |
|
sections: |
|
|
|
1 rcu_read_lock(); |
|
2 p = rcu_dereference(gp); |
|
3 do_something(p->a); |
|
4 rcu_read_unlock(); |
|
|
|
In this case, because the address of "p->a" on line 3 is computed |
|
from the value returned by the rcu_dereference() on line 2, the |
|
address dependency extends from that rcu_dereference() to that |
|
"p->a". In rare cases, optimizing compilers can destroy address |
|
dependencies. Please see Documentation/RCU/rcu_dereference.rst |
|
for more information. |
|
|
|
See also "Control Dependency" and "Data Dependency". |
|
|
|
Acquire: With respect to a lock, acquiring that lock, for example, |
|
using spin_lock(). With respect to a non-lock shared variable, |
|
a special operation that includes a load and which orders that |
|
load before later memory references running on that same CPU. |
|
An example special acquire operation is smp_load_acquire(), |
|
but atomic_read_acquire() and atomic_xchg_acquire() also include |
|
acquire loads. |
|
|
|
When an acquire load returns the value stored by a release store |
|
to that same variable, (in other words, the acquire load "reads |
|
from" the release store), then all operations preceding that |
|
store "happen before" any operations following that load acquire. |
|
|
|
See also "Happens-Before", "Reads-From", "Relaxed", and "Release". |
|
|
|
Coherence (co): When one CPU's store to a given variable overwrites |
|
either the value from another CPU's store or some later value, |
|
there is said to be a coherence link from the second CPU to |
|
the first. |
|
|
|
It is also possible to have a coherence link within a CPU, which |
|
is a "coherence internal" (coi) link. The term "coherence |
|
external" (coe) link is used when it is necessary to exclude |
|
the coi case. |
|
|
|
See also "From-reads" and "Reads-from". |
|
|
|
Control Dependency: When a later store's execution depends on a test |
|
of a value computed from a value returned by an earlier load, |
|
a "control dependency" extends from that load to that store. |
|
For example: |
|
|
|
1 if (READ_ONCE(x)) |
|
2 WRITE_ONCE(y, 1); |
|
|
|
Here, the control dependency extends from the READ_ONCE() on |
|
line 1 to the WRITE_ONCE() on line 2. Control dependencies are |
|
fragile, and can be easily destroyed by optimizing compilers. |
|
Please see control-dependencies.txt for more information. |
|
|
|
See also "Address Dependency" and "Data Dependency". |
|
|
|
Cycle: Memory-barrier pairing is restricted to a pair of CPUs, as the |
|
name suggests. And in a great many cases, a pair of CPUs is all |
|
that is required. In other cases, the notion of pairing must be |
|
extended to additional CPUs, and the result is called a "cycle". |
|
In a cycle, each CPU's ordering interacts with that of the next: |
|
|
|
CPU 0 CPU 1 CPU 2 |
|
WRITE_ONCE(x, 1); WRITE_ONCE(y, 1); WRITE_ONCE(z, 1); |
|
smp_mb(); smp_mb(); smp_mb(); |
|
r0 = READ_ONCE(y); r1 = READ_ONCE(z); r2 = READ_ONCE(x); |
|
|
|
CPU 0's smp_mb() interacts with that of CPU 1, which interacts |
|
with that of CPU 2, which in turn interacts with that of CPU 0 |
|
to complete the cycle. Because of the smp_mb() calls between |
|
each pair of memory accesses, the outcome where r0, r1, and r2 |
|
are all equal to zero is forbidden by LKMM. |
|
|
|
See also "Pairing". |
|
|
|
Data Dependency: When the data written by a later store is computed based |
|
on the value returned by an earlier load, a "data dependency" |
|
extends from that load to that later store. For example: |
|
|
|
1 r1 = READ_ONCE(x); |
|
2 WRITE_ONCE(y, r1 + 1); |
|
|
|
In this case, the data dependency extends from the READ_ONCE() |
|
on line 1 to the WRITE_ONCE() on line 2. Data dependencies are |
|
fragile and can be easily destroyed by optimizing compilers. |
|
Because optimizing compilers put a great deal of effort into |
|
working out what values integer variables might have, this is |
|
especially true in cases where the dependency is carried through |
|
an integer. |
|
|
|
See also "Address Dependency" and "Control Dependency". |
|
|
|
From-Reads (fr): When one CPU's store to a given variable happened |
|
too late to affect the value returned by another CPU's |
|
load from that same variable, there is said to be a from-reads |
|
link from the load to the store. |
|
|
|
It is also possible to have a from-reads link within a CPU, which |
|
is a "from-reads internal" (fri) link. The term "from-reads |
|
external" (fre) link is used when it is necessary to exclude |
|
the fri case. |
|
|
|
See also "Coherence" and "Reads-from". |
|
|
|
Fully Ordered: An operation such as smp_mb() that orders all of |
|
its CPU's prior accesses with all of that CPU's subsequent |
|
accesses, or a marked access such as atomic_add_return() |
|
that orders all of its CPU's prior accesses, itself, and |
|
all of its CPU's subsequent accesses. |
|
|
|
Happens-Before (hb): A relation between two accesses in which LKMM |
|
guarantees the first access precedes the second. For more |
|
detail, please see the "THE HAPPENS-BEFORE RELATION: hb" |
|
section of explanation.txt. |
|
|
|
Marked Access: An access to a variable that uses an special function or |
|
macro such as "r1 = READ_ONCE(x)" or "smp_store_release(&a, 1)". |
|
|
|
See also "Unmarked Access". |
|
|
|
Pairing: "Memory-barrier pairing" reflects the fact that synchronizing |
|
data between two CPUs requires that both CPUs their accesses. |
|
Memory barriers thus tend to come in pairs, one executed by |
|
one of the CPUs and the other by the other CPU. Of course, |
|
pairing also occurs with other types of operations, so that a |
|
smp_store_release() pairs with an smp_load_acquire() that reads |
|
the value stored. |
|
|
|
See also "Cycle". |
|
|
|
Reads-From (rf): When one CPU's load returns the value stored by some other |
|
CPU, there is said to be a reads-from link from the second |
|
CPU's store to the first CPU's load. Reads-from links have the |
|
nice property that time must advance from the store to the load, |
|
which means that algorithms using reads-from links can use lighter |
|
weight ordering and synchronization compared to algorithms using |
|
coherence and from-reads links. |
|
|
|
It is also possible to have a reads-from link within a CPU, which |
|
is a "reads-from internal" (rfi) link. The term "reads-from |
|
external" (rfe) link is used when it is necessary to exclude |
|
the rfi case. |
|
|
|
See also Coherence" and "From-reads". |
|
|
|
Relaxed: A marked access that does not imply ordering, for example, a |
|
READ_ONCE(), WRITE_ONCE(), a non-value-returning read-modify-write |
|
operation, or a value-returning read-modify-write operation whose |
|
name ends in "_relaxed". |
|
|
|
See also "Acquire" and "Release". |
|
|
|
Release: With respect to a lock, releasing that lock, for example, |
|
using spin_unlock(). With respect to a non-lock shared variable, |
|
a special operation that includes a store and which orders that |
|
store after earlier memory references that ran on that same CPU. |
|
An example special release store is smp_store_release(), but |
|
atomic_set_release() and atomic_cmpxchg_release() also include |
|
release stores. |
|
|
|
See also "Acquire" and "Relaxed". |
|
|
|
Unmarked Access: An access to a variable that uses normal C-language |
|
syntax, for example, "a = b[2]"; |
|
|
|
See also "Marked Access".
|
|
|