diff options
Diffstat (limited to 'include/linux/rcupdate.h')
| -rw-r--r-- | include/linux/rcupdate.h | 19 | 
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)  }  #endif	/* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ +#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) +bool rcu_lockdep_current_cpu_online(void); +#else /* #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) */ +static inline bool rcu_lockdep_current_cpu_online(void) +{ +	return 1; +} +#endif /* #else #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) */ +  #ifdef CONFIG_DEBUG_LOCK_ALLOC  #ifdef CONFIG_PROVE_RCU @@ -270,6 +279,9 @@ extern int debug_lockdep_rcu_enabled(void);   * occur in the same context, for example, it is illegal to invoke   * rcu_read_unlock() in process context if the matching rcu_read_lock()   * was invoked from within an irq handler. + * + * Note that rcu_read_lock() is disallowed if the CPU is either idle or + * offline from an RCU perspective, so check for those as well.   */  static inline int rcu_read_lock_held(void)  { @@ -277,6 +289,8 @@ static inline int rcu_read_lock_held(void)  		return 1;  	if (rcu_is_cpu_idle())  		return 0; +	if (!rcu_lockdep_current_cpu_online()) +		return 0;  	return lock_is_held(&rcu_lock_map);  } @@ -313,6 +327,9 @@ extern int rcu_read_lock_bh_held(void);   * notice an extended quiescent state to other CPUs that started a grace   * period. Otherwise we would delay any grace period as long as we run in   * the idle task. + * + * Similarly, we avoid claiming an SRCU read lock held if the current + * CPU is offline.   */  #ifdef CONFIG_PREEMPT_COUNT  static inline int rcu_read_lock_sched_held(void) @@ -323,6 +340,8 @@ static inline int rcu_read_lock_sched_held(void)  		return 1;  	if (rcu_is_cpu_idle())  		return 0; +	if (!rcu_lockdep_current_cpu_online()) +		return 0;  	if (debug_locks)  		lockdep_opinion = lock_is_held(&rcu_sched_lock_map);  	return lockdep_opinion || preempt_count() != 0 || irqs_disabled();  |