aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/rcutree.h
diff options
context:
space:
mode:
authorPaul E. McKenney <paul.mckenney@linaro.org>2012-02-23 16:30:16 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2012-04-24 23:54:53 -0400
commit6d8133919bac4270883b24328500875a49e71b36 (patch)
treeeae66c4640e429446ef254e468fafb9ceadb142b /include/linux/rcutree.h
parentdabb8aa96020bde8359bc73e76c484dd7ff9b7f2 (diff)
rcu: Document why rcu_blocking_is_gp() is safe
The rcu_blocking_is_gp() function tests to see if there is only one online CPU, and if so, synchronize_sched() and friends become no-ops. However, for larger systems, num_online_cpus() scans a large vector, and might be preempted while doing so. While preempted, any number of CPUs might come online and go offline, potentially resulting in num_online_cpus() returning 1 when there never had only been one CPU online. This could result in a too-short RCU grace period, which could in turn result in total failure, except that the only way that the grace period is too short is if there is an RCU read-side critical section spanning it. For RCU-sched and RCU-bh (which are the only cases using rcu_blocking_is_gp()), RCU read-side critical sections have either preemption or bh disabled, which prevents CPUs from going offline. This in turn prevents actual failures from occurring. This commit therefore adds a large block comment to rcu_blocking_is_gp() documenting why it is safe. This commit also moves rcu_blocking_is_gp() into kernel/rcutree.c, which should help prevent unwary developers from mistaking it for a generally useful function. Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'include/linux/rcutree.h')
-rw-r--r--include/linux/rcutree.h7
1 files changed, 0 insertions, 7 deletions
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index e8ee5dd0854c..b06363055ef8 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -98,13 +98,6 @@ extern void rcu_force_quiescent_state(void);
98extern void rcu_bh_force_quiescent_state(void); 98extern void rcu_bh_force_quiescent_state(void);
99extern void rcu_sched_force_quiescent_state(void); 99extern void rcu_sched_force_quiescent_state(void);
100 100
101/* A context switch is a grace period for RCU-sched and RCU-bh. */
102static inline int rcu_blocking_is_gp(void)
103{
104 might_sleep(); /* Check for RCU read-side critical section. */
105 return num_online_cpus() == 1;
106}
107
108extern void rcu_scheduler_starting(void); 101extern void rcu_scheduler_starting(void);
109extern int rcu_scheduler_active __read_mostly; 102extern int rcu_scheduler_active __read_mostly;
110 103