summaryrefslogtreecommitdiff
path: root/kernel/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r--kernel/cpu.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 083521327e64..719ba42ff5ee 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -61,13 +61,13 @@ static inline void check_for_tasks(int cpu)
* cpu' with certain environment variables set. */
static int cpu_run_sbin_hotplug(unsigned int cpu, const char *action)
{
- char *argv[3], *envp[5], cpu_str[12], action_str[32];
+ char *argv[3], *envp[6], cpu_str[12], action_str[32], devpath_str[40];
int i;
sprintf(cpu_str, "CPU=%d", cpu);
sprintf(action_str, "ACTION=%s", action);
- /* FIXME: Add DEVPATH. --RR */
-
+ sprintf(devpath_str, "DEVPATH=devices/system/cpu/cpu%d", cpu);
+
i = 0;
argv[i++] = hotplug_path;
argv[i++] = "cpu";
@@ -79,6 +79,7 @@ static int cpu_run_sbin_hotplug(unsigned int cpu, const char *action)
envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
envp[i++] = cpu_str;
envp[i++] = action_str;
+ envp[i++] = devpath_str;
envp[i] = NULL;
return call_usermodehelper(argv[0], argv, envp, 0);
@@ -123,6 +124,15 @@ int cpu_down(unsigned int cpu)
goto out;
}
+ err = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
+ (void *)(long)cpu);
+ if (err == NOTIFY_BAD) {
+ printk("%s: attempt to take down CPU %u failed\n",
+ __FUNCTION__, cpu);
+ err = -EINVAL;
+ goto out;
+ }
+
/* Ensure that we are not runnable on dying cpu */
old_allowed = current->cpus_allowed;
tmp = CPU_MASK_ALL;
@@ -131,6 +141,11 @@ int cpu_down(unsigned int cpu)
p = __stop_machine_run(take_cpu_down, NULL, cpu);
if (IS_ERR(p)) {
+ /* CPU didn't die: tell everyone. Can't complain. */
+ if (notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED,
+ (void *)(long)cpu) == NOTIFY_BAD)
+ BUG();
+
err = PTR_ERR(p);
goto out_allowed;
}