Documentation updates for 3.19
cover Documentation updates for 3.19
Hello!
This series contains a few documentation updates:
1. Records limitations of bitfields and small variables.
Also rules out pre-EV56 Alpha, which lack 8- and 16-bit memory-reference instructions. Later Alpha CPUs are OK. (The official Alpha maintainers have thus far been silent on this patch.)
2. Document the new RCU self-test boot parameters, courtesy of
Pranith Kumar.
3. Records that short-circuit boolean evaluation does not necessarily
defend against control-dependency breakage by compiler optimizations.
4. Add mention of atomic_long_t to atomic_ops.txt.
5. Fix an example in memory-barriers.txt, courtesy of Pranith Kumar.
Thanx, Paul
------------------------------------------------------------------------
b/Documentation/atomic_ops.txt | 12 +++-- b/Documentation/kernel-parameters.txt | 9 ++++ b/Documentation/memory-barriers.txt | 71 ++++++++++++++++++++++++++++------ 3 files changed, 77 insertions(+), 15 deletions(-)
PATCH 1/5 documentation: Record limitations of bitfields and small variables
From: "Paul E. McKenney" <[email protected]>
This commit documents the fact that it is not safe to use bitfields as shared variables in synchronization algorithms. It also documents that CPUs must provide one-byte and two-byte normal load and store instructions in order to be supported by the Linux kernel. (Michael Cree has agreed to the resulting non-support of pre-EV56 Alpha CPUs:
https://lkml.org/lkml/2014/9/5/143.)
--- Documentation/memory-barriers.txt | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
Documentation/memory-barriers.txt +31 -0
@@ -269,6 +269,37 @@ And there are a number of things that _must_ or _must_not_ be assumed: STORE *(A + 4) = Y; STORE *A = X; STORE {*A, *(A + 4) } = {X, Y}; +And there are anti-guarantees: + + (*) These guarantees do not apply to bitfields, because compilers often + generate code to modify these using non-atomic read-modify-write + sequences. Do not attempt to use bitfields to synchronize parallel + algorithms. + + (*) Even in cases where bitfields are protected by locks, all fields + in a given bitfield must be protected by one lock. If two fields + in a given bitfield are protected by different locks, the compiler's + non-atomic read-modify-write sequences can cause an update to one + field to corrupt the value of an adjacent field. + + (*) These guarantees apply only to properly aligned and sized scalar + variables. "Properly sized" currently means variables that are + the same size as "char", "short", "int" and "long". "Properly + aligned" means the natural alignment, thus no constraints for + "char", two-byte alignment for "short", four-byte alignment for + "int", and either four-byte or eight-byte alignment for "long", + on 32-bit and 64-bit systems, respectively. Note that this means + that the Linux kernel does not support pre-EV56 Alpha CPUs, + because these older CPUs do not provide one-byte and two-byte + load and store instructions. (In theory, the pre-EV56 Alpha CPUs + can emulate these instructions using load-linked/store-conditional + instructions, but in practice this approach has excessive overhead. + Keep in mind that this emulation would be required on -all- single- + and double-byte loads and stores in order to handle adjacent bytes + protected by different locks.) + + Alpha EV56 and later Alpha CPUs are still supported. + ========================= WHAT ARE MEMORY BARRIERS?
Signature · 1 line
1.8.1.5
PATCH 2/5 documentation: Document RCU self test boot params
From: Pranith Kumar <[email protected]>
Document the RCU self test boot parameters in kernel-parameters.txt.
--- Documentation/kernel-parameters.txt | 9 +++++++++ 1 file changed, 9 insertions(+)
Documentation/kernel-parameters.txt +9 -0
@@ -3071,6 +3071,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted. messages. Disable with a value less than or equal to zero. + rcupdate.rcu_self_test= [KNL] + Run the RCU early boot self tests + + rcupdate.rcu_self_test_bh= [KNL] + Run the RCU bh early boot self tests + + rcupdate.rcu_self_test_sched= [KNL] + Run the RCU sched early boot self tests + rdinit= [KNL] Format: <full_path> Run specified binary instead of /init from the ramdisk,
Signature · 1 line
1.8.1.5
PATCH 3/5 documentation: Additional restriction for control dependencies
In reply to Paul E. McKenneyFrom: "Paul E. McKenney" <[email protected]>
Short-circuit booleans are not defences against compilers breaking your intended control dependencies.
--- Documentation/memory-barriers.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
Documentation/memory-barriers.txt +18 -0
@@ -725,6 +725,24 @@ Please note once again that the stores to 'b' differ. If they were identical, as noted earlier, the compiler could pull this store outside of the 'if' statement. +You must also be careful not to rely too much on boolean short-circuit +evaluation. Consider this example: + + q = ACCESS_ONCE(a); + if (a || 1 > 0) + ACCESS_ONCE(b) = 1; + +Because the second condition is always true, the compiler can transform +this example as following, defeating control dependency: + + q = ACCESS_ONCE(a); + ACCESS_ONCE(b) = 1; + +This example underscores the need to ensure that the compiler cannot +out-guess your code. More generally, although ACCESS_ONCE() does force +the compiler to actually emit code for a given load, it does not force +the compiler to use the results. + Finally, control dependencies do -not- provide transitivity. This is demonstrated by two related examples, with the initial values of x and y both being zero:
Signature · 1 line
1.8.1.5
PATCH 4/5 documentation: Add atomic_long_t to atomic_ops.txt
In reply to Paul E. McKenneyFrom: "Paul E. McKenney" <[email protected]>
--- Documentation/atomic_ops.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
Documentation/atomic_ops.txt +8 -4
@@ -7,12 +7,13 @@ maintainers on how to implement atomic counter, bitops, and spinlock interfaces properly. - The atomic_t type should be defined as a signed integer. -Also, it should be made opaque such that any kind of cast to a normal -C integer type will fail. Something like the following should -suffice: + The atomic_t type should be defined as a signed integer and +the atomic_long_t type as a signed long integer. Also, they should +be made opaque such that any kind of cast to a normal C integer type +will fail. Something like the following should suffice: typedef struct { int counter; } atomic_t; + typedef struct { long counter; } atomic_long_t; Historically, counter has been declared volatile. This is now discouraged. See Documentation/volatile-considered-harmful.txt for the complete rationale.
@@ -37,6 +38,9 @@ initializer is used before runtime. If the initializer is used at runtime, a proper implicit or explicit read memory barrier is needed before reading the value with atomic_read from another thread. +As with all of the atomic_ interfaces, replace the leading "atomic_" +with "atomic_long_" to operate on atomic_long_t. + The second interface can be used at runtime, as in: struct foo { atomic_t counter; };
Signature · 1 line
1.8.1.5
PATCH 5/5 documentation: memory-barriers.txt: Correct example for reorderings
In reply to Paul E. McKenneyFrom: Pranith Kumar <[email protected]>
Correct the example of memory orderings in memory-barriers.txt
Commit 615cc2c9cf95 "Documentation/memory-barriers.txt: fix important typo re memory barriers" changed the assignment to x and y. Change the rest of the example to match this change.
--- Documentation/memory-barriers.txt | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
Documentation/memory-barriers.txt +11 -11
@@ -121,22 +121,22 @@ For example, consider the following sequence of events: The set of accesses as seen by the memory system in the middle can be arranged in 24 different combinations: - STORE A=3, STORE B=4, x=LOAD A->3, y=LOAD B->4 - STORE A=3, STORE B=4, y=LOAD B->4, x=LOAD A->3 - STORE A=3, x=LOAD A->3, STORE B=4, y=LOAD B->4 - STORE A=3, x=LOAD A->3, y=LOAD B->2, STORE B=4 - STORE A=3, y=LOAD B->2, STORE B=4, x=LOAD A->3 - STORE A=3, y=LOAD B->2, x=LOAD A->3, STORE B=4 - STORE B=4, STORE A=3, x=LOAD A->3, y=LOAD B->4 + STORE A=3, STORE B=4, y=LOAD A->3, x=LOAD B->4 + STORE A=3, STORE B=4, x=LOAD B->4, y=LOAD A->3 + STORE A=3, y=LOAD A->3, STORE B=4, x=LOAD B->4 + STORE A=3, y=LOAD A->3, x=LOAD B->2, STORE B=4 + STORE A=3, x=LOAD B->2, STORE B=4, y=LOAD A->3 + STORE A=3, x=LOAD B->2, y=LOAD A->3, STORE B=4 + STORE B=4, STORE A=3, y=LOAD A->3, x=LOAD B->4 STORE B=4, ... ... and can thus result in four different combinations of values: - x == 1, y == 2 - x == 1, y == 4 - x == 3, y == 2 - x == 3, y == 4 + x == 2, y == 1 + x == 2, y == 3 + x == 4, y == 1 + x == 4, y == 3 Furthermore, the stores committed by a CPU to the memory system may not be
Signature · 1 line
1.8.1.5
Quoted 13 lines · Paul E. McKenney
Hello!
This series contains a few documentation updates:
1. Records limitations of bitfields and small variables.
Also rules out pre-EV56 Alpha, which lack 8- and 16-bit memory-reference instructions. Later Alpha CPUs are OK. (The official Alpha maintainers have thus far been silent on this patch.)2. Document the new RCU self-test boot parameters, courtesy of
Pranith Kumar.
Quoted 6 lines
3. Records that short-circuit boolean evaluation does not necessarily
defend against control-dependency breakage by compiler optimizations.4. Add mention of
atomic_long_tto atomic_ops.txt.5. Fix an example in memory-barriers.txt, courtesy of Pranith Kumar.
Quoted 10 lines
Thanx, Paul
------------------------------------------------------------------------
b/Documentation/atomic_ops.txt | 12 +++-- b/Documentation/kernel-parameters.txt | 9 ++++ b/Documentation/memory-barriers.txt | 71 ++++++++++++++++++++++++++++------ 3 files changed, 77 insertions(+), 15 deletions(-)
Signature · 1 line
Pranith