|
@@ -260,6 +260,15 @@ retry:
|
|
|
err = 0;
|
|
|
__cpu_stop_queue_work(stopper1, work1, &wakeq);
|
|
|
__cpu_stop_queue_work(stopper2, work2, &wakeq);
|
|
|
+ /*
|
|
|
+ * The waking up of stopper threads has to happen
|
|
|
+ * in the same scheduling context as the queueing.
|
|
|
+ * Otherwise, there is a possibility of one of the
|
|
|
+ * above stoppers being woken up by another CPU,
|
|
|
+ * and preempting us. This will cause us to n ot
|
|
|
+ * wake up the other stopper forever.
|
|
|
+ */
|
|
|
+ preempt_disable();
|
|
|
unlock:
|
|
|
raw_spin_unlock(&stopper2->lock);
|
|
|
raw_spin_unlock_irq(&stopper1->lock);
|
|
@@ -271,7 +280,6 @@ unlock:
|
|
|
}
|
|
|
|
|
|
if (!err) {
|
|
|
- preempt_disable();
|
|
|
wake_up_q(&wakeq);
|
|
|
preempt_enable();
|
|
|
}
|