aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-02-10 17:32:54 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-04-18 14:38:18 -0400
commit900b1028ec388e50c98200641ae4274794c807cf (patch)
tree189ccd5b77678b8e34046d5287a1d9deac9a62c9 /kernel
parent15fecf89e46a962ccda583d919e25d9da7bf0723 (diff)
srcu: Allow SRCU to access rcu_scheduler_active
This is primarily a code-movement commit in preparation for allowing SRCU to handle early-boot SRCU grace periods. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/rcu/tiny_plugin.h9
-rw-r--r--kernel/rcu/tree.c2
-rw-r--r--kernel/rcu/tree_exp.h12
-rw-r--r--kernel/rcu/update.c52
4 files changed, 40 insertions, 35 deletions
diff --git a/kernel/rcu/tiny_plugin.h b/kernel/rcu/tiny_plugin.h
index df3a60e19f07..371034e77f87 100644
--- a/kernel/rcu/tiny_plugin.h
+++ b/kernel/rcu/tiny_plugin.h
@@ -52,7 +52,7 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk = {
52 RCU_TRACE(.name = "rcu_bh") 52 RCU_TRACE(.name = "rcu_bh")
53}; 53};
54 54
55#ifdef CONFIG_DEBUG_LOCK_ALLOC 55#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SRCU)
56#include <linux/kernel_stat.h> 56#include <linux/kernel_stat.h>
57 57
58int rcu_scheduler_active __read_mostly; 58int rcu_scheduler_active __read_mostly;
@@ -65,15 +65,16 @@ EXPORT_SYMBOL_GPL(rcu_scheduler_active);
65 * to RCU_SCHEDULER_RUNNING, skipping the RCU_SCHEDULER_INIT stage. 65 * to RCU_SCHEDULER_RUNNING, skipping the RCU_SCHEDULER_INIT stage.
66 * The reason for this is that Tiny RCU does not need kthreads, so does 66 * The reason for this is that Tiny RCU does not need kthreads, so does
67 * not have to care about the fact that the scheduler is half-initialized 67 * not have to care about the fact that the scheduler is half-initialized
68 * at a certain phase of the boot process. 68 * at a certain phase of the boot process. Unless SRCU is in the mix.
69 */ 69 */
70void __init rcu_scheduler_starting(void) 70void __init rcu_scheduler_starting(void)
71{ 71{
72 WARN_ON(nr_context_switches() > 0); 72 WARN_ON(nr_context_switches() > 0);
73 rcu_scheduler_active = RCU_SCHEDULER_RUNNING; 73 rcu_scheduler_active = IS_ENABLED(CONFIG_SRCU)
74 ? RCU_SCHEDULER_INIT : RCU_SCHEDULER_RUNNING;
74} 75}
75 76
76#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ 77#endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SRCU) */
77 78
78#ifdef CONFIG_RCU_TRACE 79#ifdef CONFIG_RCU_TRACE
79 80
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 8cc9d40b41ea..2380d1e3dfb8 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -3974,7 +3974,7 @@ early_initcall(rcu_spawn_gp_kthread);
3974 * task is booting the system, and such primitives are no-ops). After this 3974 * task is booting the system, and such primitives are no-ops). After this
3975 * function is called, any synchronous grace-period primitives are run as 3975 * function is called, any synchronous grace-period primitives are run as
3976 * expedited, with the requesting task driving the grace period forward. 3976 * expedited, with the requesting task driving the grace period forward.
3977 * A later core_initcall() rcu_exp_runtime_mode() will switch to full 3977 * A later core_initcall() rcu_set_runtime_mode() will switch to full
3978 * runtime RCU functionality. 3978 * runtime RCU functionality.
3979 */ 3979 */
3980void rcu_scheduler_starting(void) 3980void rcu_scheduler_starting(void)
diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h
index a1f52bbe9db6..51ca287828a2 100644
--- a/kernel/rcu/tree_exp.h
+++ b/kernel/rcu/tree_exp.h
@@ -737,15 +737,3 @@ void synchronize_rcu_expedited(void)
737EXPORT_SYMBOL_GPL(synchronize_rcu_expedited); 737EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
738 738
739#endif /* #else #ifdef CONFIG_PREEMPT_RCU */ 739#endif /* #else #ifdef CONFIG_PREEMPT_RCU */
740
741/*
742 * Switch to run-time mode once Tree RCU has fully initialized.
743 */
744static int __init rcu_exp_runtime_mode(void)
745{
746 rcu_test_sync_prims();
747 rcu_scheduler_active = RCU_SCHEDULER_RUNNING;
748 rcu_test_sync_prims();
749 return 0;
750}
751core_initcall(rcu_exp_runtime_mode);
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
index 55c8530316c7..c5df0d756900 100644
--- a/kernel/rcu/update.c
+++ b/kernel/rcu/update.c
@@ -124,7 +124,7 @@ EXPORT_SYMBOL(rcu_read_lock_sched_held);
124 * non-expedited counterparts? Intended for use within RCU. Note 124 * non-expedited counterparts? Intended for use within RCU. Note
125 * that if the user specifies both rcu_expedited and rcu_normal, then 125 * that if the user specifies both rcu_expedited and rcu_normal, then
126 * rcu_normal wins. (Except during the time period during boot from 126 * rcu_normal wins. (Except during the time period during boot from
127 * when the first task is spawned until the rcu_exp_runtime_mode() 127 * when the first task is spawned until the rcu_set_runtime_mode()
128 * core_initcall() is invoked, at which point everything is expedited.) 128 * core_initcall() is invoked, at which point everything is expedited.)
129 */ 129 */
130bool rcu_gp_is_normal(void) 130bool rcu_gp_is_normal(void)
@@ -190,6 +190,39 @@ void rcu_end_inkernel_boot(void)
190 190
191#endif /* #ifndef CONFIG_TINY_RCU */ 191#endif /* #ifndef CONFIG_TINY_RCU */
192 192
193/*
194 * Test each non-SRCU synchronous grace-period wait API. This is
195 * useful just after a change in mode for these primitives, and
196 * during early boot.
197 */
198void rcu_test_sync_prims(void)
199{
200 if (!IS_ENABLED(CONFIG_PROVE_RCU))
201 return;
202 synchronize_rcu();
203 synchronize_rcu_bh();
204 synchronize_sched();
205 synchronize_rcu_expedited();
206 synchronize_rcu_bh_expedited();
207 synchronize_sched_expedited();
208}
209
210#if !defined(CONFIG_TINY_RCU) || defined(CONFIG_SRCU)
211
212/*
213 * Switch to run-time mode once RCU has fully initialized.
214 */
215static int __init rcu_set_runtime_mode(void)
216{
217 rcu_test_sync_prims();
218 rcu_scheduler_active = RCU_SCHEDULER_RUNNING;
219 rcu_test_sync_prims();
220 return 0;
221}
222core_initcall(rcu_set_runtime_mode);
223
224#endif /* #if !defined(CONFIG_TINY_RCU) || defined(CONFIG_SRCU) */
225
193#ifdef CONFIG_PREEMPT_RCU 226#ifdef CONFIG_PREEMPT_RCU
194 227
195/* 228/*
@@ -817,23 +850,6 @@ static void rcu_spawn_tasks_kthread(void)
817 850
818#endif /* #ifdef CONFIG_TASKS_RCU */ 851#endif /* #ifdef CONFIG_TASKS_RCU */
819 852
820/*
821 * Test each non-SRCU synchronous grace-period wait API. This is
822 * useful just after a change in mode for these primitives, and
823 * during early boot.
824 */
825void rcu_test_sync_prims(void)
826{
827 if (!IS_ENABLED(CONFIG_PROVE_RCU))
828 return;
829 synchronize_rcu();
830 synchronize_rcu_bh();
831 synchronize_sched();
832 synchronize_rcu_expedited();
833 synchronize_rcu_bh_expedited();
834 synchronize_sched_expedited();
835}
836
837#ifdef CONFIG_PROVE_RCU 853#ifdef CONFIG_PROVE_RCU
838 854
839/* 855/*