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 | ||