x86/mm: Stop calling leave_mm() in idle code
authorAndy Lutomirski <luto@kernel.org>
Thu, 29 Jun 2017 15:53:18 +0000 (08:53 -0700)
committerIngo Molnar <mingo@kernel.org>
Wed, 5 Jul 2017 08:52:57 +0000 (10:52 +0200)
Now that lazy TLB suppresses all flush IPIs (as opposed to all but
the first), there's no need to leave_mm() when going idle.

This means we can get rid of the rcuidle hack in
switch_mm_irqs_off() and we can unexport leave_mm().

This also removes acpi_unlazy_tlb() from the x86 and ia64 headers,
since it has no callers any more.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Reviewed-by: Nadav Amit <nadav.amit@gmail.com>
Reviewed-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: linux-mm@kvack.org
Link: http://lkml.kernel.org/r/03c699cfd6021e467be650d6b73deaccfe4b4bd7.1498751203.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/ia64/include/asm/acpi.h
arch/x86/include/asm/acpi.h
arch/x86/mm/tlb.c
drivers/acpi/processor_idle.c
drivers/idle/intel_idle.c

index a3d0211970e95e5152edbaeeecd8ab3a42041ac6..c86a947f5368633b86d1a8e5dc7ddd1803982c64 100644 (file)
@@ -112,8 +112,6 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf)
        buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
 }
 
-#define acpi_unlazy_tlb(x)
-
 #ifdef CONFIG_ACPI_NUMA
 extern cpumask_t early_cpu_possible_map;
 #define for_each_possible_early_cpu(cpu)  \
index 2efc768e43627a48118d28729c380c0fbcaa7681..562286fa151f3e40f3d220925010b41fd2320309 100644 (file)
@@ -150,8 +150,6 @@ static inline void disable_acpi(void) { }
 extern int x86_acpi_numa_init(void);
 #endif /* CONFIG_ACPI_NUMA */
 
-#define acpi_unlazy_tlb(x)     leave_mm(x)
-
 #ifdef CONFIG_ACPI_APEI
 static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
 {
index 0982c997d36f2d6835b8f3a19d4221f2ce031408..2c1b8881e9d381a4b61724f08fd3a3553887f65e 100644 (file)
@@ -50,7 +50,6 @@ void leave_mm(int cpu)
 
        switch_mm(NULL, &init_mm, NULL);
 }
-EXPORT_SYMBOL_GPL(leave_mm);
 
 void switch_mm(struct mm_struct *prev, struct mm_struct *next,
               struct task_struct *tsk)
@@ -117,15 +116,8 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
                        this_cpu_write(cpu_tlbstate.ctxs[0].tlb_gen,
                                       next_tlb_gen);
                        write_cr3(__pa(next->pgd));
-
-                       /*
-                        * This gets called via leave_mm() in the idle path
-                        * where RCU functions differently.  Tracing normally
-                        * uses RCU, so we have to call the tracepoint
-                        * specially here.
-                        */
-                       trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH,
-                                               TLB_FLUSH_ALL);
+                       trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH,
+                                       TLB_FLUSH_ALL);
                }
 
                /*
@@ -167,13 +159,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
                this_cpu_write(cpu_tlbstate.loaded_mm, next);
                write_cr3(__pa(next->pgd));
 
-               /*
-                * This gets called via leave_mm() in the idle path where RCU
-                * functions differently.  Tracing normally uses RCU, so we
-                * have to call the tracepoint specially here.
-                */
-               trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH,
-                                       TLB_FLUSH_ALL);
+               trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
        }
 
        load_mm_cr4(next);
index 5c8aa9cf62d70de12b240e62887aaf59311e4a99..fe3d2a40f3111bea5440f00ee25ba92df0ef3e64 100644 (file)
@@ -708,8 +708,6 @@ static DEFINE_RAW_SPINLOCK(c3_lock);
 static void acpi_idle_enter_bm(struct acpi_processor *pr,
                               struct acpi_processor_cx *cx, bool timer_bc)
 {
-       acpi_unlazy_tlb(smp_processor_id());
-
        /*
         * Must be done before busmaster disable as we might need to
         * access HPET !
index 216d7ec88c0c7d55eca7ef198a53fb754da3c182..2ae43f59091df5760d638d8f8d94f121cea6696c 100644 (file)
@@ -912,16 +912,15 @@ static __cpuidle int intel_idle(struct cpuidle_device *dev,
        struct cpuidle_state *state = &drv->states[index];
        unsigned long eax = flg2MWAIT(state->flags);
        unsigned int cstate;
-       int cpu = smp_processor_id();
 
        cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
 
        /*
-        * leave_mm() to avoid costly and often unnecessary wakeups
-        * for flushing the user TLB's associated with the active mm.
+        * NB: if CPUIDLE_FLAG_TLB_FLUSHED is set, this idle transition
+        * will probably flush the TLB.  It's not guaranteed to flush
+        * the TLB, though, so it's not clear that we can do anything
+        * useful with this knowledge.
         */
-       if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED)
-               leave_mm(cpu);
 
        if (!(lapic_timer_reliable_states & (1 << (cstate))))
                tick_broadcast_enter();