|
@@ -2940,11 +2940,6 @@ static int synchronize_sched_expedited_cpu_stop(void *data)
|
|
|
* restructure your code to batch your updates, and then use a single
|
|
|
* synchronize_sched() instead.
|
|
|
*
|
|
|
- * Note that it is illegal to call this function while holding any lock
|
|
|
- * that is acquired by a CPU-hotplug notifier. And yes, it is also illegal
|
|
|
- * to call this function from a CPU-hotplug notifier. Failing to observe
|
|
|
- * these restriction will result in deadlock.
|
|
|
- *
|
|
|
* This implementation can be thought of as an application of ticket
|
|
|
* locking to RCU, with sync_sched_expedited_started and
|
|
|
* sync_sched_expedited_done taking on the roles of the halves
|
|
@@ -2994,7 +2989,12 @@ void synchronize_sched_expedited(void)
|
|
|
*/
|
|
|
snap = atomic_long_inc_return(&rsp->expedited_start);
|
|
|
firstsnap = snap;
|
|
|
- get_online_cpus();
|
|
|
+ if (!try_get_online_cpus()) {
|
|
|
+ /* CPU hotplug operation in flight, fall back to normal GP. */
|
|
|
+ wait_rcu_gp(call_rcu_sched);
|
|
|
+ atomic_long_inc(&rsp->expedited_normal);
|
|
|
+ return;
|
|
|
+ }
|
|
|
WARN_ON_ONCE(cpu_is_offline(raw_smp_processor_id()));
|
|
|
|
|
|
/*
|
|
@@ -3041,7 +3041,12 @@ void synchronize_sched_expedited(void)
|
|
|
* and they started after our first try, so their grace
|
|
|
* period works for us.
|
|
|
*/
|
|
|
- get_online_cpus();
|
|
|
+ if (!try_get_online_cpus()) {
|
|
|
+ /* CPU hotplug operation in flight, use normal GP. */
|
|
|
+ wait_rcu_gp(call_rcu_sched);
|
|
|
+ atomic_long_inc(&rsp->expedited_normal);
|
|
|
+ return;
|
|
|
+ }
|
|
|
snap = atomic_long_read(&rsp->expedited_start);
|
|
|
smp_mb(); /* ensure read is before try_stop_cpus(). */
|
|
|
}
|