[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190531063645.4697-13-namit@vmware.com>
Date: Thu, 30 May 2019 23:36:45 -0700
From: Nadav Amit <namit@...are.com>
To: Peter Zijlstra <peterz@...radead.org>,
Andy Lutomirski <luto@...nel.org>
Cc: Borislav Petkov <bp@...en8.de>,
Dave Hansen <dave.hansen@...el.com>,
Ingo Molnar <mingo@...hat.com>,
Thomas Gleixner <tglx@...utronix.de>, x86@...nel.org,
linux-kernel@...r.kernel.org, Nadav Amit <namit@...are.com>,
Brian Gerst <brgerst@...il.com>,
"H . Peter Anvin" <hpa@...or.com>, Rik van Riel <riel@...riel.com>
Subject: [RFC PATCH v2 12/12] x86/mm/tlb: Reverting the removal of flush_tlb_info from stack
Partially revert 3db6d5a5eca ("x86/mm/tlb: Remove 'struct
flush_tlb_info' from the stack").
Now that we copy flush_tlb_info and inline it with the IPI information,
we can put it back onto the stack. This simplifies the code and should be
slightly more robust. The stack is also a bit more likely to be cached
than a global variable.
Cc: Peter Zijlstra <peterz@...radead.org>
Cc: Andy Lutomirski <luto@...nel.org>
Cc: Borislav Petkov <bp@...en8.de>
Cc: Brian Gerst <brgerst@...il.com>
Cc: Dave Hansen <dave.hansen@...el.com>
Cc: H. Peter Anvin <hpa@...or.com>
Cc: Rik van Riel <riel@...riel.com>
Cc: Thomas Gleixner <tglx@...utronix.de>
Signed-off-by: Nadav Amit <namit@...are.com>
---
arch/x86/mm/tlb.c | 46 +++++++++++++++++++++++++---------------------
1 file changed, 25 insertions(+), 21 deletions(-)
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index fd7e90adbe43..81170fd6b1dd 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -827,15 +827,17 @@ static inline void put_flush_tlb_info(void)
static void flush_tlb_on_cpus(const cpumask_t *cpumask,
const struct flush_tlb_info *info)
{
- int this_cpu = smp_processor_id();
bool flush_others = false;
+ int this_cpu;
+
+ this_cpu = get_cpu();
if (cpumask_any_but(cpumask, this_cpu) < nr_cpu_ids)
flush_others = true;
if (static_branch_likely(&flush_tlb_multi_enabled) && flush_others) {
flush_tlb_multi(cpumask, info);
- return;
+ goto out;
}
if (cpumask_test_cpu(this_cpu, cpumask)) {
@@ -847,27 +849,33 @@ static void flush_tlb_on_cpus(const cpumask_t *cpumask,
if (flush_others)
flush_tlb_others(cpumask, info);
+
+out:
+ put_cpu();
}
void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
unsigned long end, unsigned int stride_shift,
bool freed_tables)
{
- struct flush_tlb_info *info;
- u64 new_tlb_gen;
+ struct flush_tlb_info info = {
+ .mm = mm,
+ .stride_shift = stride_shift,
+ .freed_tables = freed_tables,
+ };
/* Should we flush just the requested range? */
if ((end == TLB_FLUSH_ALL) ||
((end - start) >> stride_shift) > tlb_single_page_flush_ceiling) {
- start = 0;
- end = TLB_FLUSH_ALL;
+ info.start = 0;
+ info.end = TLB_FLUSH_ALL;
+ } else {
+ info.start = start;
+ info.end = end;
}
/* This is also a barrier that synchronizes with switch_mm(). */
- new_tlb_gen = inc_mm_tlb_gen(mm);
-
- info = get_flush_tlb_info(mm, start, end, stride_shift, freed_tables,
- new_tlb_gen);
+ info.new_tlb_gen = inc_mm_tlb_gen(mm);
/*
* Assert that mm_cpumask() corresponds with the loaded mm. We got one
@@ -878,9 +886,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
(mm == this_cpu_read(cpu_tlbstate.loaded_mm)) ||
mm == &init_mm);
- flush_tlb_on_cpus(mm_cpumask(mm), info);
-
- put_flush_tlb_info();
+ flush_tlb_on_cpus(mm_cpumask(mm), &info);
}
@@ -913,18 +919,18 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
(end - start) > tlb_single_page_flush_ceiling << PAGE_SHIFT) {
on_each_cpu(do_flush_tlb_all, NULL, 1);
} else {
- struct flush_tlb_info *info;
-
- info = get_flush_tlb_info(NULL, start, end, 0, false, 0);
+ struct flush_tlb_info info = {
+ .mm = NULL,
+ .start = start,
+ .end = end,
+ };
/*
* We have to wait for the remote shootdown to be done since it
* is kernel space.
*/
__on_each_cpu_mask(cpu_online_mask, do_kernel_range_flush,
- info, sizeof(*info), 1);
-
- put_flush_tlb_info();
+ &info, sizeof(info), 1);
}
}
@@ -942,9 +948,7 @@ static const struct flush_tlb_info full_flush_tlb_info = {
void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch)
{
- preempt_disable();
flush_tlb_on_cpus(&batch->cpumask, &full_flush_tlb_info);
- preempt_enable();
cpumask_clear(&batch->cpumask);
}
--
2.20.1
Powered by blists - more mailing lists