aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2004-08-22 22:31:55 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-22 22:31:55 -0700
commit8861f2cb3e6e254ec4e5b56768b1bc179b003903 (patch)
tree2ade9c710dabf127ca2a18e2b792a4a57133eed7 /arch
parent7d2d3531e457993f49d3d57edd5c540d62928ce1 (diff)
downloadhistory-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.c15
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;