linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Nicholas Piggin <npiggin@gmail.com>
To: linuxppc-dev@lists.ozlabs.org,
	"Aneesh Kumar K . V" <aneesh.kumar@linux.vnet.ibm.com>,
	Nicholas Piggin <npiggin@gmail.com>
Subject: [RFC PATCH 6/7] powerpc/64s/radix: reset mm_cpumask for single thread process when possible
Date: Tue, 31 Oct 2017 18:18:27 +1100	[thread overview]
Message-ID: <20171031071828.28448-1-npiggin@gmail.com> (raw)
In-Reply-To: <20171031064432.25190-1-npiggin@gmail.com>

When a single-threaded process has a non-local mm_cpumask and requires
a full PID tlbie invalidation, use that as an opportunity to reset the
cpumask back to the current CPU we're running on.

There is a lot of tuning we can do with this, and more sophisticated
management of PIDs and stale translations across CPUs, but this is
something simple that can be done to significantly help single threaded
processes without changing behaviour too much.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/mmu_context.h | 19 +++++++++++++
 arch/powerpc/mm/tlb-radix.c            | 52 +++++++++++++++++++++++++++-------
 2 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index 20eae6f76247..05516027fd82 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -5,6 +5,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
+#include <linux/sched/mm.h>
 #include <linux/spinlock.h>
 #include <asm/mmu.h>	
 #include <asm/cputable.h>
@@ -153,6 +154,24 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
 static inline void enter_lazy_tlb(struct mm_struct *mm,
 				  struct task_struct *tsk)
 {
+#ifdef CONFIG_PPC_BOOK3S_64
+	/*
+	 * Under radix, we do not want to keep lazy PIDs around because
+	 * even if the CPU does not access userspace, it can still bring
+	 * in translations through speculation and prefetching.
+	 *
+	 * Switching away here allows us to trim back the mm_cpumask in
+	 * cases where we know the process is not running on some CPUs
+	 * (see mm/tlb-radix.c).
+	 */
+	if (radix_enabled() && mm != &init_mm) {
+		mmgrab(&init_mm);
+		tsk->active_mm = &init_mm;
+		switch_mm_irqs_off(mm, tsk->active_mm, tsk);
+		mmdrop(mm);
+	}
+#endif
+
 	/* 64-bit Book3E keeps track of current PGD in the PACA */
 #ifdef CONFIG_PPC_BOOK3E_64
 	get_paca()->pgd = NULL;
diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c
index 49cc581a31cd..db7e696e4faf 100644
--- a/arch/powerpc/mm/tlb-radix.c
+++ b/arch/powerpc/mm/tlb-radix.c
@@ -255,10 +255,18 @@ void radix__flush_tlb_mm(struct mm_struct *mm)
 		return;
 
 	preempt_disable();
-	if (!mm_is_thread_local(mm))
-		_tlbie_pid(pid, RIC_FLUSH_TLB);
-	else
+	if (!mm_is_thread_local(mm)) {
+		if (atomic_read(&mm->mm_users) == 1 && current->mm == mm) {
+			_tlbie_pid(pid, RIC_FLUSH_ALL);
+			atomic_set(&mm->context.active_cpus, 1);
+			cpumask_clear(mm_cpumask(mm));
+			cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+		} else {
+			_tlbie_pid(pid, RIC_FLUSH_TLB);
+		}
+	} else {
 		_tlbiel_pid(pid, RIC_FLUSH_TLB);
+	}
 	preempt_enable();
 }
 EXPORT_SYMBOL(radix__flush_tlb_mm);
@@ -272,10 +280,16 @@ void radix__flush_all_mm(struct mm_struct *mm)
 		return;
 
 	preempt_disable();
-	if (!mm_is_thread_local(mm))
+	if (!mm_is_thread_local(mm)) {
 		_tlbie_pid(pid, RIC_FLUSH_ALL);
-	else
+		if (atomic_read(&mm->mm_users) == 1 && current->mm == mm) {
+			atomic_set(&mm->context.active_cpus, 1);
+			cpumask_clear(mm_cpumask(mm));
+			cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+		}
+	} else {
 		_tlbiel_pid(pid, RIC_FLUSH_ALL);
+	}
 	preempt_enable();
 }
 EXPORT_SYMBOL(radix__flush_all_mm);
@@ -368,10 +382,18 @@ void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 	}
 
 	if (full) {
-		if (local)
+		if (local) {
 			_tlbiel_pid(pid, RIC_FLUSH_TLB);
-		else
-			_tlbie_pid(pid, RIC_FLUSH_TLB);
+		} else {
+			if (atomic_read(&mm->mm_users) == 1 && current->mm == mm) {
+				_tlbie_pid(pid, RIC_FLUSH_ALL);
+				atomic_set(&mm->context.active_cpus, 1);
+				cpumask_clear(mm_cpumask(mm));
+				cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+			} else {
+				_tlbie_pid(pid, RIC_FLUSH_TLB);
+			}
+		}
 	} else {
 		bool hflush = false;
 		unsigned long hstart, hend;
@@ -481,10 +503,18 @@ static inline void __radix__flush_tlb_range_psize(struct mm_struct *mm,
 	}
 
 	if (full) {
-		if (local)
+		if (local) {
 			_tlbiel_pid(pid, also_pwc ? RIC_FLUSH_ALL : RIC_FLUSH_TLB);
-		else
-			_tlbie_pid(pid, also_pwc ? RIC_FLUSH_ALL: RIC_FLUSH_TLB);
+		} else {
+			if (atomic_read(&mm->mm_users) == 1 && current->mm == mm) {
+				_tlbie_pid(pid, RIC_FLUSH_ALL);
+				atomic_set(&mm->context.active_cpus, 1);
+				cpumask_clear(mm_cpumask(mm));
+				cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+			} else {
+				_tlbie_pid(pid, also_pwc ? RIC_FLUSH_ALL : RIC_FLUSH_TLB);
+			}
+		}
 	} else {
 		if (local)
 			_tlbiel_va_range(start, end, pid, page_size, psize, also_pwc);
-- 
2.15.0.rc2

       reply	other threads:[~2017-10-31  7:18 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20171031064432.25190-1-npiggin@gmail.com>
2017-10-31  7:18 ` Nicholas Piggin [this message]
2017-10-31  7:18   ` [RFC PATCH 7/7] powerpc/64s/radix: Only flush local TLB for spurious fault flushes Nicholas Piggin
2017-10-31 23:28   ` [RFC PATCH 6/7] powerpc/64s/radix: reset mm_cpumask for single thread process when possible Nicholas Piggin
2017-11-01  5:09   ` Balbir Singh
2017-11-01  5:16     ` Nicholas Piggin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171031071828.28448-1-npiggin@gmail.com \
    --to=npiggin@gmail.com \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).