diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-10-28 09:22:24 -0700 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-12-09 15:12:39 -0800 |
commit | 24ef659a857c3cba40b64ea51ea4fce8d2fb7bbc (patch) | |
tree | a3059c0605de74b27d67bcfbb58bceabf3dff948 /kernel/rcu/rcu.h | |
parent | bc72d962d6a0ba8d9d5314d04fd1775261a9ec79 (diff) | |
download | linux-24ef659a857c3cba40b64ea51ea4fce8d2fb7bbc.tar.bz2 |
rcu: Provide better diagnostics for blocking in RCU callback functions
Currently blocking in an RCU callback function will result in
"scheduling while atomic", which could be triggered for any number
of reasons. To aid debugging, this patch introduces a rcu_callback_map
that is used to tie the inappropriate voluntary context switch back
to the fact that the function is being invoked from within a callback.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcu/rcu.h')
-rw-r--r-- | kernel/rcu/rcu.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h index 7859a0a3951e..a8f981a2d110 100644 --- a/kernel/rcu/rcu.h +++ b/kernel/rcu/rcu.h @@ -102,13 +102,16 @@ static inline bool __rcu_reclaim(const char *rn, struct rcu_head *head) { unsigned long offset = (unsigned long)head->func; + rcu_lock_acquire(&rcu_callback_map); if (__is_kfree_rcu_offset(offset)) { RCU_TRACE(trace_rcu_invoke_kfree_callback(rn, head, offset)); kfree((void *)head - offset); + rcu_lock_release(&rcu_callback_map); return 1; } else { RCU_TRACE(trace_rcu_invoke_callback(rn, head)); head->func(head); + rcu_lock_release(&rcu_callback_map); return 0; } } |