aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cpu.c
diff options
context:
space:
mode:
authorJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-11-22 13:06:44 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-11-22 13:06:44 -0500
commit0bd2af46839ad6262d25714a6ec0365db9d6b98f (patch)
treedcced72d230d69fd0c5816ac6dd03ab84799a93e /kernel/cpu.c
parente138a5d2356729b8752e88520cc1525fae9794ac (diff)
parentf26b90440cd74c78fe10c9bd5160809704a9627c (diff)
Merge ../scsi-rc-fixes-2.6
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r--kernel/cpu.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 32c96628463e..272254f20d97 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -19,7 +19,7 @@
19static DEFINE_MUTEX(cpu_add_remove_lock); 19static DEFINE_MUTEX(cpu_add_remove_lock);
20static DEFINE_MUTEX(cpu_bitmask_lock); 20static DEFINE_MUTEX(cpu_bitmask_lock);
21 21
22static __cpuinitdata BLOCKING_NOTIFIER_HEAD(cpu_chain); 22static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
23 23
24/* If set, cpu_up and cpu_down will return -EBUSY and do nothing. 24/* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
25 * Should always be manipulated under cpu_add_remove_lock 25 * Should always be manipulated under cpu_add_remove_lock
@@ -58,8 +58,8 @@ void unlock_cpu_hotplug(void)
58 recursive_depth--; 58 recursive_depth--;
59 return; 59 return;
60 } 60 }
61 mutex_unlock(&cpu_bitmask_lock);
62 recursive = NULL; 61 recursive = NULL;
62 mutex_unlock(&cpu_bitmask_lock);
63} 63}
64EXPORT_SYMBOL_GPL(unlock_cpu_hotplug); 64EXPORT_SYMBOL_GPL(unlock_cpu_hotplug);
65 65
@@ -68,7 +68,11 @@ EXPORT_SYMBOL_GPL(unlock_cpu_hotplug);
68/* Need to know about CPUs going up/down? */ 68/* Need to know about CPUs going up/down? */
69int __cpuinit register_cpu_notifier(struct notifier_block *nb) 69int __cpuinit register_cpu_notifier(struct notifier_block *nb)
70{ 70{
71 return blocking_notifier_chain_register(&cpu_chain, nb); 71 int ret;
72 mutex_lock(&cpu_add_remove_lock);
73 ret = raw_notifier_chain_register(&cpu_chain, nb);
74 mutex_unlock(&cpu_add_remove_lock);
75 return ret;
72} 76}
73 77
74#ifdef CONFIG_HOTPLUG_CPU 78#ifdef CONFIG_HOTPLUG_CPU
@@ -77,7 +81,9 @@ EXPORT_SYMBOL(register_cpu_notifier);
77 81
78void unregister_cpu_notifier(struct notifier_block *nb) 82void unregister_cpu_notifier(struct notifier_block *nb)
79{ 83{
80 blocking_notifier_chain_unregister(&cpu_chain, nb); 84 mutex_lock(&cpu_add_remove_lock);
85 raw_notifier_chain_unregister(&cpu_chain, nb);
86 mutex_unlock(&cpu_add_remove_lock);
81} 87}
82EXPORT_SYMBOL(unregister_cpu_notifier); 88EXPORT_SYMBOL(unregister_cpu_notifier);
83 89
@@ -126,7 +132,7 @@ static int _cpu_down(unsigned int cpu)
126 if (!cpu_online(cpu)) 132 if (!cpu_online(cpu))
127 return -EINVAL; 133 return -EINVAL;
128 134
129 err = blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, 135 err = raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
130 (void *)(long)cpu); 136 (void *)(long)cpu);
131 if (err == NOTIFY_BAD) { 137 if (err == NOTIFY_BAD) {
132 printk("%s: attempt to take down CPU %u failed\n", 138 printk("%s: attempt to take down CPU %u failed\n",
@@ -144,18 +150,18 @@ static int _cpu_down(unsigned int cpu)
144 p = __stop_machine_run(take_cpu_down, NULL, cpu); 150 p = __stop_machine_run(take_cpu_down, NULL, cpu);
145 mutex_unlock(&cpu_bitmask_lock); 151 mutex_unlock(&cpu_bitmask_lock);
146 152
147 if (IS_ERR(p)) { 153 if (IS_ERR(p) || cpu_online(cpu)) {
148 /* CPU didn't die: tell everyone. Can't complain. */ 154 /* CPU didn't die: tell everyone. Can't complain. */
149 if (blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, 155 if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED,
150 (void *)(long)cpu) == NOTIFY_BAD) 156 (void *)(long)cpu) == NOTIFY_BAD)
151 BUG(); 157 BUG();
152 158
153 err = PTR_ERR(p); 159 if (IS_ERR(p)) {
154 goto out_allowed; 160 err = PTR_ERR(p);
155 } 161 goto out_allowed;
156 162 }
157 if (cpu_online(cpu))
158 goto out_thread; 163 goto out_thread;
164 }
159 165
160 /* Wait for it to sleep (leaving idle task). */ 166 /* Wait for it to sleep (leaving idle task). */
161 while (!idle_cpu(cpu)) 167 while (!idle_cpu(cpu))
@@ -169,7 +175,7 @@ static int _cpu_down(unsigned int cpu)
169 put_cpu(); 175 put_cpu();
170 176
171 /* CPU is completely dead: tell everyone. Too late to complain. */ 177 /* CPU is completely dead: tell everyone. Too late to complain. */
172 if (blocking_notifier_call_chain(&cpu_chain, CPU_DEAD, 178 if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD,
173 (void *)(long)cpu) == NOTIFY_BAD) 179 (void *)(long)cpu) == NOTIFY_BAD)
174 BUG(); 180 BUG();
175 181
@@ -206,7 +212,7 @@ static int __devinit _cpu_up(unsigned int cpu)
206 if (cpu_online(cpu) || !cpu_present(cpu)) 212 if (cpu_online(cpu) || !cpu_present(cpu))
207 return -EINVAL; 213 return -EINVAL;
208 214
209 ret = blocking_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu); 215 ret = raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);
210 if (ret == NOTIFY_BAD) { 216 if (ret == NOTIFY_BAD) {
211 printk("%s: attempt to bring up CPU %u failed\n", 217 printk("%s: attempt to bring up CPU %u failed\n",
212 __FUNCTION__, cpu); 218 __FUNCTION__, cpu);
@@ -223,11 +229,11 @@ static int __devinit _cpu_up(unsigned int cpu)
223 BUG_ON(!cpu_online(cpu)); 229 BUG_ON(!cpu_online(cpu));
224 230
225 /* Now call notifier in preparation. */ 231 /* Now call notifier in preparation. */
226 blocking_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu); 232 raw_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu);
227 233
228out_notify: 234out_notify:
229 if (ret != 0) 235 if (ret != 0)
230 blocking_notifier_call_chain(&cpu_chain, 236 raw_notifier_call_chain(&cpu_chain,
231 CPU_UP_CANCELED, hcpu); 237 CPU_UP_CANCELED, hcpu);
232 238
233 return ret; 239 return ret;