提交 fc75cdfa 编写于 作者: H Heiko Carstens 提交者: Linus Torvalds

[PATCH] cpu hotplug: fix CPU_UP_CANCEL handling

If a cpu hotplug callback fails on CPU_UP_PREPARE, all callbacks will be
called with CPU_UP_CANCELED.  A few of these callbacks assume that on
CPU_UP_PREPARE a pointer to task has been stored in a percpu array.  This
assumption is not true if CPU_UP_PREPARE fails and the following calls to
kthread_bind() in CPU_UP_CANCELED will cause an addressing exception
because of passing a NULL pointer.
Signed-off-by: NHeiko Carstens <heiko.carstens@de.ibm.com>
Cc: Ashok Raj <ashok.raj@intel.com>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 04a3446c
...@@ -4756,6 +4756,8 @@ static int migration_call(struct notifier_block *nfb, unsigned long action, ...@@ -4756,6 +4756,8 @@ static int migration_call(struct notifier_block *nfb, unsigned long action,
break; break;
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
case CPU_UP_CANCELED: case CPU_UP_CANCELED:
if (!cpu_rq(cpu)->migration_thread)
break;
/* Unbind it from offline cpu so it can run. Fall thru. */ /* Unbind it from offline cpu so it can run. Fall thru. */
kthread_bind(cpu_rq(cpu)->migration_thread, kthread_bind(cpu_rq(cpu)->migration_thread,
any_online_cpu(cpu_online_map)); any_online_cpu(cpu_online_map));
......
...@@ -470,6 +470,8 @@ static int cpu_callback(struct notifier_block *nfb, ...@@ -470,6 +470,8 @@ static int cpu_callback(struct notifier_block *nfb,
break; break;
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
case CPU_UP_CANCELED: case CPU_UP_CANCELED:
if (!per_cpu(ksoftirqd, hotcpu))
break;
/* Unbind so it can run. Fall thru. */ /* Unbind so it can run. Fall thru. */
kthread_bind(per_cpu(ksoftirqd, hotcpu), kthread_bind(per_cpu(ksoftirqd, hotcpu),
any_online_cpu(cpu_online_map)); any_online_cpu(cpu_online_map));
......
...@@ -127,6 +127,8 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) ...@@ -127,6 +127,8 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
break; break;
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
case CPU_UP_CANCELED: case CPU_UP_CANCELED:
if (!per_cpu(watchdog_task, hotcpu))
break;
/* Unbind so it can run. Fall thru. */ /* Unbind so it can run. Fall thru. */
kthread_bind(per_cpu(watchdog_task, hotcpu), kthread_bind(per_cpu(watchdog_task, hotcpu),
any_online_cpu(cpu_online_map)); any_online_cpu(cpu_online_map));
......
...@@ -590,6 +590,8 @@ static int workqueue_cpu_callback(struct notifier_block *nfb, ...@@ -590,6 +590,8 @@ static int workqueue_cpu_callback(struct notifier_block *nfb,
case CPU_UP_CANCELED: case CPU_UP_CANCELED:
list_for_each_entry(wq, &workqueues, list) { list_for_each_entry(wq, &workqueues, list) {
if (!per_cpu_ptr(wq->cpu_wq, hotcpu)->thread)
continue;
/* Unbind so it can run. */ /* Unbind so it can run. */
kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread, kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread,
any_online_cpu(cpu_online_map)); any_online_cpu(cpu_online_map));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册