···101011113. Resizeable Arrays12121313-Each of these situations are discussed below.1313+Each of these three situations involves an RCU-protected pointer to an1414+array that is separately indexed. It might be tempting to consider use1515+of RCU to instead protect the index into an array, however, this use1616+case is -not- supported. The problem with RCU-protected indexes into1717+arrays is that compilers can play way too many optimization games with1818+integers, which means that the rules governing handling of these indexes1919+are far more trouble than they are worth. If RCU-protected indexes into2020+arrays prove to be particularly valuable (which they have not thus far),2121+explicit cooperation from the compiler will be required to permit them2222+to be safely used.2323+2424+That aside, each of the three RCU-protected pointer situations are2525+described in the following sections.142615271628Situation 1: Hash Tables···4836Situation 3: Resizeable Arrays49375038Use of RCU for resizeable arrays is demonstrated by the grow_ary()5151-function used by the System V IPC code. The array is used to map from5252-semaphore, message-queue, and shared-memory IDs to the data structure5353-that represents the corresponding IPC construct. The grow_ary()3939+function formerly used by the System V IPC code. The array is used4040+to map from semaphore, message-queue, and shared-memory IDs to the data4141+structure that represents the corresponding IPC construct. The grow_ary()5442function does not acquire any locks; instead its caller must hold the5543ids->sem semaphore.5644
-10
Documentation/RCU/lockdep.txt
···4747 Use explicit check expression "c" along with4848 srcu_read_lock_held()(). This is useful in code that4949 is invoked by both SRCU readers and updaters.5050- rcu_dereference_index_check(p, c):5151- Use explicit check expression "c", but the caller5252- must supply one of the rcu_read_lock_held() functions.5353- This is useful in code that uses RCU-protected arrays5454- that is invoked by both RCU readers and updaters.5550 rcu_dereference_raw(p):5651 Don't check. (Use sparingly, if at all.)5752 rcu_dereference_protected(p, c):···5964 but retain the compiler constraints that prevent duplicating6065 or coalescsing. This is useful when when testing the6166 value of the pointer itself, for example, against NULL.6262- rcu_access_index(idx):6363- Return the value of the index and omit all barriers, but6464- retain the compiler constraints that prevent duplicating6565- or coalescsing. This is useful when when testing the6666- value of the index itself, for example, against -1.67676868The rcu_dereference_check() check expression can be any boolean6969expression, but would normally include a lockdep expression. However,
+12-21
Documentation/RCU/rcu_dereference.txt
···2525 for an example where the compiler can in fact deduce the exact2626 value of the pointer, and thus cause misordering.27272828-o Do not use single-element RCU-protected arrays. The compiler2929- is within its right to assume that the value of an index into3030- such an array must necessarily evaluate to zero. The compiler3131- could then substitute the constant zero for the computation, so3232- that the array index no longer depended on the value returned3333- by rcu_dereference(). If the array index no longer depends3434- on rcu_dereference(), then both the compiler and the CPU3535- are within their rights to order the array access before the3636- rcu_dereference(), which can cause the array access to return3737- garbage.3838-3928o Avoid cancellation when using the "+" and "-" infix arithmetic4029 operators. For example, for a given variable "x", avoid4130 "(x-x)". There are similar arithmetic pitfalls from other···6576 dereferencing. For example, the following (rather improbable)6677 code is buggy:67786868- int a[2];6969- int index;7070- int force_zero_index = 1;7979+ int *p;8080+ int *q;71817282 ...73837474- r1 = rcu_dereference(i1)7575- r2 = a[r1 && force_zero_index]; /* BUGGY!!! */8484+ p = rcu_dereference(gp)8585+ q = &global_q;8686+ q += p != &oom_p1 && p != &oom_p2;8787+ r1 = *q; /* BUGGY!!! */76887789 The reason this is buggy is that "&&" and "||" are often compiled7890 using branches. While weak-memory machines such as ARM or PowerPC···8494 ">", ">=", "<", or "<=") when dereferencing. For example,8595 the following (quite strange) code is buggy:86968787- int a[2];8888- int index;8989- int flip_index = 0;9797+ int *p;9898+ int *q;909991100 ...921019393- r1 = rcu_dereference(i1)9494- r2 = a[r1 != flip_index]; /* BUGGY!!! */102102+ p = rcu_dereference(gp)103103+ q = &global_q;104104+ q += p > &oom_p;105105+ r1 = *q; /* BUGGY!!! */9510696107 As before, the reason this is buggy is that relational operators97108 are often compiled using branches. And as before, although