summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorZwane Mwaikambo <zwane@arm.linux.org.uk>2005-03-07 17:53:55 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-03-07 17:53:55 -0800
commit20b0bb36b2cf703fecc5a8bbbcdc126642cd44c7 (patch)
treea9f1acd9fec1ca8303b2d4b854ba8ae10b16ca27 /kernel
parentad87b3750efcaf5ceffd82d10dbf4bc1d267d69e (diff)
[PATCH] Run softirqs on proper processor on offline
We take down ksoftirqds at CPU_DEAD time, so there is a brief period whereupon there is a ksoftirqd thread for an offline processor, it is at this point that ->cpus_allowed won't have it pinned anymore. An online processor would then take down that ksoftirqd and exit it. Ensure that we only offline the processor when it's safe and never run softirqs in another processor's ksoftirqd context. This also gets rid of the warnings in ksoftirqd on cpu offline. Signed-off-by: Zwane Mwaikambo <zwane@arm.linux.org.uk> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/softirq.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 582a1e8091bc..b4ab6af1dea8 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -355,8 +355,12 @@ static int ksoftirqd(void * __bind_cpu)
set_current_state(TASK_INTERRUPTIBLE);
while (!kthread_should_stop()) {
- if (!local_softirq_pending())
+ preempt_disable();
+ if (!local_softirq_pending()) {
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
+ }
__set_current_state(TASK_RUNNING);
@@ -364,14 +368,14 @@ static int ksoftirqd(void * __bind_cpu)
/* Preempt disable stops cpu going offline.
If already offline, we'll be on wrong CPU:
don't process */
- preempt_disable();
if (cpu_is_offline((long)__bind_cpu))
goto wait_to_die;
do_softirq();
- preempt_enable();
+ preempt_enable_no_resched();
cond_resched();
+ preempt_disable();
}
-
+ preempt_enable();
set_current_state(TASK_INTERRUPTIBLE);
}
__set_current_state(TASK_RUNNING);