diff options
-rw-r--r-- | include/linux/rcupdate.h | 4 | ||||
-rw-r--r-- | include/linux/rcutiny.h | 13 | ||||
-rw-r--r-- | include/linux/rcutree.h | 3 | ||||
-rw-r--r-- | kernel/rcupdate.c | 19 | ||||
-rw-r--r-- | kernel/rcutiny.c | 7 | ||||
-rw-r--r-- | kernel/rcutiny_plugin.h | 39 | ||||
-rw-r--r-- | kernel/rcutree.c | 19 |
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 */ |
66 | extern void rcu_init(void); | 66 | extern void rcu_init(void); |
67 | extern int rcu_scheduler_active; | ||
68 | extern 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 |
179 | static inline int rcu_read_lock_sched_held(void) | 177 | static 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 */ |
184 | static inline int rcu_read_lock_sched_held(void) | 182 | static 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 | |||
133 | extern int rcu_scheduler_active __read_mostly; | ||
134 | extern void rcu_scheduler_starting(void); | ||
135 | |||
136 | #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ | ||
137 | |||
138 | static 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 | ||
126 | extern void rcu_scheduler_starting(void); | ||
127 | extern 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 = | |||
64 | EXPORT_SYMBOL_GPL(rcu_sched_lock_map); | 63 | EXPORT_SYMBOL_GPL(rcu_sched_lock_map); |
65 | #endif | 64 | #endif |
66 | 65 | ||
67 | int rcu_scheduler_active __read_mostly; | ||
68 | EXPORT_SYMBOL_GPL(rcu_scheduler_active); | ||
69 | |||
70 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 66 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
71 | 67 | ||
72 | int debug_lockdep_rcu_enabled(void) | 68 | int 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 | */ | ||
107 | void 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 | ||
58 | int rcu_scheduler_active __read_mostly; | ||
59 | EXPORT_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 | ||
59 | static long rcu_dynticks_nesting = 1; | 64 | static 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 | */ | ||
33 | void 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); | |||
80 | struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state); | 81 | struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state); |
81 | DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); | 82 | DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); |
82 | 83 | ||
84 | int rcu_scheduler_active __read_mostly; | ||
85 | EXPORT_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 | */ | ||
1798 | void 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 | */ |