aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAndreas Herrmann <andreas.herrmann3@amd.com>2007-11-14 20:00:44 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-14 21:45:44 -0500
commitbae19fe033b0c5ed99b1ed27a4cce84625a24606 (patch)
treefe8356f234bb4e8a1ab9edfb92bc9e8be0265b58 /arch
parent77f2878b4f78c0b29c4a2580665a446c77901152 (diff)
x86: don't call mce_create_device on CPU_UP_PREPARE
Fix regression introduced with d435d862baca3e25e5eec236762a43251b1e7ffc ("cpu hotplug: mce: fix cpu hotplug error handling"). A CPU which was not brought up during boot (using maxcpus and additional_cpus parameters) couldn't be onlined anymore. For such a CPU it seemed that MCE was not supported during CPU_UP_PREPARE-time which caused mce_cpu_callback to return NOTIFY_BAD to notifier_call_chain. To fix this we: - call mce_create_device for CPU_ONLINE event (instead of CPU_UP_PREPARE), - avoid mce_remove_device() for the CPU that is not correctly initialized by mce_create_device() failure, - make mce_cpu_callback always return NOTIFY_OK for CPU_ONLINE event. Because CPU_ONLINE callback return value is always ignored. [akinobu.mita@gmail.com: avoid mce_remove_device() for not initialized device] [akinobu.mita@gmail.com: make mce_cpu_callback always return NOTIFY_OK] Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_64.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
index b9f802e35209..447b351f1f2a 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
@@ -802,6 +802,8 @@ static struct sysdev_attribute *mce_attributes[] = {
802 NULL 802 NULL
803}; 803};
804 804
805static cpumask_t mce_device_initialized = CPU_MASK_NONE;
806
805/* Per cpu sysdev init. All of the cpus still share the same ctl bank */ 807/* Per cpu sysdev init. All of the cpus still share the same ctl bank */
806static __cpuinit int mce_create_device(unsigned int cpu) 808static __cpuinit int mce_create_device(unsigned int cpu)
807{ 809{
@@ -825,6 +827,7 @@ static __cpuinit int mce_create_device(unsigned int cpu)
825 if (err) 827 if (err)
826 goto error; 828 goto error;
827 } 829 }
830 cpu_set(cpu, mce_device_initialized);
828 831
829 return 0; 832 return 0;
830error: 833error:
@@ -841,10 +844,14 @@ static void mce_remove_device(unsigned int cpu)
841{ 844{
842 int i; 845 int i;
843 846
847 if (!cpu_isset(cpu, mce_device_initialized))
848 return;
849
844 for (i = 0; mce_attributes[i]; i++) 850 for (i = 0; mce_attributes[i]; i++)
845 sysdev_remove_file(&per_cpu(device_mce,cpu), 851 sysdev_remove_file(&per_cpu(device_mce,cpu),
846 mce_attributes[i]); 852 mce_attributes[i]);
847 sysdev_unregister(&per_cpu(device_mce,cpu)); 853 sysdev_unregister(&per_cpu(device_mce,cpu));
854 cpu_clear(cpu, mce_device_initialized);
848} 855}
849 856
850/* Get notified when a cpu comes on/off. Be hotplug friendly. */ 857/* Get notified when a cpu comes on/off. Be hotplug friendly. */
@@ -852,21 +859,18 @@ static int
852mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) 859mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
853{ 860{
854 unsigned int cpu = (unsigned long)hcpu; 861 unsigned int cpu = (unsigned long)hcpu;
855 int err = 0;
856 862
857 switch (action) { 863 switch (action) {
858 case CPU_UP_PREPARE: 864 case CPU_ONLINE:
859 case CPU_UP_PREPARE_FROZEN: 865 case CPU_ONLINE_FROZEN:
860 err = mce_create_device(cpu); 866 mce_create_device(cpu);
861 break; 867 break;
862 case CPU_UP_CANCELED:
863 case CPU_UP_CANCELED_FROZEN:
864 case CPU_DEAD: 868 case CPU_DEAD:
865 case CPU_DEAD_FROZEN: 869 case CPU_DEAD_FROZEN:
866 mce_remove_device(cpu); 870 mce_remove_device(cpu);
867 break; 871 break;
868 } 872 }
869 return err ? NOTIFY_BAD : NOTIFY_OK; 873 return NOTIFY_OK;
870} 874}
871 875
872static struct notifier_block mce_cpu_notifier = { 876static struct notifier_block mce_cpu_notifier = {