瀏覽代碼

[S390] idle: avoid RCU usage in extended quiescent state

Avoid calling wake_up() from our NMI "bottom halve" from RCU extended
quiescent state in idle. wake_up() has RCU read-side critical sections
but this will be completely ignored by RCU if the cpu is in extended
quiescent state.
Which means that whatever object is being accessed from within the
read-side critical section can be freed concurrently from a different
cpu.
So make sure we leave extended quiescent state before calling wake_up().

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Heiko Carstens 14 年之前
父節點
當前提交
f3612304ee
共有 1 個文件被更改,包括 3 次插入2 次删除
  1. 3 2
      arch/s390/kernel/process.c

+ 3 - 2
arch/s390/kernel/process.c

@@ -76,7 +76,6 @@ static void default_idle(void)
 	if (test_thread_flag(TIF_MCCK_PENDING)) {
 	if (test_thread_flag(TIF_MCCK_PENDING)) {
 		local_mcck_enable();
 		local_mcck_enable();
 		local_irq_enable();
 		local_irq_enable();
-		s390_handle_mcck();
 		return;
 		return;
 	}
 	}
 	trace_hardirqs_on();
 	trace_hardirqs_on();
@@ -93,10 +92,12 @@ void cpu_idle(void)
 	for (;;) {
 	for (;;) {
 		tick_nohz_idle_enter();
 		tick_nohz_idle_enter();
 		rcu_idle_enter();
 		rcu_idle_enter();
-		while (!need_resched())
+		while (!need_resched() && !test_thread_flag(TIF_MCCK_PENDING))
 			default_idle();
 			default_idle();
 		rcu_idle_exit();
 		rcu_idle_exit();
 		tick_nohz_idle_exit();
 		tick_nohz_idle_exit();
+		if (test_thread_flag(TIF_MCCK_PENDING))
+			s390_handle_mcck();
 		preempt_enable_no_resched();
 		preempt_enable_no_resched();
 		schedule();
 		schedule();
 		preempt_disable();
 		preempt_disable();