diff options
| author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2010-03-15 20:03:43 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-03-16 04:57:49 -0400 |
| commit | e3818b8dce2a934cd1521dbc4827e5238d8f45d8 (patch) | |
| tree | 871d73c67a9bfd84b7ed7c49e9d4027eac7e577f | |
| parent | a3d3203e4bb40f253b1541e310dc0f9305be7c84 (diff) | |
rcu: Make rcu_read_lock_bh_held() allow for disabled BH
Disabling BH can stand in for rcu_read_lock_bh(), and this patch
updates rcu_read_lock_bh_held() to allow for this. In order to
avoid include-file hell, this function is moved out of line to
kernel/rcupdate.c.
This fixes a false positive RCU warning.
Reported-by: Arnd Bergmann <arnd@arndb.de>
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Acked-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: dipankar@in.ibm.com
Cc: mathieu.desnoyers@polymtl.ca
Cc: josh@joshtriplett.org
Cc: dvhltc@us.ibm.com
Cc: niv@us.ibm.com
Cc: peterz@infradead.org
Cc: rostedt@goodmis.org
Cc: Valdis.Kletnieks@vt.edu
Cc: dhowells@redhat.com
LKML-Reference: <20100316000343.GA25857@linux.vnet.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | include/linux/rcupdate.h | 19 | ||||
| -rw-r--r-- | kernel/rcupdate.c | 23 |
2 files changed, 27 insertions, 15 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 3024050c82a1..e1bdc4bfd275 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
| @@ -123,22 +123,11 @@ static inline int rcu_read_lock_held(void) | |||
| 123 | return lock_is_held(&rcu_lock_map); | 123 | return lock_is_held(&rcu_lock_map); |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | /** | 126 | /* |
| 127 | * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section? | 127 | * rcu_read_lock_bh_held() is defined out of line to avoid #include-file |
| 128 | * | 128 | * hell. |
| 129 | * If CONFIG_PROVE_LOCKING is selected and enabled, returns nonzero iff in | ||
| 130 | * an RCU-bh read-side critical section. In absence of CONFIG_PROVE_LOCKING, | ||
| 131 | * this assumes we are in an RCU-bh read-side critical section unless it can | ||
| 132 | * prove otherwise. | ||
| 133 | * | ||
| 134 | * Check rcu_scheduler_active to prevent false positives during boot. | ||
| 135 | */ | 129 | */ |
| 136 | static inline int rcu_read_lock_bh_held(void) | 130 | extern int rcu_read_lock_bh_held(void); |
| 137 | { | ||
| 138 | if (!debug_lockdep_rcu_enabled()) | ||
| 139 | return 1; | ||
| 140 | return lock_is_held(&rcu_bh_lock_map); | ||
| 141 | } | ||
| 142 | 131 | ||
| 143 | /** | 132 | /** |
| 144 | * rcu_read_lock_sched_held - might we be in RCU-sched read-side critical section? | 133 | * rcu_read_lock_sched_held - might we be in RCU-sched read-side critical section? |
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index f1125c1a6321..63fe25433980 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include <linux/mutex.h> | 45 | #include <linux/mutex.h> |
| 46 | #include <linux/module.h> | 46 | #include <linux/module.h> |
| 47 | #include <linux/kernel_stat.h> | 47 | #include <linux/kernel_stat.h> |
| 48 | #include <linux/hardirq.h> | ||
| 48 | 49 | ||
| 49 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 50 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 50 | static struct lock_class_key rcu_lock_key; | 51 | static struct lock_class_key rcu_lock_key; |
| @@ -66,6 +67,28 @@ EXPORT_SYMBOL_GPL(rcu_sched_lock_map); | |||
| 66 | int rcu_scheduler_active __read_mostly; | 67 | int rcu_scheduler_active __read_mostly; |
| 67 | EXPORT_SYMBOL_GPL(rcu_scheduler_active); | 68 | EXPORT_SYMBOL_GPL(rcu_scheduler_active); |
| 68 | 69 | ||
| 70 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 71 | |||
| 72 | /** | ||
| 73 | * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section? | ||
| 74 | * | ||
| 75 | * Check for bottom half being disabled, which covers both the | ||
| 76 | * CONFIG_PROVE_RCU and not cases. Note that if someone uses | ||
| 77 | * rcu_read_lock_bh(), but then later enables BH, lockdep (if enabled) | ||
| 78 | * will show the situation. | ||
| 79 | * | ||
| 80 | * Check debug_lockdep_rcu_enabled() to prevent false positives during boot. | ||
| 81 | */ | ||
| 82 | int rcu_read_lock_bh_held(void) | ||
| 83 | { | ||
| 84 | if (!debug_lockdep_rcu_enabled()) | ||
| 85 | return 1; | ||
| 86 | return in_softirq(); | ||
| 87 | } | ||
| 88 | EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held); | ||
| 89 | |||
| 90 | #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ | ||
| 91 | |||
| 69 | /* | 92 | /* |
| 70 | * This function is invoked towards the end of the scheduler's initialization | 93 | * This function is invoked towards the end of the scheduler's initialization |
| 71 | * process. Before this is called, the idle task might contain | 94 | * process. Before this is called, the idle task might contain |
