[IA64] - Avoid slow TLB purges on SGI Altix systems

flush_tlb_all() can be a scaling issue on large SGI Altix systems
since it uses the global call_lock and always executes on all cpus.
When a process enters flush_tlb_range() to purge TLBs for another
process, it is possible to avoid flush_tlb_all() and instead allow
sn2_global_tlb_purge() to purge TLBs only where necessary.

This patch modifies flush_tlb_range() so that this case can be handled
by platform TLB purge functions and updates ia64_global_tlb_purge()
accordingly.  sn2_global_tlb_purge() now calculates the region register
value from the mm argument introduced with this patch.

Signed-off-by: Dean Roe <roe@sgi.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
This commit is contained in:
Dean Roe
2005-10-27 15:41:04 -05:00
committed by Tony Luck
parent 72ab373a56
commit c1902aae32
3 changed files with 29 additions and 20 deletions

View File

@@ -86,10 +86,15 @@ wrap_mmu_context (struct mm_struct *mm)
}
void
ia64_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long nbits)
{
static DEFINE_SPINLOCK(ptcg_lock);
if (mm != current->active_mm) {
flush_tlb_all();
return;
}
/* HW requires global serialization of ptc.ga. */
spin_lock(&ptcg_lock);
{
@@ -135,15 +140,12 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
unsigned long size = end - start;
unsigned long nbits;
#ifndef CONFIG_SMP
if (mm != current->active_mm) {
/* this does happen, but perhaps it's not worth optimizing for? */
#ifdef CONFIG_SMP
flush_tlb_all();
#else
mm->context = 0;
#endif
return;
}
#endif
nbits = ia64_fls(size + 0xfff);
while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits))
@@ -153,7 +155,7 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
start &= ~((1UL << nbits) - 1);
# ifdef CONFIG_SMP
platform_global_tlb_purge(start, end, nbits);
platform_global_tlb_purge(mm, start, end, nbits);
# else
do {
ia64_ptcl(start, (nbits<<2));