diff options
Diffstat (limited to 'kernel/cpu.c')
| -rw-r--r-- | kernel/cpu.c | 38 |
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 @@ | |||
| 19 | static DEFINE_MUTEX(cpu_add_remove_lock); | 19 | static DEFINE_MUTEX(cpu_add_remove_lock); |
| 20 | static DEFINE_MUTEX(cpu_bitmask_lock); | 20 | static DEFINE_MUTEX(cpu_bitmask_lock); |
| 21 | 21 | ||
| 22 | static __cpuinitdata BLOCKING_NOTIFIER_HEAD(cpu_chain); | 22 | static __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 | } |
| 64 | EXPORT_SYMBOL_GPL(unlock_cpu_hotplug); | 64 | EXPORT_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? */ |
| 69 | int __cpuinit register_cpu_notifier(struct notifier_block *nb) | 69 | int __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 | ||
| 78 | void unregister_cpu_notifier(struct notifier_block *nb) | 82 | void 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 | } |
| 82 | EXPORT_SYMBOL(unregister_cpu_notifier); | 88 | EXPORT_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 | ||
| 228 | out_notify: | 234 | out_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; |
