diff options
| -rw-r--r-- | arch/ia64/include/asm/acpi.h | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/acpi.h | 2 | ||||
| -rw-r--r-- | arch/x86/mm/tlb.c | 17 | ||||
| -rw-r--r-- | drivers/acpi/processor_idle.c | 2 | ||||
| -rw-r--r-- | drivers/idle/intel_idle.c | 9 |
5 files changed, 25 insertions, 7 deletions
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index c86a947f5368..a3d0211970e9 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h | |||
| @@ -112,6 +112,8 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf) | |||
| 112 | buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; | 112 | buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | #define acpi_unlazy_tlb(x) | ||
| 116 | |||
| 115 | #ifdef CONFIG_ACPI_NUMA | 117 | #ifdef CONFIG_ACPI_NUMA |
| 116 | extern cpumask_t early_cpu_possible_map; | 118 | extern cpumask_t early_cpu_possible_map; |
| 117 | #define for_each_possible_early_cpu(cpu) \ | 119 | #define for_each_possible_early_cpu(cpu) \ |
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 72d867f6b518..8d0ec9df1cbe 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
| @@ -150,6 +150,8 @@ static inline void disable_acpi(void) { } | |||
| 150 | extern int x86_acpi_numa_init(void); | 150 | extern int x86_acpi_numa_init(void); |
| 151 | #endif /* CONFIG_ACPI_NUMA */ | 151 | #endif /* CONFIG_ACPI_NUMA */ |
| 152 | 152 | ||
| 153 | #define acpi_unlazy_tlb(x) leave_mm(x) | ||
| 154 | |||
| 153 | #ifdef CONFIG_ACPI_APEI | 155 | #ifdef CONFIG_ACPI_APEI |
| 154 | static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr) | 156 | static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr) |
| 155 | { | 157 | { |
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 0f3d0cea4d00..3118392cdf75 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c | |||
| @@ -85,6 +85,7 @@ void leave_mm(int cpu) | |||
| 85 | 85 | ||
| 86 | switch_mm(NULL, &init_mm, NULL); | 86 | switch_mm(NULL, &init_mm, NULL); |
| 87 | } | 87 | } |
| 88 | EXPORT_SYMBOL_GPL(leave_mm); | ||
| 88 | 89 | ||
| 89 | void switch_mm(struct mm_struct *prev, struct mm_struct *next, | 90 | void switch_mm(struct mm_struct *prev, struct mm_struct *next, |
| 90 | struct task_struct *tsk) | 91 | struct task_struct *tsk) |
| @@ -195,12 +196,22 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, | |||
| 195 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id); | 196 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id); |
| 196 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen); | 197 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen); |
| 197 | write_cr3(build_cr3(next, new_asid)); | 198 | write_cr3(build_cr3(next, new_asid)); |
| 198 | trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, | 199 | |
| 199 | TLB_FLUSH_ALL); | 200 | /* |
| 201 | * NB: This gets called via leave_mm() in the idle path | ||
| 202 | * where RCU functions differently. Tracing normally | ||
| 203 | * uses RCU, so we need to use the _rcuidle variant. | ||
| 204 | * | ||
| 205 | * (There is no good reason for this. The idle code should | ||
| 206 | * be rearranged to call this before rcu_idle_enter().) | ||
| 207 | */ | ||
| 208 | trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL); | ||
| 200 | } else { | 209 | } else { |
| 201 | /* The new ASID is already up to date. */ | 210 | /* The new ASID is already up to date. */ |
| 202 | write_cr3(build_cr3_noflush(next, new_asid)); | 211 | write_cr3(build_cr3_noflush(next, new_asid)); |
| 203 | trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, 0); | 212 | |
| 213 | /* See above wrt _rcuidle. */ | ||
| 214 | trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, 0); | ||
| 204 | } | 215 | } |
| 205 | 216 | ||
| 206 | this_cpu_write(cpu_tlbstate.loaded_mm, next); | 217 | this_cpu_write(cpu_tlbstate.loaded_mm, next); |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 2736e25e9dc6..d50a7b6ccddd 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -710,6 +710,8 @@ static DEFINE_RAW_SPINLOCK(c3_lock); | |||
| 710 | static void acpi_idle_enter_bm(struct acpi_processor *pr, | 710 | static void acpi_idle_enter_bm(struct acpi_processor *pr, |
| 711 | struct acpi_processor_cx *cx, bool timer_bc) | 711 | struct acpi_processor_cx *cx, bool timer_bc) |
| 712 | { | 712 | { |
| 713 | acpi_unlazy_tlb(smp_processor_id()); | ||
| 714 | |||
| 713 | /* | 715 | /* |
| 714 | * Must be done before busmaster disable as we might need to | 716 | * Must be done before busmaster disable as we might need to |
| 715 | * access HPET ! | 717 | * access HPET ! |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 5dc7ea4b6bc4..f0b06b14e782 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
| @@ -913,15 +913,16 @@ static __cpuidle int intel_idle(struct cpuidle_device *dev, | |||
| 913 | struct cpuidle_state *state = &drv->states[index]; | 913 | struct cpuidle_state *state = &drv->states[index]; |
| 914 | unsigned long eax = flg2MWAIT(state->flags); | 914 | unsigned long eax = flg2MWAIT(state->flags); |
| 915 | unsigned int cstate; | 915 | unsigned int cstate; |
| 916 | int cpu = smp_processor_id(); | ||
| 916 | 917 | ||
| 917 | cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1; | 918 | cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1; |
| 918 | 919 | ||
| 919 | /* | 920 | /* |
| 920 | * NB: if CPUIDLE_FLAG_TLB_FLUSHED is set, this idle transition | 921 | * leave_mm() to avoid costly and often unnecessary wakeups |
| 921 | * will probably flush the TLB. It's not guaranteed to flush | 922 | * for flushing the user TLB's associated with the active mm. |
| 922 | * the TLB, though, so it's not clear that we can do anything | ||
| 923 | * useful with this knowledge. | ||
| 924 | */ | 923 | */ |
| 924 | if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED) | ||
| 925 | leave_mm(cpu); | ||
| 925 | 926 | ||
| 926 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) | 927 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) |
| 927 | tick_broadcast_enter(); | 928 | tick_broadcast_enter(); |
