Commit d435d862 authored by Akinobu Mita's avatar Akinobu Mita Committed by Linus Torvalds

cpu hotplug: mce: fix cpu hotplug error handling

- Clear kobject in percpu device_mce before calling sysdev_register() with

  Because mce_create_device() may fail and it leaves kobject filled with
  junk. It will be the problem when mce_create_device() will be called
  next time.

- Fix error handling in mce_create_device()

  Error handling should not do sysdev_remove_file() with not yet added
  attributes.

- Don't register hotcpu notifier when mce_create_device() returns error

- Do mce_create_device() in CPU_UP_PREPARE instead of CPU_ONLINE

Cc: Andi Kleen <andi@firstfloor.org>
Signed-off-by: default avatarAkinobu Mita <akinobu.mita@gmail.com>
Cc: Gautham R Shenoy <ego@in.ibm.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Andi Kleen <ak@suse.de>
Cc: Jan Beulich <jbeulich@novell.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 881a841f
...@@ -802,16 +802,29 @@ static __cpuinit int mce_create_device(unsigned int cpu) ...@@ -802,16 +802,29 @@ static __cpuinit int mce_create_device(unsigned int cpu)
if (!mce_available(&cpu_data[cpu])) if (!mce_available(&cpu_data[cpu]))
return -EIO; return -EIO;
memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
per_cpu(device_mce,cpu).id = cpu; per_cpu(device_mce,cpu).id = cpu;
per_cpu(device_mce,cpu).cls = &mce_sysclass; per_cpu(device_mce,cpu).cls = &mce_sysclass;
err = sysdev_register(&per_cpu(device_mce,cpu)); err = sysdev_register(&per_cpu(device_mce,cpu));
if (err)
return err;
for (i = 0; mce_attributes[i]; i++) {
err = sysdev_create_file(&per_cpu(device_mce,cpu),
mce_attributes[i]);
if (err)
goto error;
}
if (!err) { return 0;
for (i = 0; mce_attributes[i]; i++) error:
sysdev_create_file(&per_cpu(device_mce,cpu), while (i--) {
mce_attributes[i]); sysdev_remove_file(&per_cpu(device_mce,cpu),
mce_attributes[i]);
} }
sysdev_unregister(&per_cpu(device_mce,cpu));
return err; return err;
} }
...@@ -823,7 +836,6 @@ static void mce_remove_device(unsigned int cpu) ...@@ -823,7 +836,6 @@ static void mce_remove_device(unsigned int cpu)
sysdev_remove_file(&per_cpu(device_mce,cpu), sysdev_remove_file(&per_cpu(device_mce,cpu),
mce_attributes[i]); mce_attributes[i]);
sysdev_unregister(&per_cpu(device_mce,cpu)); sysdev_unregister(&per_cpu(device_mce,cpu));
memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
} }
/* Get notified when a cpu comes on/off. Be hotplug friendly. */ /* Get notified when a cpu comes on/off. Be hotplug friendly. */
...@@ -831,18 +843,21 @@ static int ...@@ -831,18 +843,21 @@ static int
mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
{ {
unsigned int cpu = (unsigned long)hcpu; unsigned int cpu = (unsigned long)hcpu;
int err = 0;
switch (action) { switch (action) {
case CPU_ONLINE: case CPU_UP_PREPARE:
case CPU_ONLINE_FROZEN: case CPU_UP_PREPARE_FROZEN:
mce_create_device(cpu); err = mce_create_device(cpu);
break; break;
case CPU_UP_CANCELED:
case CPU_UP_CANCELED_FROZEN:
case CPU_DEAD: case CPU_DEAD:
case CPU_DEAD_FROZEN: case CPU_DEAD_FROZEN:
mce_remove_device(cpu); mce_remove_device(cpu);
break; break;
} }
return NOTIFY_OK; return err ? NOTIFY_BAD : NOTIFY_OK;
} }
static struct notifier_block mce_cpu_notifier = { static struct notifier_block mce_cpu_notifier = {
...@@ -857,9 +872,13 @@ static __init int mce_init_device(void) ...@@ -857,9 +872,13 @@ static __init int mce_init_device(void)
if (!mce_available(&boot_cpu_data)) if (!mce_available(&boot_cpu_data))
return -EIO; return -EIO;
err = sysdev_class_register(&mce_sysclass); err = sysdev_class_register(&mce_sysclass);
if (err)
return err;
for_each_online_cpu(i) { for_each_online_cpu(i) {
mce_create_device(i); err = mce_create_device(i);
if (err)
return err;
} }
register_hotcpu_notifier(&mce_cpu_notifier); register_hotcpu_notifier(&mce_cpu_notifier);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment