Patchwork sparc64: Don't pass a pointer to xcall_flush_tlb_pending

login
register
mail settings
Submitter Dave Kleikamp
Date April 19, 2013, 5:40 p.m.
Message ID <517181A3.5090905@oracle.com>
Download mbox | patch
Permalink /patch/238072/
State RFC
Delegated to: David Miller
Headers show

Comments

Dave Kleikamp - April 19, 2013, 5:40 p.m.
Here's a lightly-tested incremental patch to yours that limits
smp_flush_tlb_page's  cross calls to the mm's active set.

Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>

--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/arch/sparc/include/asm/tlbflush_64.h b/arch/sparc/include/asm/tlbflush_64.h
index d4b56bb..f3c8a0f 100644
--- a/arch/sparc/include/asm/tlbflush_64.h
+++ b/arch/sparc/include/asm/tlbflush_64.h
@@ -54,21 +54,21 @@  do {	flush_tsb_kernel_range(start,end); \
 	__flush_tlb_kernel_range(start,end); \
 } while (0)
 
-#define global_flush_tlb_page(context, vaddr) \
-	__flush_tlb_page(context, vaddr)
+#define global_flush_tlb_page(mm, vaddr) \
+	__flush_tlb_page(CTX_HWBITS((mm)->context), vaddr)
 
 #else /* CONFIG_SMP */
 
 extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
-extern void smp_flush_tlb_page(unsigned long context, unsigned long vaddr);
+extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr);
 
 #define flush_tlb_kernel_range(start, end) \
 do {	flush_tsb_kernel_range(start,end); \
 	smp_flush_tlb_kernel_range(start, end); \
 } while (0)
 
-#define global_flush_tlb_page(context, vaddr) \
-	smp_flush_tlb_page(context, vaddr)
+#define global_flush_tlb_page(mm, vaddr) \
+	smp_flush_tlb_page(mm, vaddr)
 
 #endif /* ! CONFIG_SMP */
 
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 33bd996..1dee6e9 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1108,10 +1108,16 @@  void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long
 	put_cpu();
 }
 
-void smp_flush_tlb_page(unsigned long context, unsigned long vaddr)
+void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr)
 {
-	smp_cross_call(&xcall_flush_tlb_page,
-		       context, vaddr, 0);
+	unsigned long context = CTX_HWBITS(mm->context);
+	int cpu = get_cpu();
+
+	if (mm == current->mm && atomic_read(&mm->mm_users) == 1)
+		cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
+	else
+		smp_cross_call(&xcall_flush_tlb_page, context, vaddr, 0);
+
 	__flush_tlb_page(context, vaddr);
 }
 
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
index 26ddb58..1e31b30 100644
--- a/arch/sparc/mm/tlb.c
+++ b/arch/sparc/mm/tlb.c
@@ -77,7 +77,7 @@  static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
 	}
 
 	if (!tb->active) {
-		global_flush_tlb_page(CTX_HWBITS(mm->context), vaddr);
+		global_flush_tlb_page(mm, vaddr);
 		flush_tsb_user_page(mm, vaddr);
 		return;
 	}