From: Martin Hicks <mort@wildopensource.com>

This is a patch based on one that Jack Steiner sent to the ia64 list in
November.  The original thread can be found at:

http://marc.theaimsgroup.com/?l=linux-ia64&m=106869606922555&w=2

I created the little wrapper function that was requested.  I think the only
other arch, other than ia64, that doesn't at least include asm-generic/tlb.h
is arm.


Something appears broken in TLB flushing on IA64 (& possibly other
architectures).  Functionally, it works but performance is bad on systems
with large cpu counts.

The result is that TLB flushing in exit_mmap() is frequently being done via
IPIs to all cpus rather than with a "ptc" instruction or with a new
context..



---

 include/asm-arm/tlb.h     |    6 ++++++
 include/asm-generic/tlb.h |    5 +++++
 include/asm-ia64/tlb.h    |    6 ++++++
 mm/memory.c               |    3 ++-
 4 files changed, 19 insertions(+), 1 deletion(-)

diff -puN include/asm-arm/tlb.h~tlb-flushing-speedup include/asm-arm/tlb.h
--- 25/include/asm-arm/tlb.h~tlb-flushing-speedup	2004-02-16 23:43:20.000000000 -0800
+++ 25-akpm/include/asm-arm/tlb.h	2004-02-16 23:43:20.000000000 -0800
@@ -70,6 +70,12 @@ tlb_finish_mmu(struct mmu_gather *tlb, u
 	check_pgt_cache();
 }
 
+static inline unsigned int
+tlb_is_full_mm(struct mmu_gather *tlb)
+{
+     return tlb->fullmm;
+}
+
 #define tlb_remove_tlb_entry(tlb,ptep,address)	do { } while (0)
 
 #define tlb_start_vma(tlb,vma)						\
diff -puN include/asm-generic/tlb.h~tlb-flushing-speedup include/asm-generic/tlb.h
--- 25/include/asm-generic/tlb.h~tlb-flushing-speedup	2004-02-16 23:43:20.000000000 -0800
+++ 25-akpm/include/asm-generic/tlb.h	2004-02-16 23:43:20.000000000 -0800
@@ -98,6 +98,11 @@ tlb_finish_mmu(struct mmu_gather *tlb, u
 	check_pgt_cache();
 }
 
+static inline unsigned int
+tlb_is_full_mm(struct mmu_gather *tlb)
+{
+	return tlb->fullmm;
+}
 
 /* tlb_remove_page
  *	Must perform the equivalent to __free_pte(pte_get_and_clear(ptep)), while
diff -puN include/asm-ia64/tlb.h~tlb-flushing-speedup include/asm-ia64/tlb.h
--- 25/include/asm-ia64/tlb.h~tlb-flushing-speedup	2004-02-16 23:43:20.000000000 -0800
+++ 25-akpm/include/asm-ia64/tlb.h	2004-02-16 23:43:20.000000000 -0800
@@ -173,6 +173,12 @@ tlb_finish_mmu (struct mmu_gather *tlb, 
 	check_pgt_cache();
 }
 
+static inline unsigned int
+tlb_is_full_mm(struct mmu_gather *tlb)
+{
+     return tlb->fullmm;
+}
+
 /*
  * Logically, this routine frees PAGE.  On MP machines, the actual freeing of the page
  * must be delayed until after the TLB has been flushed (see comments at the beginning of
diff -puN mm/memory.c~tlb-flushing-speedup mm/memory.c
--- 25/mm/memory.c~tlb-flushing-speedup	2004-02-16 23:43:20.000000000 -0800
+++ 25-akpm/mm/memory.c	2004-02-16 23:43:20.000000000 -0800
@@ -574,9 +574,10 @@ int unmap_vmas(struct mmu_gather **tlbp,
 			if ((long)zap_bytes > 0)
 				continue;
 			if (need_resched()) {
+				int fullmm = tlb_is_full_mm(*tlbp);
 				tlb_finish_mmu(*tlbp, tlb_start, start);
 				cond_resched_lock(&mm->page_table_lock);
-				*tlbp = tlb_gather_mmu(mm, 0);
+				*tlbp = tlb_gather_mmu(mm, fullmm);
 				tlb_start_valid = 0;
 			}
 			zap_bytes = ZAP_BLOCK_SIZE;

_