提交 106dd5af 编写于 作者: M Michael wang 提交者: Ingo Molnar

sched: Fix endless sync_sched/rcu() loop inside _cpu_down()

Commit 6acce3ef:

	sched: Remove get_online_cpus() usage

tries to do sync_sched/rcu() inside _cpu_down() but triggers:

	INFO: task swapper/0:1 blocked for more than 120 seconds.
	...
	[<ffffffff811263dc>] synchronize_rcu+0x2c/0x30
	[<ffffffff81d1bd82>] _cpu_down+0x2b2/0x340
	...

It was caused by that in the rcu boost case we rely on smpboot thread to
finish the rcu callback, which has already been parked before sync in here
and leads to the endless sync_sched/rcu().

This patch exchanges the sequence of smpboot_park_threads() and
sync_sched/rcu() to fix the bug.
Reported-by: NFengguang Wu <fengguang.wu@intel.com>
Tested-by: NFengguang Wu <fengguang.wu@intel.com>
Signed-off-by: NMichael Wang <wangyun@linux.vnet.ibm.com>
Signed-off-by: NPeter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/5282EDC0.6060003@linux.vnet.ibm.comSigned-off-by: NIngo Molnar <mingo@kernel.org>
上级 9b66bfb2
...@@ -306,7 +306,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) ...@@ -306,7 +306,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
__func__, cpu); __func__, cpu);
goto out_release; goto out_release;
} }
smpboot_park_threads(cpu);
/* /*
* By now we've cleared cpu_active_mask, wait for all preempt-disabled * By now we've cleared cpu_active_mask, wait for all preempt-disabled
...@@ -315,12 +314,16 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) ...@@ -315,12 +314,16 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
* *
* For CONFIG_PREEMPT we have preemptible RCU and its sync_rcu() might * For CONFIG_PREEMPT we have preemptible RCU and its sync_rcu() might
* not imply sync_sched(), so explicitly call both. * not imply sync_sched(), so explicitly call both.
*
* Do sync before park smpboot threads to take care the rcu boost case.
*/ */
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
synchronize_sched(); synchronize_sched();
#endif #endif
synchronize_rcu(); synchronize_rcu();
smpboot_park_threads(cpu);
/* /*
* So now all preempt/rcu users must observe !cpu_active(). * So now all preempt/rcu users must observe !cpu_active().
*/ */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册