diff options
Diffstat (limited to 'kernel/cpu.c')
| -rw-r--r-- | kernel/cpu.c | 26 |
1 files changed, 6 insertions, 20 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 25bba73b1be3..545777574779 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
| @@ -164,6 +164,7 @@ static inline void check_for_tasks(int cpu) | |||
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | struct take_cpu_down_param { | 166 | struct take_cpu_down_param { |
| 167 | struct task_struct *caller; | ||
| 167 | unsigned long mod; | 168 | unsigned long mod; |
| 168 | void *hcpu; | 169 | void *hcpu; |
| 169 | }; | 170 | }; |
| @@ -172,6 +173,7 @@ struct take_cpu_down_param { | |||
| 172 | static int __ref take_cpu_down(void *_param) | 173 | static int __ref take_cpu_down(void *_param) |
| 173 | { | 174 | { |
| 174 | struct take_cpu_down_param *param = _param; | 175 | struct take_cpu_down_param *param = _param; |
| 176 | unsigned int cpu = (unsigned long)param->hcpu; | ||
| 175 | int err; | 177 | int err; |
| 176 | 178 | ||
| 177 | /* Ensure this CPU doesn't handle any more interrupts. */ | 179 | /* Ensure this CPU doesn't handle any more interrupts. */ |
| @@ -182,6 +184,8 @@ static int __ref take_cpu_down(void *_param) | |||
| 182 | raw_notifier_call_chain(&cpu_chain, CPU_DYING | param->mod, | 184 | raw_notifier_call_chain(&cpu_chain, CPU_DYING | param->mod, |
| 183 | param->hcpu); | 185 | param->hcpu); |
| 184 | 186 | ||
| 187 | if (task_cpu(param->caller) == cpu) | ||
| 188 | move_task_off_dead_cpu(cpu, param->caller); | ||
| 185 | /* Force idle task to run as soon as we yield: it should | 189 | /* Force idle task to run as soon as we yield: it should |
| 186 | immediately notice cpu is offline and die quickly. */ | 190 | immediately notice cpu is offline and die quickly. */ |
| 187 | sched_idle_next(); | 191 | sched_idle_next(); |
| @@ -192,10 +196,10 @@ static int __ref take_cpu_down(void *_param) | |||
| 192 | static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | 196 | static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) |
| 193 | { | 197 | { |
| 194 | int err, nr_calls = 0; | 198 | int err, nr_calls = 0; |
| 195 | cpumask_var_t old_allowed; | ||
| 196 | void *hcpu = (void *)(long)cpu; | 199 | void *hcpu = (void *)(long)cpu; |
| 197 | unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; | 200 | unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; |
| 198 | struct take_cpu_down_param tcd_param = { | 201 | struct take_cpu_down_param tcd_param = { |
| 202 | .caller = current, | ||
| 199 | .mod = mod, | 203 | .mod = mod, |
| 200 | .hcpu = hcpu, | 204 | .hcpu = hcpu, |
| 201 | }; | 205 | }; |
| @@ -206,9 +210,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
| 206 | if (!cpu_online(cpu)) | 210 | if (!cpu_online(cpu)) |
| 207 | return -EINVAL; | 211 | return -EINVAL; |
| 208 | 212 | ||
| 209 | if (!alloc_cpumask_var(&old_allowed, GFP_KERNEL)) | ||
| 210 | return -ENOMEM; | ||
| 211 | |||
| 212 | cpu_hotplug_begin(); | 213 | cpu_hotplug_begin(); |
| 213 | set_cpu_active(cpu, false); | 214 | set_cpu_active(cpu, false); |
| 214 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, | 215 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, |
| @@ -225,10 +226,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
| 225 | goto out_release; | 226 | goto out_release; |
| 226 | } | 227 | } |
| 227 | 228 | ||
| 228 | /* Ensure that we are not runnable on dying cpu */ | ||
| 229 | cpumask_copy(old_allowed, ¤t->cpus_allowed); | ||
| 230 | set_cpus_allowed_ptr(current, cpu_active_mask); | ||
| 231 | |||
| 232 | err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu)); | 229 | err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu)); |
| 233 | if (err) { | 230 | if (err) { |
| 234 | set_cpu_active(cpu, true); | 231 | set_cpu_active(cpu, true); |
| @@ -237,7 +234,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
| 237 | hcpu) == NOTIFY_BAD) | 234 | hcpu) == NOTIFY_BAD) |
| 238 | BUG(); | 235 | BUG(); |
| 239 | 236 | ||
| 240 | goto out_allowed; | 237 | goto out_release; |
| 241 | } | 238 | } |
| 242 | BUG_ON(cpu_online(cpu)); | 239 | BUG_ON(cpu_online(cpu)); |
| 243 | 240 | ||
| @@ -255,8 +252,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
| 255 | 252 | ||
| 256 | check_for_tasks(cpu); | 253 | check_for_tasks(cpu); |
| 257 | 254 | ||
| 258 | out_allowed: | ||
| 259 | set_cpus_allowed_ptr(current, old_allowed); | ||
| 260 | out_release: | 255 | out_release: |
| 261 | cpu_hotplug_done(); | 256 | cpu_hotplug_done(); |
| 262 | if (!err) { | 257 | if (!err) { |
| @@ -264,7 +259,6 @@ out_release: | |||
| 264 | hcpu) == NOTIFY_BAD) | 259 | hcpu) == NOTIFY_BAD) |
| 265 | BUG(); | 260 | BUG(); |
| 266 | } | 261 | } |
| 267 | free_cpumask_var(old_allowed); | ||
| 268 | return err; | 262 | return err; |
| 269 | } | 263 | } |
| 270 | 264 | ||
| @@ -272,9 +266,6 @@ int __ref cpu_down(unsigned int cpu) | |||
| 272 | { | 266 | { |
| 273 | int err; | 267 | int err; |
| 274 | 268 | ||
| 275 | err = stop_machine_create(); | ||
| 276 | if (err) | ||
| 277 | return err; | ||
| 278 | cpu_maps_update_begin(); | 269 | cpu_maps_update_begin(); |
| 279 | 270 | ||
| 280 | if (cpu_hotplug_disabled) { | 271 | if (cpu_hotplug_disabled) { |
| @@ -286,7 +277,6 @@ int __ref cpu_down(unsigned int cpu) | |||
| 286 | 277 | ||
| 287 | out: | 278 | out: |
| 288 | cpu_maps_update_done(); | 279 | cpu_maps_update_done(); |
| 289 | stop_machine_destroy(); | ||
| 290 | return err; | 280 | return err; |
| 291 | } | 281 | } |
| 292 | EXPORT_SYMBOL(cpu_down); | 282 | EXPORT_SYMBOL(cpu_down); |
| @@ -367,9 +357,6 @@ int disable_nonboot_cpus(void) | |||
| 367 | { | 357 | { |
| 368 | int cpu, first_cpu, error; | 358 | int cpu, first_cpu, error; |
| 369 | 359 | ||
| 370 | error = stop_machine_create(); | ||
| 371 | if (error) | ||
| 372 | return error; | ||
| 373 | cpu_maps_update_begin(); | 360 | cpu_maps_update_begin(); |
| 374 | first_cpu = cpumask_first(cpu_online_mask); | 361 | first_cpu = cpumask_first(cpu_online_mask); |
| 375 | /* | 362 | /* |
| @@ -400,7 +387,6 @@ int disable_nonboot_cpus(void) | |||
| 400 | printk(KERN_ERR "Non-boot CPUs are not disabled\n"); | 387 | printk(KERN_ERR "Non-boot CPUs are not disabled\n"); |
| 401 | } | 388 | } |
| 402 | cpu_maps_update_done(); | 389 | cpu_maps_update_done(); |
| 403 | stop_machine_destroy(); | ||
| 404 | return error; | 390 | return error; |
| 405 | } | 391 | } |
| 406 | 392 | ||
