diff options
author | Ingo Molnar <mingo@elte.hu> | 2011-10-01 14:21:36 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-10-01 14:21:36 +0200 |
commit | 048b718029033af117870d3da47da12995be14a3 (patch) | |
tree | b3d4bf5219cd6543c35cb79d1aa08ae98cf2a8af /kernel/rcupdate.c | |
parent | 47ea91b4052d9e94b9dca5d7a3d947fbebd07ba9 (diff) | |
parent | afe24b122eb6edb5f1cb942570ac8d766105c7fc (diff) |
Merge branch 'rcu/next' of git://github.com/paulmckrcu/linux into core/rcu
Diffstat (limited to 'kernel/rcupdate.c')
-rw-r--r-- | kernel/rcupdate.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index ddddb320be6..ca0d23b6b3e 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -46,6 +46,11 @@ #include <linux/module.h> #include <linux/hardirq.h> +#define CREATE_TRACE_POINTS +#include <trace/events/rcu.h> + +#include "rcu.h" + #ifdef CONFIG_DEBUG_LOCK_ALLOC static struct lock_class_key rcu_lock_key; struct lockdep_map rcu_lock_map = @@ -94,11 +99,16 @@ EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held); #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ +struct rcu_synchronize { + struct rcu_head head; + struct completion completion; +}; + /* * Awaken the corresponding synchronize_rcu() instance now that a * grace period has elapsed. */ -void wakeme_after_rcu(struct rcu_head *head) +static void wakeme_after_rcu(struct rcu_head *head) { struct rcu_synchronize *rcu; @@ -106,6 +116,20 @@ void wakeme_after_rcu(struct rcu_head *head) complete(&rcu->completion); } +void wait_rcu_gp(call_rcu_func_t crf) +{ + struct rcu_synchronize rcu; + + init_rcu_head_on_stack(&rcu.head); + init_completion(&rcu.completion); + /* Will wake me after RCU finished. */ + crf(&rcu.head, wakeme_after_rcu); + /* Wait for it. */ + wait_for_completion(&rcu.completion); + destroy_rcu_head_on_stack(&rcu.head); +} +EXPORT_SYMBOL_GPL(wait_rcu_gp); + #ifdef CONFIG_PROVE_RCU /* * wrapper function to avoid #include problems. |