Messages in this thread Patch in this message | | | From | "Paul E. McKenney" <> | Subject | [PATCH RFC tip/core/rcu 1/6] rcu: Stabilize use of num_online_cpus() for GP short circuit | Date | Mon, 23 Apr 2012 09:42:22 -0700 |
| |
From: "Paul E. McKenney" <paul.mckenney@linaro.org>
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 would result in a too-short RCU grace period, which could in turn result in total failure.
This commit therefore protects the num_online_cpus() with preempt_disable().
Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> --- include/linux/rcutree.h | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index e8ee5dd..997179f 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h @@ -101,8 +101,13 @@ extern void rcu_sched_force_quiescent_state(void); /* A context switch is a grace period for RCU-sched and RCU-bh. */ static inline int rcu_blocking_is_gp(void) { + int ret; + might_sleep(); /* Check for RCU read-side critical section. */ - return num_online_cpus() == 1; + preempt_disable(); /* Prevent CPU hotplug from confusing us. */ + ret = num_online_cpus() == 1; + preempt_enable(); + return ret; } extern void rcu_scheduler_starting(void); -- 1.7.8
| |