diff options
author | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-08-03 18:36:50 +0000 |
---|---|---|
committer | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-08-03 18:36:50 +0000 |
commit | 88d841ccdf48445d22b6a378b6f54f8ea53ab8d4 (patch) | |
tree | 64620759d86c3d4d136e468053d1ad1ec8a8af13 /arch/mips64/kernel/smp.c | |
parent | 268f75a8e5c22c58a216746be2d11958d2ad2146 (diff) |
Fix over enthusiastic tlbflush optimizations.
Diffstat (limited to 'arch/mips64/kernel/smp.c')
-rw-r--r-- | arch/mips64/kernel/smp.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/mips64/kernel/smp.c b/arch/mips64/kernel/smp.c index c72d46276..7ee8b8ec9 100644 --- a/arch/mips64/kernel/smp.c +++ b/arch/mips64/kernel/smp.c @@ -212,12 +212,15 @@ static void flush_tlb_mm_ipi(void *mm) * context on other cpus are invalidated to force a new context allocation * at switch_mm time, should the mm ever be used on other cpus. For * multithreaded address spaces, intercpu interrupts have to be sent. + * Another case where intercpu interrupts are required is when the target + * mm might be active on another cpu (eg debuggers doing the flushes on + * behalf of debugees, kswapd stealing pages from another process etc). * Kanoj 07/00. */ void flush_tlb_mm(struct mm_struct *mm) { - if (atomic_read(&mm->mm_users) != 1) { + if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1); } else { int i; @@ -244,7 +247,7 @@ static void flush_tlb_range_ipi(void *info) void flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - if (atomic_read(&mm->mm_users) != 1) { + if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { struct flush_tlb_data fd; fd.mm = mm; @@ -269,7 +272,7 @@ static void flush_tlb_page_ipi(void *info) void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { - if (atomic_read(&vma->vm_mm->mm_users) != 1) { + if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) { struct flush_tlb_data fd; fd.vma = vma; |