aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/rcupdate.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/rcupdate.h')
-rw-r--r--include/linux/rcupdate.h19
1 files changed, 19 insertions, 0 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index f409529ff35..146d37d3177 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -226,6 +226,15 @@ static inline void destroy_rcu_head_on_stack(struct rcu_head *head)
226} 226}
227#endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ 227#endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
228 228
229#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU)
230bool rcu_lockdep_current_cpu_online(void);
231#else /* #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) */
232static inline bool rcu_lockdep_current_cpu_online(void)
233{
234 return 1;
235}
236#endif /* #else #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) */
237
229#ifdef CONFIG_DEBUG_LOCK_ALLOC 238#ifdef CONFIG_DEBUG_LOCK_ALLOC
230 239
231#ifdef CONFIG_PROVE_RCU 240#ifdef CONFIG_PROVE_RCU
@@ -270,6 +279,9 @@ extern int debug_lockdep_rcu_enabled(void);
270 * occur in the same context, for example, it is illegal to invoke 279 * occur in the same context, for example, it is illegal to invoke
271 * rcu_read_unlock() in process context if the matching rcu_read_lock() 280 * rcu_read_unlock() in process context if the matching rcu_read_lock()
272 * was invoked from within an irq handler. 281 * was invoked from within an irq handler.
282 *
283 * Note that rcu_read_lock() is disallowed if the CPU is either idle or
284 * offline from an RCU perspective, so check for those as well.
273 */ 285 */
274static inline int rcu_read_lock_held(void) 286static inline int rcu_read_lock_held(void)
275{ 287{
@@ -277,6 +289,8 @@ static inline int rcu_read_lock_held(void)
277 return 1; 289 return 1;
278 if (rcu_is_cpu_idle()) 290 if (rcu_is_cpu_idle())
279 return 0; 291 return 0;
292 if (!rcu_lockdep_current_cpu_online())
293 return 0;
280 return lock_is_held(&rcu_lock_map); 294 return lock_is_held(&rcu_lock_map);
281} 295}
282 296
@@ -313,6 +327,9 @@ extern int rcu_read_lock_bh_held(void);
313 * notice an extended quiescent state to other CPUs that started a grace 327 * notice an extended quiescent state to other CPUs that started a grace
314 * period. Otherwise we would delay any grace period as long as we run in 328 * period. Otherwise we would delay any grace period as long as we run in
315 * the idle task. 329 * the idle task.
330 *
331 * Similarly, we avoid claiming an SRCU read lock held if the current
332 * CPU is offline.
316 */ 333 */
317#ifdef CONFIG_PREEMPT_COUNT 334#ifdef CONFIG_PREEMPT_COUNT
318static inline int rcu_read_lock_sched_held(void) 335static inline int rcu_read_lock_sched_held(void)
@@ -323,6 +340,8 @@ static inline int rcu_read_lock_sched_held(void)
323 return 1; 340 return 1;
324 if (rcu_is_cpu_idle()) 341 if (rcu_is_cpu_idle())
325 return 0; 342 return 0;
343 if (!rcu_lockdep_current_cpu_online())
344 return 0;
326 if (debug_locks) 345 if (debug_locks)
327 lockdep_opinion = lock_is_held(&rcu_sched_lock_map); 346 lockdep_opinion = lock_is_held(&rcu_sched_lock_map);
328 return lockdep_opinion || preempt_count() != 0 || irqs_disabled(); 347 return lockdep_opinion || preempt_count() != 0 || irqs_disabled();