diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-04-20 09:09:27 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-05-27 15:56:17 -0400 |
commit | cf9fbf8017e2ab5cb33b6602b626f7f005718124 (patch) | |
tree | ca2ca92b0454c408c420fd9f744975eb08b3b9eb | |
parent | 1ebee8017d84ec8a0ba893cf7b8be3f70ead088b (diff) |
documentation: RCU-protected array indexes no longer supported
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r-- | Documentation/RCU/arrayRCU.txt | 20 | ||||
-rw-r--r-- | Documentation/RCU/lockdep.txt | 10 | ||||
-rw-r--r-- | Documentation/RCU/rcu_dereference.txt | 33 | ||||
-rw-r--r-- | Documentation/RCU/whatisRCU.txt | 2 |
4 files changed, 28 insertions, 37 deletions
diff --git a/Documentation/RCU/arrayRCU.txt b/Documentation/RCU/arrayRCU.txt index 453ebe6953ee..f05a9afb2c39 100644 --- a/Documentation/RCU/arrayRCU.txt +++ b/Documentation/RCU/arrayRCU.txt | |||
@@ -10,7 +10,19 @@ also be used to protect arrays. Three situations are as follows: | |||
10 | 10 | ||
11 | 3. Resizeable Arrays | 11 | 3. Resizeable Arrays |
12 | 12 | ||
13 | Each of these situations are discussed below. | 13 | Each of these three situations involves an RCU-protected pointer to an |
14 | array that is separately indexed. It might be tempting to consider use | ||
15 | of RCU to instead protect the index into an array, however, this use | ||
16 | case is -not- supported. The problem with RCU-protected indexes into | ||
17 | arrays is that compilers can play way too many optimization games with | ||
18 | integers, which means that the rules governing handling of these indexes | ||
19 | are far more trouble than they are worth. If RCU-protected indexes into | ||
20 | arrays prove to be particularly valuable (which they have not thus far), | ||
21 | explicit cooperation from the compiler will be required to permit them | ||
22 | to be safely used. | ||
23 | |||
24 | That aside, each of the three RCU-protected pointer situations are | ||
25 | described in the following sections. | ||
14 | 26 | ||
15 | 27 | ||
16 | Situation 1: Hash Tables | 28 | Situation 1: Hash Tables |
@@ -36,9 +48,9 @@ Quick Quiz: Why is it so important that updates be rare when | |||
36 | Situation 3: Resizeable Arrays | 48 | Situation 3: Resizeable Arrays |
37 | 49 | ||
38 | Use of RCU for resizeable arrays is demonstrated by the grow_ary() | 50 | Use of RCU for resizeable arrays is demonstrated by the grow_ary() |
39 | function used by the System V IPC code. The array is used to map from | 51 | function formerly used by the System V IPC code. The array is used |
40 | semaphore, message-queue, and shared-memory IDs to the data structure | 52 | to map from semaphore, message-queue, and shared-memory IDs to the data |
41 | that represents the corresponding IPC construct. The grow_ary() | 53 | structure that represents the corresponding IPC construct. The grow_ary() |
42 | function does not acquire any locks; instead its caller must hold the | 54 | function does not acquire any locks; instead its caller must hold the |
43 | ids->sem semaphore. | 55 | ids->sem semaphore. |
44 | 56 | ||
diff --git a/Documentation/RCU/lockdep.txt b/Documentation/RCU/lockdep.txt index cd83d2348fef..da51d3068850 100644 --- a/Documentation/RCU/lockdep.txt +++ b/Documentation/RCU/lockdep.txt | |||
@@ -47,11 +47,6 @@ checking of rcu_dereference() primitives: | |||
47 | Use explicit check expression "c" along with | 47 | Use explicit check expression "c" along with |
48 | srcu_read_lock_held()(). This is useful in code that | 48 | srcu_read_lock_held()(). This is useful in code that |
49 | is invoked by both SRCU readers and updaters. | 49 | is invoked by both SRCU readers and updaters. |
50 | rcu_dereference_index_check(p, c): | ||
51 | Use explicit check expression "c", but the caller | ||
52 | must supply one of the rcu_read_lock_held() functions. | ||
53 | This is useful in code that uses RCU-protected arrays | ||
54 | that is invoked by both RCU readers and updaters. | ||
55 | rcu_dereference_raw(p): | 50 | rcu_dereference_raw(p): |
56 | Don't check. (Use sparingly, if at all.) | 51 | Don't check. (Use sparingly, if at all.) |
57 | rcu_dereference_protected(p, c): | 52 | rcu_dereference_protected(p, c): |
@@ -64,11 +59,6 @@ checking of rcu_dereference() primitives: | |||
64 | but retain the compiler constraints that prevent duplicating | 59 | but retain the compiler constraints that prevent duplicating |
65 | or coalescsing. This is useful when when testing the | 60 | or coalescsing. This is useful when when testing the |
66 | value of the pointer itself, for example, against NULL. | 61 | value of the pointer itself, for example, against NULL. |
67 | rcu_access_index(idx): | ||
68 | Return the value of the index and omit all barriers, but | ||
69 | retain the compiler constraints that prevent duplicating | ||
70 | or coalescsing. This is useful when when testing the | ||
71 | value of the index itself, for example, against -1. | ||
72 | 62 | ||
73 | The rcu_dereference_check() check expression can be any boolean | 63 | The rcu_dereference_check() check expression can be any boolean |
74 | expression, but would normally include a lockdep expression. However, | 64 | expression, but would normally include a lockdep expression. However, |
diff --git a/Documentation/RCU/rcu_dereference.txt b/Documentation/RCU/rcu_dereference.txt index ceb05da5a5ac..66864d2a7f60 100644 --- a/Documentation/RCU/rcu_dereference.txt +++ b/Documentation/RCU/rcu_dereference.txt | |||
@@ -25,17 +25,6 @@ o You must use one of the rcu_dereference() family of primitives | |||
25 | for an example where the compiler can in fact deduce the exact | 25 | for an example where the compiler can in fact deduce the exact |
26 | value of the pointer, and thus cause misordering. | 26 | value of the pointer, and thus cause misordering. |
27 | 27 | ||
28 | o Do not use single-element RCU-protected arrays. The compiler | ||
29 | is within its right to assume that the value of an index into | ||
30 | such an array must necessarily evaluate to zero. The compiler | ||
31 | could then substitute the constant zero for the computation, so | ||
32 | that the array index no longer depended on the value returned | ||
33 | by rcu_dereference(). If the array index no longer depends | ||
34 | on rcu_dereference(), then both the compiler and the CPU | ||
35 | are within their rights to order the array access before the | ||
36 | rcu_dereference(), which can cause the array access to return | ||
37 | garbage. | ||
38 | |||
39 | o Avoid cancellation when using the "+" and "-" infix arithmetic | 28 | o Avoid cancellation when using the "+" and "-" infix arithmetic |
40 | operators. For example, for a given variable "x", avoid | 29 | operators. For example, for a given variable "x", avoid |
41 | "(x-x)". There are similar arithmetic pitfalls from other | 30 | "(x-x)". There are similar arithmetic pitfalls from other |
@@ -76,14 +65,15 @@ o Do not use the results from the boolean "&&" and "||" when | |||
76 | dereferencing. For example, the following (rather improbable) | 65 | dereferencing. For example, the following (rather improbable) |
77 | code is buggy: | 66 | code is buggy: |
78 | 67 | ||
79 | int a[2]; | 68 | int *p; |
80 | int index; | 69 | int *q; |
81 | int force_zero_index = 1; | ||
82 | 70 | ||
83 | ... | 71 | ... |
84 | 72 | ||
85 | r1 = rcu_dereference(i1) | 73 | p = rcu_dereference(gp) |
86 | r2 = a[r1 && force_zero_index]; /* BUGGY!!! */ | 74 | q = &global_q; |
75 | q += p != &oom_p1 && p != &oom_p2; | ||
76 | r1 = *q; /* BUGGY!!! */ | ||
87 | 77 | ||
88 | The reason this is buggy is that "&&" and "||" are often compiled | 78 | The reason this is buggy is that "&&" and "||" are often compiled |
89 | using branches. While weak-memory machines such as ARM or PowerPC | 79 | using branches. While weak-memory machines such as ARM or PowerPC |
@@ -94,14 +84,15 @@ o Do not use the results from relational operators ("==", "!=", | |||
94 | ">", ">=", "<", or "<=") when dereferencing. For example, | 84 | ">", ">=", "<", or "<=") when dereferencing. For example, |
95 | the following (quite strange) code is buggy: | 85 | the following (quite strange) code is buggy: |
96 | 86 | ||
97 | int a[2]; | 87 | int *p; |
98 | int index; | 88 | int *q; |
99 | int flip_index = 0; | ||
100 | 89 | ||
101 | ... | 90 | ... |
102 | 91 | ||
103 | r1 = rcu_dereference(i1) | 92 | p = rcu_dereference(gp) |
104 | r2 = a[r1 != flip_index]; /* BUGGY!!! */ | 93 | q = &global_q; |
94 | q += p > &oom_p; | ||
95 | r1 = *q; /* BUGGY!!! */ | ||
105 | 96 | ||
106 | As before, the reason this is buggy is that relational operators | 97 | As before, the reason this is buggy is that relational operators |
107 | are often compiled using branches. And as before, although | 98 | are often compiled using branches. And as before, although |
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index 88dfce182f66..b201d4cd77f9 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt | |||
@@ -879,9 +879,7 @@ SRCU: Initialization/cleanup | |||
879 | 879 | ||
880 | All: lockdep-checked RCU-protected pointer access | 880 | All: lockdep-checked RCU-protected pointer access |
881 | 881 | ||
882 | rcu_access_index | ||
883 | rcu_access_pointer | 882 | rcu_access_pointer |
884 | rcu_dereference_index_check | ||
885 | rcu_dereference_raw | 883 | rcu_dereference_raw |
886 | rcu_lockdep_assert | 884 | rcu_lockdep_assert |
887 | rcu_sleep_check | 885 | rcu_sleep_check |