summaryrefslogtreecommitdiff
path: root/kernel/softirq.c
diff options
context:
space:
mode:
authorSatoru Takeuchi <takeuchi_satoru@jp.fujitsu.com>2007-07-15 23:39:48 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 09:05:41 -0700
commit1c6b4aa94576eee6dec3b8011f60d7f666db90b0 (patch)
tree68d94f262f47d555e90c764b49bb0925e5e43fca /kernel/softirq.c
parent85653af7d488702165eba72c6c1dd0250fae4e70 (diff)
downloadlwn-1c6b4aa94576eee6dec3b8011f60d7f666db90b0.tar.gz
lwn-1c6b4aa94576eee6dec3b8011f60d7f666db90b0.zip
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>
Diffstat (limited to 'kernel/softirq.c')
-rw-r--r--kernel/softirq.c6
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,
kthread_bind(per_cpu(ksoftirqd, hotcpu),
any_online_cpu(cpu_online_map));
case CPU_DEAD:
- case CPU_DEAD_FROZEN:
+ case CPU_DEAD_FROZEN: {
+ struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
+
p = per_cpu(ksoftirqd, hotcpu);
per_cpu(ksoftirqd, hotcpu) = NULL;
+ sched_setscheduler(p, SCHED_FIFO, &param);
kthread_stop(p);
takeover_tasklets(hotcpu);
break;
+ }
#endif /* CONFIG_HOTPLUG_CPU */
}
return NOTIFY_OK;