diff options
Diffstat (limited to 'Documentation/RCU/lockdep.txt')
| -rw-r--r-- | Documentation/RCU/lockdep.txt | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/Documentation/RCU/lockdep.txt b/Documentation/RCU/lockdep.txt index fe24b58627bd..d7a49b2f6994 100644 --- a/Documentation/RCU/lockdep.txt +++ b/Documentation/RCU/lockdep.txt | |||
| @@ -32,9 +32,20 @@ checking of rcu_dereference() primitives: | |||
| 32 | srcu_dereference(p, sp): | 32 | srcu_dereference(p, sp): |
| 33 | Check for SRCU read-side critical section. | 33 | Check for SRCU read-side critical section. |
| 34 | rcu_dereference_check(p, c): | 34 | rcu_dereference_check(p, c): |
| 35 | Use explicit check expression "c". | 35 | Use explicit check expression "c". This is useful in |
| 36 | code that is invoked by both readers and updaters. | ||
| 36 | rcu_dereference_raw(p) | 37 | rcu_dereference_raw(p) |
| 37 | Don't check. (Use sparingly, if at all.) | 38 | Don't check. (Use sparingly, if at all.) |
| 39 | rcu_dereference_protected(p, c): | ||
| 40 | Use explicit check expression "c", and omit all barriers | ||
| 41 | and compiler constraints. This is useful when the data | ||
| 42 | structure cannot change, for example, in code that is | ||
| 43 | invoked only by updaters. | ||
| 44 | rcu_access_pointer(p): | ||
| 45 | Return the value of the pointer and omit all barriers, | ||
| 46 | but retain the compiler constraints that prevent duplicating | ||
| 47 | or coalescsing. This is useful when when testing the | ||
| 48 | value of the pointer itself, for example, against NULL. | ||
| 38 | 49 | ||
| 39 | The rcu_dereference_check() check expression can be any boolean | 50 | The rcu_dereference_check() check expression can be any boolean |
| 40 | expression, but would normally include one of the rcu_read_lock_held() | 51 | expression, but would normally include one of the rcu_read_lock_held() |
| @@ -59,7 +70,20 @@ In case (1), the pointer is picked up in an RCU-safe manner for vanilla | |||
| 59 | RCU read-side critical sections, in case (2) the ->file_lock prevents | 70 | RCU read-side critical sections, in case (2) the ->file_lock prevents |
| 60 | any change from taking place, and finally, in case (3) the current task | 71 | any change from taking place, and finally, in case (3) the current task |
| 61 | is the only task accessing the file_struct, again preventing any change | 72 | is the only task accessing the file_struct, again preventing any change |
| 62 | from taking place. | 73 | from taking place. If the above statement was invoked only from updater |
| 74 | code, it could instead be written as follows: | ||
| 75 | |||
| 76 | file = rcu_dereference_protected(fdt->fd[fd], | ||
| 77 | lockdep_is_held(&files->file_lock) || | ||
| 78 | atomic_read(&files->count) == 1); | ||
| 79 | |||
| 80 | This would verify cases #2 and #3 above, and furthermore lockdep would | ||
| 81 | complain if this was used in an RCU read-side critical section unless one | ||
| 82 | of these two cases held. Because rcu_dereference_protected() omits all | ||
| 83 | barriers and compiler constraints, it generates better code than do the | ||
| 84 | other flavors of rcu_dereference(). On the other hand, it is illegal | ||
| 85 | to use rcu_dereference_protected() if either the RCU-protected pointer | ||
| 86 | or the RCU-protected data that it points to can change concurrently. | ||
| 63 | 87 | ||
| 64 | There are currently only "universal" versions of the rcu_assign_pointer() | 88 | There are currently only "universal" versions of the rcu_assign_pointer() |
| 65 | and RCU list-/tree-traversal primitives, which do not (yet) check for | 89 | and RCU list-/tree-traversal primitives, which do not (yet) check for |
