linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Andy Lutomirski <luto@kernel.org>
To: X86 ML <x86@kernel.org>
Cc: Borislav Petkov <bpetkov@suse.de>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Mel Gorman <mgorman@suse.de>,
	"linux-mm@kvack.org" <linux-mm@kvack.org>,
	Nadav Amit <nadav.amit@gmail.com>, Rik van Riel <riel@redhat.com>,
	Andy Lutomirski <luto@kernel.org>
Subject: [RFC 01/11] x86/ldt: Simplify LDT switching logic
Date: Mon,  5 Jun 2017 15:36:25 -0700	[thread overview]
Message-ID: <a5eb3dead15bcb36732bb5b655ef4ebe23cf4aa3.1496701658.git.luto@kernel.org> (raw)
In-Reply-To: <cover.1496701658.git.luto@kernel.org>
In-Reply-To: <cover.1496701658.git.luto@kernel.org>

We used to switch the LDT if the prev and next mms' LDTs didn't
match.  This was correct but overcomplicated -- it was subject to a
harmless race if prev called modify_ldt() which switching.  It was
also a pointless optimization, since different mms' LDTs are always
different.

Simplify the code to update LDTR if either the previous or the next
mm has an LDT.  While we're at it, clean up the code by moving all
the ifdeffery to a header where it belongs.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 arch/x86/include/asm/mmu_context.h | 23 +++++++++++++++++++++++
 arch/x86/mm/tlb.c                  | 20 ++------------------
 2 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index f20d7ea47095..d59bbfb4c8b4 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -93,6 +93,29 @@ static inline void load_mm_ldt(struct mm_struct *mm)
 #else
 	clear_LDT();
 #endif
+}
+
+static inline void switch_ldt(struct mm_struct *prev, struct mm_struct *next)
+{
+#ifdef CONFIG_MODIFY_LDT_SYSCALL
+	/*
+	 * Load the LDT if either the old or new mm had an LDT.
+	 *
+	 * An mm will never go from having an LDT to not having an LDT.  Two
+	 * mms never share an LDT, so we don't gain anything by checking to
+	 * see whether the LDT changed.  There's also no guarantee that
+	 * prev->context.ldt actually matches LDTR, but, if LDTR is non-NULL,
+	 * then prev->context.ldt will also be non-NULL.
+	 *
+	 * If we really cared, we could optimize the case where prev == next
+	 * and we're existing lazy mode.  Most of the time, if this happens,
+	 * we don't actually need to reload LDTR, but modify_ldt() is mostly
+	 * used by legacy code and emulators where we don't need this level of
+	 * performance.
+	 */
+	if (unlikely(prev->context.ldt || next->context.ldt))
+		load_mm_ldt(next);
+#endif
 
 	DEBUG_LOCKS_WARN_ON(preemptible());
 }
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 2a5e851f2035..b2485d69f7c2 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -148,25 +148,9 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 		     real_prev != &init_mm);
 	cpumask_clear_cpu(cpu, mm_cpumask(real_prev));
 
-	/* Load per-mm CR4 state */
+	/* Load per-mm CR4 and LDTR state */
 	load_mm_cr4(next);
-
-#ifdef CONFIG_MODIFY_LDT_SYSCALL
-	/*
-	 * Load the LDT, if the LDT is different.
-	 *
-	 * It's possible that prev->context.ldt doesn't match
-	 * the LDT register.  This can happen if leave_mm(prev)
-	 * was called and then modify_ldt changed
-	 * prev->context.ldt but suppressed an IPI to this CPU.
-	 * In this case, prev->context.ldt != NULL, because we
-	 * never set context.ldt to NULL while the mm still
-	 * exists.  That means that next->context.ldt !=
-	 * prev->context.ldt, because mms never share an LDT.
-	 */
-	if (unlikely(real_prev->context.ldt != next->context.ldt))
-		load_mm_ldt(next);
-#endif
+	switch_ldt(real_prev, next);
 }
 
 /*
-- 
2.9.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  reply	other threads:[~2017-06-05 22:37 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-05 22:36 [RFC 00/11] PCID and improved laziness Andy Lutomirski
2017-06-05 22:36 ` Andy Lutomirski [this message]
2017-06-05 22:40   ` [RFC 01/11] x86/ldt: Simplify LDT switching logic Linus Torvalds
2017-06-05 22:44     ` Andy Lutomirski
2017-06-05 22:51     ` Linus Torvalds
2017-06-05 22:36 ` [RFC 02/11] x86/mm: Remove reset_lazy_tlbstate() Andy Lutomirski
2017-06-05 22:36 ` [RFC 03/11] x86/mm: Give each mm TLB flush generation a unique ID Andy Lutomirski
2017-06-05 22:36 ` [RFC 04/11] x86/mm: Track the TLB's tlb_gen and update the flushing algorithm Andy Lutomirski
2017-06-06  5:03   ` Nadav Amit
2017-06-06 22:45     ` Andy Lutomirski
2017-06-05 22:36 ` [RFC 05/11] x86/mm: Rework lazy TLB mode and TLB freshness tracking Andy Lutomirski
2017-06-06  1:39   ` Nadav Amit
2017-06-06 21:23     ` Andy Lutomirski
2017-06-06 19:11   ` Rik van Riel
2017-06-06 21:34     ` Andy Lutomirski
2017-06-07  3:33       ` Rik van Riel
2017-06-07  4:54         ` Andy Lutomirski
2017-06-07  5:11           ` Andy Lutomirski
2017-06-05 22:36 ` [RFC 06/11] x86/mm: Stop calling leave_mm() in idle code Andy Lutomirski
2017-06-05 22:36 ` [RFC 07/11] x86/mm: Disable PCID on 32-bit kernels Andy Lutomirski
2017-06-05 22:36 ` [RFC 08/11] x86/mm: Add nopcid to turn off PCID Andy Lutomirski
2017-06-06  3:22   ` Andi Kleen
2017-06-14  4:52     ` Andy Lutomirski
2017-06-14  9:51       ` Borislav Petkov
2017-06-05 22:36 ` [RFC 09/11] x86/mm: Teach CR3 readers about PCID Andy Lutomirski
2017-06-05 22:36 ` [RFC 10/11] x86/mm: Enable CR4.PCIDE on supported systems Andy Lutomirski
2017-06-06 21:31   ` Boris Ostrovsky
2017-06-06 21:35     ` Andy Lutomirski
2017-06-06 21:48       ` Boris Ostrovsky
2017-06-06 21:54         ` Andy Lutomirski
2017-06-05 22:36 ` [RFC 11/11] x86/mm: Try to preserve old TLB entries using PCID Andy Lutomirski

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=a5eb3dead15bcb36732bb5b655ef4ebe23cf4aa3.1496701658.git.luto@kernel.org \
    --to=luto@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=bpetkov@suse.de \
    --cc=linux-mm@kvack.org \
    --cc=mgorman@suse.de \
    --cc=nadav.amit@gmail.com \
    --cc=riel@redhat.com \
    --cc=torvalds@linux-foundation.org \
    --cc=x86@kernel.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).