aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2007-10-18 06:05:14 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-18 17:37:21 -0400
commit881a841f4ae268207c29721532406ad061e41857 (patch)
tree5349a9ccbb8e57cb0c84d6c0cffe979d5f14e6e9 /arch
parentc7e38a9c27ced4020d64749400cece4fbad4679e (diff)
cpu hotplug: msr: fix cpu hotplug error handling
Do msr_device_create() in CPU_UP_PREPARE instead of CPU_ONLINE. Cc: "H. Peter Anvin" <hpa@zytor.com> Signed-off-by: Akinobu 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: 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/msr.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index df85c9c13601..e0d5e82e64b3 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -133,37 +133,42 @@ static const struct file_operations msr_fops = {
133 .open = msr_open, 133 .open = msr_open,
134}; 134};
135 135
136static int __cpuinit msr_device_create(int i) 136static int msr_device_create(int cpu)
137{ 137{
138 int err = 0;
139 struct device *dev; 138 struct device *dev;
140 139
141 dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), "msr%d",i); 140 dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu),
142 if (IS_ERR(dev)) 141 "msr%d", cpu);
143 err = PTR_ERR(dev); 142 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
144 return err; 143}
144
145static void msr_device_destroy(int cpu)
146{
147 device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
145} 148}
146 149
147static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb, 150static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb,
148 unsigned long action, void *hcpu) 151 unsigned long action, void *hcpu)
149{ 152{
150 unsigned int cpu = (unsigned long)hcpu; 153 unsigned int cpu = (unsigned long)hcpu;
154 int err = 0;
151 155
152 switch (action) { 156 switch (action) {
153 case CPU_ONLINE: 157 case CPU_UP_PREPARE:
154 case CPU_ONLINE_FROZEN: 158 case CPU_UP_PREPARE_FROZEN:
155 msr_device_create(cpu); 159 err = msr_device_create(cpu);
156 break; 160 break;
161 case CPU_UP_CANCELED:
162 case CPU_UP_CANCELED_FROZEN:
157 case CPU_DEAD: 163 case CPU_DEAD:
158 case CPU_DEAD_FROZEN: 164 case CPU_DEAD_FROZEN:
159 device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); 165 msr_device_destroy(cpu);
160 break; 166 break;
161 } 167 }
162 return NOTIFY_OK; 168 return err ? NOTIFY_BAD : NOTIFY_OK;
163} 169}
164 170
165static struct notifier_block __cpuinitdata msr_class_cpu_notifier = 171static struct notifier_block __cpuinitdata msr_class_cpu_notifier = {
166{
167 .notifier_call = msr_class_cpu_callback, 172 .notifier_call = msr_class_cpu_callback,
168}; 173};
169 174
@@ -196,7 +201,7 @@ static int __init msr_init(void)
196out_class: 201out_class:
197 i = 0; 202 i = 0;
198 for_each_online_cpu(i) 203 for_each_online_cpu(i)
199 device_destroy(msr_class, MKDEV(MSR_MAJOR, i)); 204 msr_device_destroy(i);
200 class_destroy(msr_class); 205 class_destroy(msr_class);
201out_chrdev: 206out_chrdev:
202 unregister_chrdev(MSR_MAJOR, "cpu/msr"); 207 unregister_chrdev(MSR_MAJOR, "cpu/msr");
@@ -208,7 +213,7 @@ static void __exit msr_exit(void)
208{ 213{
209 int cpu = 0; 214 int cpu = 0;
210 for_each_online_cpu(cpu) 215 for_each_online_cpu(cpu)
211 device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); 216 msr_device_destroy(cpu);
212 class_destroy(msr_class); 217 class_destroy(msr_class);
213 unregister_chrdev(MSR_MAJOR, "cpu/msr"); 218 unregister_chrdev(MSR_MAJOR, "cpu/msr");
214 unregister_hotcpu_notifier(&msr_class_cpu_notifier); 219 unregister_hotcpu_notifier(&msr_class_cpu_notifier);