diff options
author | Satoru Takeuchi <takeuchi_satoru@jp.fujitsu.com> | 2007-07-16 02:39:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-16 12:05:41 -0400 |
commit | 1c6b4aa94576eee6dec3b8011f60d7f666db90b0 (patch) | |
tree | 68d94f262f47d555e90c764b49bb0925e5e43fca | |
parent | 85653af7d488702165eba72c6c1dd0250fae4e70 (diff) |
cpu hotplug: fix ksoftirqd termination on cpu hotplug with naughty realtime process
Fix ksoftirqd termination on cpu hotplug with naughty real time process.
Assuming the following case:
- Try to hot remove CPU2 from CPU1.
- There is a real time process on CPU2, and that process doesn't sleep at all.
- That rt process and ksoftirqd/2 is migrated to the CPU0
Then ksoftirqd/2 can't stop becasue that rt process runs everlastingly on
CPU0, and CPU1 waiting the ksoftirqd/2's termination hangs up. To fix this
problem, set the priority of ksoftirqd/2 to max one before kthread_stop().
[akpm@linux-foundation.org: fix warning]
Signed-off-by: Satoru Takeuchi <takeuchi_satoru@jp.fujitsu.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | kernel/softirq.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c index 73217a9e2875..8de267790166 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -614,12 +614,16 @@ static int __cpuinit cpu_callback(struct notifier_block *nfb, | |||
614 | kthread_bind(per_cpu(ksoftirqd, hotcpu), | 614 | kthread_bind(per_cpu(ksoftirqd, hotcpu), |
615 | any_online_cpu(cpu_online_map)); | 615 | any_online_cpu(cpu_online_map)); |
616 | case CPU_DEAD: | 616 | case CPU_DEAD: |
617 | case CPU_DEAD_FROZEN: | 617 | case CPU_DEAD_FROZEN: { |
618 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; | ||
619 | |||
618 | p = per_cpu(ksoftirqd, hotcpu); | 620 | p = per_cpu(ksoftirqd, hotcpu); |
619 | per_cpu(ksoftirqd, hotcpu) = NULL; | 621 | per_cpu(ksoftirqd, hotcpu) = NULL; |
622 | sched_setscheduler(p, SCHED_FIFO, ¶m); | ||
620 | kthread_stop(p); | 623 | kthread_stop(p); |
621 | takeover_tasklets(hotcpu); | 624 | takeover_tasklets(hotcpu); |
622 | break; | 625 | break; |
626 | } | ||
623 | #endif /* CONFIG_HOTPLUG_CPU */ | 627 | #endif /* CONFIG_HOTPLUG_CPU */ |
624 | } | 628 | } |
625 | return NOTIFY_OK; | 629 | return NOTIFY_OK; |