Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 277202
b: refs/heads/master
c: e6b80a3
h: refs/heads/master
v: v3
  • Loading branch information
Frederic Weisbecker authored and Paul E. McKenney committed Dec 11, 2011
1 parent fceac7f commit 1c367a2
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a0f8eefb127f5be07628954f310a7fc8c82b2fc3
refs/heads/master: e6b80a3b0994ea6c3d876d72464f2debbfcfeb05
26 changes: 26 additions & 0 deletions trunk/include/linux/rcupdate.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,15 @@ static inline void destroy_rcu_head_on_stack(struct rcu_head *head)

#ifdef CONFIG_DEBUG_LOCK_ALLOC

#ifdef CONFIG_PROVE_RCU
extern int rcu_is_cpu_idle(void);
#else /* !CONFIG_PROVE_RCU */
static inline int rcu_is_cpu_idle(void)
{
return 0;
}
#endif /* else !CONFIG_PROVE_RCU */

extern struct lockdep_map rcu_lock_map;
# define rcu_read_acquire() \
lock_acquire(&rcu_lock_map, 0, 0, 2, 1, NULL, _THIS_IP_)
Expand Down Expand Up @@ -262,6 +271,8 @@ static inline int rcu_read_lock_held(void)
{
if (!debug_lockdep_rcu_enabled())
return 1;
if (rcu_is_cpu_idle())
return 0;
return lock_is_held(&rcu_lock_map);
}

Expand All @@ -285,6 +296,19 @@ extern int rcu_read_lock_bh_held(void);
*
* Check debug_lockdep_rcu_enabled() to prevent false positives during boot
* and while lockdep is disabled.
*
* Note that if the CPU is in the idle loop from an RCU point of
* view (ie: that we are in the section between rcu_idle_enter() and
* rcu_idle_exit()) then rcu_read_lock_held() returns false even if the CPU
* did an rcu_read_lock(). The reason for this is that RCU ignores CPUs
* that are in such a section, considering these as in extended quiescent
* state, so such a CPU is effectively never in an RCU read-side critical
* section regardless of what RCU primitives it invokes. This state of
* affairs is required --- we need to keep an RCU-free window in idle
* where the CPU may possibly enter into low power mode. This way we can
* 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.
*/
#ifdef CONFIG_PREEMPT_COUNT
static inline int rcu_read_lock_sched_held(void)
Expand All @@ -293,6 +317,8 @@ static inline int rcu_read_lock_sched_held(void)

if (!debug_lockdep_rcu_enabled())
return 1;
if (rcu_is_cpu_idle())
return 0;
if (debug_locks)
lockdep_opinion = lock_is_held(&rcu_sched_lock_map);
return lockdep_opinion || preempt_count() != 0 || irqs_disabled();
Expand Down
2 changes: 2 additions & 0 deletions trunk/kernel/rcupdate.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ int rcu_read_lock_bh_held(void)
{
if (!debug_lockdep_rcu_enabled())
return 1;
if (rcu_is_cpu_idle())
return 0;
return in_softirq() || irqs_disabled();
}
EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held);
Expand Down
1 change: 1 addition & 0 deletions trunk/kernel/rcutiny.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ int rcu_is_cpu_idle(void)
{
return !rcu_dynticks_nesting;
}
EXPORT_SYMBOL(rcu_is_cpu_idle);

#endif /* #ifdef CONFIG_PROVE_RCU */

Expand Down
1 change: 1 addition & 0 deletions trunk/kernel/rcutree.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ int rcu_is_cpu_idle(void)
preempt_enable();
return ret;
}
EXPORT_SYMBOL(rcu_is_cpu_idle);

#endif /* #ifdef CONFIG_PROVE_RCU */

Expand Down

0 comments on commit 1c367a2

Please sign in to comment.