diff options
author | Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | 2010-04-17 08:48:42 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2010-06-14 19:37:26 -0400 |
commit | 551d55a944b143ef26fbd482d1c463199d6f65cf (patch) | |
tree | 6911d3f8e8719ba5ca43c83acdf87cbc8276d7d1 /kernel/rcutiny.c | |
parent | 875352c94224c88f5aa28cb77206f993bd31b7a2 (diff) |
tree/tiny rcu: Add debug RCU head objects
Helps finding racy users of call_rcu(), which results in hangs because list
entries are overwritten and/or skipped.
Changelog since v4:
- Bissectability is now OK
- Now generate a WARN_ON_ONCE() for non-initialized rcu_head passed to
call_rcu(). Statically initialized objects are detected with
object_is_static().
- Rename rcu_head_init_on_stack to init_rcu_head_on_stack.
- Remove init_rcu_head() completely.
Changelog since v3:
- Include comments from Lai Jiangshan
This new patch version is based on the debugobjects with the newly introduced
"active state" tracker.
Non-initialized entries are all considered as "statically initialized". An
activation fixup (triggered by call_rcu()) takes care of performing the debug
object initialization without issuing any warning. Since we cannot increase the
size of struct rcu_head, I don't see much room to put an identifier for
statically initialized rcu_head structures. So for now, we have to live without
"activation without explicit init" detection. But the main purpose of this debug
option is to detect double-activations (double call_rcu() use of a rcu_head
before the callback is executed), which is correctly addressed here.
This also detects potential internal RCU callback corruption, which would cause
the callbacks to be executed twice.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
CC: David S. Miller <davem@davemloft.net>
CC: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
CC: akpm@linux-foundation.org
CC: mingo@elte.hu
CC: laijs@cn.fujitsu.com
CC: dipankar@in.ibm.com
CC: josh@joshtriplett.org
CC: dvhltc@us.ibm.com
CC: niv@us.ibm.com
CC: tglx@linutronix.de
CC: peterz@infradead.org
CC: rostedt@goodmis.org
CC: Valdis.Kletnieks@vt.edu
CC: dhowells@redhat.com
CC: eric.dumazet@gmail.com
CC: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Diffstat (limited to 'kernel/rcutiny.c')
-rw-r--r-- | kernel/rcutiny.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c index 38729d3cd236..196ec02f8be0 100644 --- a/kernel/rcutiny.c +++ b/kernel/rcutiny.c | |||
@@ -169,6 +169,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp) | |||
169 | while (list) { | 169 | while (list) { |
170 | next = list->next; | 170 | next = list->next; |
171 | prefetch(next); | 171 | prefetch(next); |
172 | debug_rcu_head_unqueue(list); | ||
172 | list->func(list); | 173 | list->func(list); |
173 | list = next; | 174 | list = next; |
174 | } | 175 | } |
@@ -211,6 +212,7 @@ static void __call_rcu(struct rcu_head *head, | |||
211 | { | 212 | { |
212 | unsigned long flags; | 213 | unsigned long flags; |
213 | 214 | ||
215 | debug_rcu_head_queue(head); | ||
214 | head->func = func; | 216 | head->func = func; |
215 | head->next = NULL; | 217 | head->next = NULL; |
216 | 218 | ||