diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/rcupdate.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index bd5d5c8e5140..28d2f24e7871 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
@@ -74,6 +74,8 @@ void wakeme_after_rcu(struct rcu_head *head) | |||
74 | complete(&rcu->completion); | 74 | complete(&rcu->completion); |
75 | } | 75 | } |
76 | 76 | ||
77 | #ifdef CONFIG_TREE_PREEMPT_RCU | ||
78 | |||
77 | /** | 79 | /** |
78 | * synchronize_rcu - wait until a grace period has elapsed. | 80 | * synchronize_rcu - wait until a grace period has elapsed. |
79 | * | 81 | * |
@@ -87,7 +89,7 @@ void synchronize_rcu(void) | |||
87 | { | 89 | { |
88 | struct rcu_synchronize rcu; | 90 | struct rcu_synchronize rcu; |
89 | 91 | ||
90 | if (rcu_blocking_is_gp()) | 92 | if (!rcu_scheduler_active) |
91 | return; | 93 | return; |
92 | 94 | ||
93 | init_completion(&rcu.completion); | 95 | init_completion(&rcu.completion); |
@@ -98,6 +100,46 @@ void synchronize_rcu(void) | |||
98 | } | 100 | } |
99 | EXPORT_SYMBOL_GPL(synchronize_rcu); | 101 | EXPORT_SYMBOL_GPL(synchronize_rcu); |
100 | 102 | ||
103 | #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */ | ||
104 | |||
105 | /** | ||
106 | * synchronize_sched - wait until an rcu-sched grace period has elapsed. | ||
107 | * | ||
108 | * Control will return to the caller some time after a full rcu-sched | ||
109 | * grace period has elapsed, in other words after all currently executing | ||
110 | * rcu-sched read-side critical sections have completed. These read-side | ||
111 | * critical sections are delimited by rcu_read_lock_sched() and | ||
112 | * rcu_read_unlock_sched(), and may be nested. Note that preempt_disable(), | ||
113 | * local_irq_disable(), and so on may be used in place of | ||
114 | * rcu_read_lock_sched(). | ||
115 | * | ||
116 | * This means that all preempt_disable code sequences, including NMI and | ||
117 | * hardware-interrupt handlers, in progress on entry will have completed | ||
118 | * before this primitive returns. However, this does not guarantee that | ||
119 | * softirq handlers will have completed, since in some kernels, these | ||
120 | * handlers can run in process context, and can block. | ||
121 | * | ||
122 | * This primitive provides the guarantees made by the (now removed) | ||
123 | * synchronize_kernel() API. In contrast, synchronize_rcu() only | ||
124 | * guarantees that rcu_read_lock() sections will have completed. | ||
125 | * In "classic RCU", these two guarantees happen to be one and | ||
126 | * the same, but can differ in realtime RCU implementations. | ||
127 | */ | ||
128 | void synchronize_sched(void) | ||
129 | { | ||
130 | struct rcu_synchronize rcu; | ||
131 | |||
132 | if (rcu_blocking_is_gp()) | ||
133 | return; | ||
134 | |||
135 | init_completion(&rcu.completion); | ||
136 | /* Will wake me after RCU finished. */ | ||
137 | call_rcu_sched(&rcu.head, wakeme_after_rcu); | ||
138 | /* Wait for it. */ | ||
139 | wait_for_completion(&rcu.completion); | ||
140 | } | ||
141 | EXPORT_SYMBOL_GPL(synchronize_sched); | ||
142 | |||
101 | /** | 143 | /** |
102 | * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed. | 144 | * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed. |
103 | * | 145 | * |