diff options
author | Paul Mackerras <paulus@samba.org> | 2004-08-22 22:31:55 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-22 22:31:55 -0700 |
commit | 8861f2cb3e6e254ec4e5b56768b1bc179b003903 (patch) | |
tree | 2ade9c710dabf127ca2a18e2b792a4a57133eed7 /arch | |
parent | 7d2d3531e457993f49d3d57edd5c540d62928ce1 (diff) | |
download | history-8861f2cb3e6e254ec4e5b56768b1bc179b003903.tar.gz |
[PATCH] ppc64: Don't call scheduler on offline cpu
When taking a cpu offline, once the cpu has been removed from
cpu_online_map, it is not supposed to service any more interrupts. This
presents a problem on ppc64 because we cannot truly disable the
decrementer. There used to be cpu_is_offline() checks in several scheduler
functions (e.g. rebalance_tick()) which papered over this issue, but these
checks were removed recently. So with recent 2.6 kernels, an attempt to
offline a cpu can result in a crash in find_busiest_group(). This patch
prevents such crashes.
Signed-off-by: Nathan Lynch <nathanl@austin.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ppc64/kernel/time.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 132ab3747e72e5..7177572c4755a4 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -48,6 +48,7 @@ #include <linux/time.h> #include <linux/init.h> #include <linux/profile.h> +#include <linux/cpu.h> #include <asm/segment.h> #include <asm/io.h> @@ -285,8 +286,20 @@ int timer_interrupt(struct pt_regs * regs) while (lpaca->next_jiffy_update_tb <= (cur_tb = get_tb())) { #ifdef CONFIG_SMP - smp_local_timer_interrupt(regs); + /* + * We cannot disable the decrementer, so in the period + * between this cpu's being marked offline in cpu_online_map + * and calling stop-self, it is taking timer interrupts. + * Avoid calling into the scheduler rebalancing code if this + * is the case. + */ + if (!cpu_is_offline(cpu)) + smp_local_timer_interrupt(regs); #endif + /* + * No need to check whether cpu is offline here; boot_cpuid + * should have been fixed up by now. + */ if (cpu == boot_cpuid) { write_seqlock(&xtime_lock); tb_last_stamp = lpaca->next_jiffy_update_tb; |