aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorJack Steiner <steiner@sgi.com>2005-12-15 12:41:22 -0600
committerTony Luck <tony.luck@intel.com>2005-12-16 10:46:25 -0800
commitd74700e604db717eef7a3112176e6350fb00d0e3 (patch)
tree2a8df4baec55fba949d4b02b95c611fe96cdce78 /arch/ia64
parent3bd7f01713f30e7c616ab975ebb84ab7eb58a60a (diff)
downloadkernel_samsung_smdk4412-d74700e604db717eef7a3112176e6350fb00d0e3.zip
kernel_samsung_smdk4412-d74700e604db717eef7a3112176e6350fb00d0e3.tar.gz
kernel_samsung_smdk4412-d74700e604db717eef7a3112176e6350fb00d0e3.tar.bz2
[IA64-SGI] Missed TLB flush
I see why the problem exists only on SN. SN uses a different hardware mechanism to purge TLB entries across nodes. It looks like there is a bug in the SN TLB flushing code. During context switch, kernel threads inherit the mm of the task that was previously running on the cpu. This confuses the code in sn2_global_tlb_purge(). The result is a missed TLB purge for the task that owns the "borrowed" mm. (I hit the problem running heavy stress where kswapd was purging code pages of a user task that woke kswapd. The user task took a SIGILL fault trying to execute code in the page that had been ripped out from underneath it). Signed-off-by: Jack Steiner <steiner@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/sn/kernel/sn2/sn2_smp.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
index 5d54f5f..471bbaa 100644
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
@@ -202,7 +202,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
unsigned long end, unsigned long nbits)
{
int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
- int mymm = (mm == current->active_mm);
+ int mymm = (mm == current->active_mm && current->mm);
volatile unsigned long *ptc0, *ptc1;
unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value;
short nasids[MAX_NUMNODES], nix;