|
@@ -25,17 +25,6 @@ o You must use one of the rcu_dereference() family of primitives
|
|
for an example where the compiler can in fact deduce the exact
|
|
for an example where the compiler can in fact deduce the exact
|
|
value of the pointer, and thus cause misordering.
|
|
value of the pointer, and thus cause misordering.
|
|
|
|
|
|
-o Do not use single-element RCU-protected arrays. The compiler
|
|
|
|
- is within its right to assume that the value of an index into
|
|
|
|
- such an array must necessarily evaluate to zero. The compiler
|
|
|
|
- could then substitute the constant zero for the computation, so
|
|
|
|
- that the array index no longer depended on the value returned
|
|
|
|
- by rcu_dereference(). If the array index no longer depends
|
|
|
|
- on rcu_dereference(), then both the compiler and the CPU
|
|
|
|
- are within their rights to order the array access before the
|
|
|
|
- rcu_dereference(), which can cause the array access to return
|
|
|
|
- garbage.
|
|
|
|
-
|
|
|
|
o Avoid cancellation when using the "+" and "-" infix arithmetic
|
|
o Avoid cancellation when using the "+" and "-" infix arithmetic
|
|
operators. For example, for a given variable "x", avoid
|
|
operators. For example, for a given variable "x", avoid
|
|
"(x-x)". There are similar arithmetic pitfalls from other
|
|
"(x-x)". There are similar arithmetic pitfalls from other
|
|
@@ -76,14 +65,15 @@ o Do not use the results from the boolean "&&" and "||" when
|
|
dereferencing. For example, the following (rather improbable)
|
|
dereferencing. For example, the following (rather improbable)
|
|
code is buggy:
|
|
code is buggy:
|
|
|
|
|
|
- int a[2];
|
|
|
|
- int index;
|
|
|
|
- int force_zero_index = 1;
|
|
|
|
|
|
+ int *p;
|
|
|
|
+ int *q;
|
|
|
|
|
|
...
|
|
...
|
|
|
|
|
|
- r1 = rcu_dereference(i1)
|
|
|
|
- r2 = a[r1 && force_zero_index]; /* BUGGY!!! */
|
|
|
|
|
|
+ p = rcu_dereference(gp)
|
|
|
|
+ q = &global_q;
|
|
|
|
+ q += p != &oom_p1 && p != &oom_p2;
|
|
|
|
+ r1 = *q; /* BUGGY!!! */
|
|
|
|
|
|
The reason this is buggy is that "&&" and "||" are often compiled
|
|
The reason this is buggy is that "&&" and "||" are often compiled
|
|
using branches. While weak-memory machines such as ARM or PowerPC
|
|
using branches. While weak-memory machines such as ARM or PowerPC
|
|
@@ -94,14 +84,15 @@ o Do not use the results from relational operators ("==", "!=",
|
|
">", ">=", "<", or "<=") when dereferencing. For example,
|
|
">", ">=", "<", or "<=") when dereferencing. For example,
|
|
the following (quite strange) code is buggy:
|
|
the following (quite strange) code is buggy:
|
|
|
|
|
|
- int a[2];
|
|
|
|
- int index;
|
|
|
|
- int flip_index = 0;
|
|
|
|
|
|
+ int *p;
|
|
|
|
+ int *q;
|
|
|
|
|
|
...
|
|
...
|
|
|
|
|
|
- r1 = rcu_dereference(i1)
|
|
|
|
- r2 = a[r1 != flip_index]; /* BUGGY!!! */
|
|
|
|
|
|
+ p = rcu_dereference(gp)
|
|
|
|
+ q = &global_q;
|
|
|
|
+ q += p > &oom_p;
|
|
|
|
+ r1 = *q; /* BUGGY!!! */
|
|
|
|
|
|
As before, the reason this is buggy is that relational operators
|
|
As before, the reason this is buggy is that relational operators
|
|
are often compiled using branches. And as before, although
|
|
are often compiled using branches. And as before, although
|