aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/rcupdate.h4
-rw-r--r--include/linux/rcutiny.h13
-rw-r--r--include/linux/rcutree.h3
-rw-r--r--kernel/rcupdate.c19
-rw-r--r--kernel/rcutiny.c7
-rw-r--r--kernel/rcutiny_plugin.h39
-rw-r--r--kernel/rcutree.c19
7 files changed, 82 insertions, 22 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index d8fb2abcf303..23be3a702516 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -64,8 +64,6 @@ extern int sched_expedited_torture_stats(char *page);
64 64
65/* Internal to kernel */ 65/* Internal to kernel */
66extern void rcu_init(void); 66extern void rcu_init(void);
67extern int rcu_scheduler_active;
68extern void rcu_scheduler_starting(void);
69 67
70#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) 68#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
71#include <linux/rcutree.h> 69#include <linux/rcutree.h>
@@ -178,7 +176,7 @@ static inline int rcu_read_lock_bh_held(void)
178#ifdef CONFIG_PREEMPT 176#ifdef CONFIG_PREEMPT
179static inline int rcu_read_lock_sched_held(void) 177static inline int rcu_read_lock_sched_held(void)
180{ 178{
181 return !rcu_scheduler_active || preempt_count() != 0 || irqs_disabled(); 179 return preempt_count() != 0 || irqs_disabled();
182} 180}
183#else /* #ifdef CONFIG_PREEMPT */ 181#else /* #ifdef CONFIG_PREEMPT */
184static inline int rcu_read_lock_sched_held(void) 182static inline int rcu_read_lock_sched_held(void)
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
index ff22b97fb979..14e5a76b2c06 100644
--- a/include/linux/rcutiny.h
+++ b/include/linux/rcutiny.h
@@ -128,4 +128,17 @@ static inline int rcu_preempt_depth(void)
128 return 0; 128 return 0;
129} 129}
130 130
131#ifdef CONFIG_DEBUG_LOCK_ALLOC
132
133extern int rcu_scheduler_active __read_mostly;
134extern void rcu_scheduler_starting(void);
135
136#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
137
138static inline void rcu_scheduler_starting(void)
139{
140}
141
142#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
143
131#endif /* __LINUX_RCUTINY_H */ 144#endif /* __LINUX_RCUTINY_H */
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index b9f74606f320..48282055e83d 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -123,4 +123,7 @@ static inline int rcu_blocking_is_gp(void)
123 return num_online_cpus() == 1; 123 return num_online_cpus() == 1;
124} 124}
125 125
126extern void rcu_scheduler_starting(void);
127extern int rcu_scheduler_active __read_mostly;
128
126#endif /* __LINUX_RCUTREE_H */ 129#endif /* __LINUX_RCUTREE_H */
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 49d808e833b0..72a8dc9567f5 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -44,7 +44,6 @@
44#include <linux/cpu.h> 44#include <linux/cpu.h>
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>
48#include <linux/hardirq.h> 47#include <linux/hardirq.h>
49 48
50#ifdef CONFIG_DEBUG_LOCK_ALLOC 49#ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -64,9 +63,6 @@ struct lockdep_map rcu_sched_lock_map =
64EXPORT_SYMBOL_GPL(rcu_sched_lock_map); 63EXPORT_SYMBOL_GPL(rcu_sched_lock_map);
65#endif 64#endif
66 65
67int rcu_scheduler_active __read_mostly;
68EXPORT_SYMBOL_GPL(rcu_scheduler_active);
69
70#ifdef CONFIG_DEBUG_LOCK_ALLOC 66#ifdef CONFIG_DEBUG_LOCK_ALLOC
71 67
72int debug_lockdep_rcu_enabled(void) 68int debug_lockdep_rcu_enabled(void)
@@ -97,21 +93,6 @@ EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held);
97#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ 93#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
98 94
99/* 95/*
100 * This function is invoked towards the end of the scheduler's initialization
101 * process. Before this is called, the idle task might contain
102 * RCU read-side critical sections (during which time, this idle
103 * task is booting the system). After this function is called, the
104 * idle tasks are prohibited from containing RCU read-side critical
105 * sections.
106 */
107void rcu_scheduler_starting(void)
108{
109 WARN_ON(num_online_cpus() != 1);
110 WARN_ON(nr_context_switches() > 0);
111 rcu_scheduler_active = 1;
112}
113
114/*
115 * Awaken the corresponding synchronize_rcu() instance now that a 96 * Awaken the corresponding synchronize_rcu() instance now that a
116 * grace period has elapsed. 97 * grace period has elapsed.
117 */ 98 */
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
index d9f8a623c9fa..b1804ff83d5e 100644
--- a/kernel/rcutiny.c
+++ b/kernel/rcutiny.c
@@ -54,6 +54,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk = {
54 .curtail = &rcu_bh_ctrlblk.rcucblist, 54 .curtail = &rcu_bh_ctrlblk.rcucblist,
55}; 55};
56 56
57#ifdef CONFIG_DEBUG_LOCK_ALLOC
58int rcu_scheduler_active __read_mostly;
59EXPORT_SYMBOL_GPL(rcu_scheduler_active);
60#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
61
57#ifdef CONFIG_NO_HZ 62#ifdef CONFIG_NO_HZ
58 63
59static long rcu_dynticks_nesting = 1; 64static long rcu_dynticks_nesting = 1;
@@ -276,3 +281,5 @@ void __init rcu_init(void)
276{ 281{
277 open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); 282 open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
278} 283}
284
285#include "rcutiny_plugin.h"
diff --git a/kernel/rcutiny_plugin.h b/kernel/rcutiny_plugin.h
new file mode 100644
index 000000000000..d223a92bc742
--- /dev/null
+++ b/kernel/rcutiny_plugin.h
@@ -0,0 +1,39 @@
1/*
2 * Read-Copy Update mechanism for mutual exclusion (tree-based version)
3 * Internal non-public definitions that provide either classic
4 * or preemptable semantics.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 * Copyright IBM Corporation, 2009
21 *
22 * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
23 */
24
25#ifdef CONFIG_DEBUG_LOCK_ALLOC
26
27#include <linux/kernel_stat.h>
28
29/*
30 * During boot, we forgive RCU lockdep issues. After this function is
31 * invoked, we start taking RCU lockdep issues seriously.
32 */
33void rcu_scheduler_starting(void)
34{
35 WARN_ON(nr_context_switches() > 0);
36 rcu_scheduler_active = 1;
37}
38
39#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index e33631354b69..3623f8e10220 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -46,6 +46,7 @@
46#include <linux/cpu.h> 46#include <linux/cpu.h>
47#include <linux/mutex.h> 47#include <linux/mutex.h>
48#include <linux/time.h> 48#include <linux/time.h>
49#include <linux/kernel_stat.h>
49 50
50#include "rcutree.h" 51#include "rcutree.h"
51 52
@@ -80,6 +81,9 @@ DEFINE_PER_CPU(struct rcu_data, rcu_sched_data);
80struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state); 81struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state);
81DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); 82DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
82 83
84int rcu_scheduler_active __read_mostly;
85EXPORT_SYMBOL_GPL(rcu_scheduler_active);
86
83/* 87/*
84 * Return true if an RCU grace period is in progress. The ACCESS_ONCE()s 88 * Return true if an RCU grace period is in progress. The ACCESS_ONCE()s
85 * permit this function to be invoked without holding the root rcu_node 89 * permit this function to be invoked without holding the root rcu_node
@@ -1784,6 +1788,21 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
1784} 1788}
1785 1789
1786/* 1790/*
1791 * This function is invoked towards the end of the scheduler's initialization
1792 * process. Before this is called, the idle task might contain
1793 * RCU read-side critical sections (during which time, this idle
1794 * task is booting the system). After this function is called, the
1795 * idle tasks are prohibited from containing RCU read-side critical
1796 * sections. This function also enables RCU lockdep checking.
1797 */
1798void rcu_scheduler_starting(void)
1799{
1800 WARN_ON(num_online_cpus() != 1);
1801 WARN_ON(nr_context_switches() > 0);
1802 rcu_scheduler_active = 1;
1803}
1804
1805/*
1787 * Compute the per-level fanout, either using the exact fanout specified 1806 * Compute the per-level fanout, either using the exact fanout specified
1788 * or balancing the tree, depending on CONFIG_RCU_FANOUT_EXACT. 1807 * or balancing the tree, depending on CONFIG_RCU_FANOUT_EXACT.
1789 */ 1808 */