x86/mm/tlb: Only trim the mm_cpumask once a second
Subsystems (2)
Sasha Levin
maintainerPATCH 1/3 x86/mm/tlb: Only trim the mm_cpumask once a second
From: Rik van Riel <[email protected]>
[ Upstream commit 6db2526c1d694c91c6e05e2f186c085e9460f202 ]
Setting and clearing CPU bits in the mm_cpumask is only ever done by the CPU itself, from the context switch code or the TLB flush code.
Synchronization is handled by switch_mm_irqs_off() blocking interrupts.
Sending TLB flush IPIs to CPUs that are in the mm_cpumask, but no longer running the program causes a regression in the will-it-scale tlbflush2 test. This test is contrived, but a large regression here might cause a small regression in some real world workload.
Instead of always sending IPIs to CPUs that are in the mm_cpumask, but no longer running the program, send these IPIs only once a second.
The rest of the time we can skip over CPUs where the loaded_mm is different from the target mm.
--- arch/x86/include/asm/mmu.h | 2 ++ arch/x86/include/asm/mmu_context.h | 1 + arch/x86/include/asm/tlbflush.h | 1 + arch/x86/mm/tlb.c | 35 +++++++++++++++++++++++++++--- 4 files changed, 36 insertions(+), 3 deletions(-)
arch/x86/include/asm/mmu.h +2 -0
@@ -33,6 +33,8 @@ typedef struct {*/ atomic64_t tlb_gen; +unsigned long next_trim_cpumask; +#ifdef CONFIG_MODIFY_LDT_SYSCALL struct rw_semaphore ldt_usr_sem;struct ldt_struct *ldt;
arch/x86/include/asm/mmu_context.h +1 -0
@@ -106,6 +106,7 @@ static inline int init_new_context(struct task_struct *tsk, mm->context.ctx_id =atomic64_inc_return (&last_mm_ctx_id);atomic64_set (&mm->context.tlb_gen,0 ); + mm->context.next_trim_cpumask = jiffies +HZ ;#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS if (cpu_feature_enabled (X86_FEATURE_OSPKE )) {
arch/x86/include/asm/tlbflush.h +1 -0
@@ -207,6 +207,7 @@ struct flush_tlb_info {unsigned int initiating_cpu;u8 stride_shift;u8 freed_tables; +u8 trim_cpumask; };void flush_tlb_local (void );
arch/x86/mm/tlb.c +32 -3
@@ -854,9 +854,36 @@ static void flush_tlb_func(void *info) nr_invalidate); } -static bool tlb_is_not_lazy (int cpu,void *data) +static bool should_flush_tlb (int cpu,void *data) { -return !per_cpu (cpu_tlbstate_shared.is_lazy, cpu); +struct flush_tlb_info *info = data; + +/* Lazy TLB will get flushed at the next context switch. */ +if (per_cpu (cpu_tlbstate_shared.is_lazy, cpu)) +return false; + +/* No mm means kernel memory flush. */ +if (!info->mm) +return true; + +/* The target mm is loaded, and the CPU is not lazy. */ +if (per_cpu (cpu_tlbstate.loaded_mm, cpu) == info->mm) +return true; + +/* In cpumask, but not the loaded mm? Periodically remove by flushing. */ +if (info->trim_cpumask) +return true; + +return false; +} + +static bool should_trim_cpumask (struct mm_struct *mm) +{ +if (time_after (jiffies,READ_ONCE (mm->context.next_trim_cpumask))) { +WRITE_ONCE (mm->context.next_trim_cpumask, jiffies +HZ ); +return true; + } +return false; } DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state_shared, cpu_tlbstate_shared);
@@ -890,7 +917,7 @@ STATIC_NOPV void native_flush_tlb_multi(const struct cpumask *cpumask,if (info->freed_tables)on_each_cpu_mask (cpumask, flush_tlb_func, (void *)info, true);else -on_each_cpu_cond_mask (tlb_is_not_lazy, flush_tlb_func, +on_each_cpu_cond_mask (should_flush_tlb, flush_tlb_func, (void *)info,1 , cpumask); }
@@ -941,6 +968,7 @@ static struct flush_tlb_info *get_flush_tlb_info(struct mm_struct *mm, info->freed_tables = freed_tables; info->new_tlb_gen = new_tlb_gen; info->initiating_cpu =smp_processor_id (); + info->trim_cpumask =0 ;return info; }
@@ -983,6 +1011,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,* flush_tlb_func_local() directly in this case. */ if (cpumask_any_but (mm_cpumask (mm), cpu) < nr_cpu_ids) { + info->trim_cpumask =should_trim_cpumask (mm);flush_tlb_multi (mm_cpumask (mm), info); }else if (mm ==this_cpu_read (cpu_tlbstate.loaded_mm)) {lockdep_assert_irqs_enabled ();
Signature · 1 line
2.39.5
Sasha Levin
maintainerPATCH 2/3 orangefs: fix a oob in orangefs_debug_write
From: Mike Marshall <[email protected]>
[ Upstream commit f7c848431632598ff9bce57a659db6af60d75b39 ]
I got a syzbot report: slab-out-of-bounds Read in orangefs_debug_write... several people suggested fixes, I tested Al Viro's suggestion and made this patch.
--- fs/orangefs/orangefs-debugfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/orangefs/orangefs-debugfs.c +2 -2
@@ -393,9 +393,9 @@ static ssize_t orangefs_debug_write(struct file *file,* Thwart users who try to jamb a ridiculous number * of bytes into the debug file... */ -if (count >ORANGEFS_MAX_DEBUG_STRING_LEN +1 ) { +if (count >ORANGEFS_MAX_DEBUG_STRING_LEN ) { silly = count; - count =ORANGEFS_MAX_DEBUG_STRING_LEN +1 ; + count =ORANGEFS_MAX_DEBUG_STRING_LEN ; } buf =kzalloc (ORANGEFS_MAX_DEBUG_STRING_LEN ,GFP_KERNEL );
Signature · 1 line
2.39.5
Sasha Levin
maintainerPATCH 3/3 ASoC: Intel: bytcr_rt5640: Add DMI quirk for Vexia Edu Atla 10 tablet 5V
In reply to Sasha LevinFrom: Hans de Goede <[email protected]>
[ Upstream commit 6917192378c1ce17ba31df51c4e0d8b1c97a453b ]
The Vexia EDU ATLA 10 tablet comes in 2 different versions with significantly different mainboards. The only outward difference is that the charging barrel on one is marked 5V and the other is marked 9V.
The 5V version mostly works with the BYTCR defaults, except that it is missing a CHAN package in its ACPI tables and the default of using SSP0-AIF2 is wrong, instead SSP0-AIF1 must be used. That and its jack detect signal is not inverted as it usually is.
Add a DMI quirk for the 5V version to fix sound not working.
--- sound/soc/intel/boards/bytcr_rt5640.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
sound/soc/intel/boards/bytcr_rt5640.c +16 -1
@@ -1102,7 +1102,22 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {BYT_RT5640_SSP0_AIF2 | BYT_RT5640_MCLK_EN), }, - { /* Vexia Edu Atla 10 tablet */ + { +/* Vexia Edu Atla 10 tablet 5V version */ + .matches = { +/* Having all 3 of these not set is somewhat unique */ +DMI_MATCH (DMI_SYS_VENDOR ,"To be filled by O.E.M." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"To be filled by O.E.M." ), +DMI_MATCH (DMI_BOARD_NAME ,"To be filled by O.E.M." ), +/* Above strings are too generic, also match on BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "05/14/2015"), + }, + .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | +BYT_RT5640_JD_NOT_INV | +BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, + { /* Vexia Edu Atla 10 tablet 9V version */ .matches = {DMI_MATCH (DMI_BOARD_VENDOR ,"AMI Corporation" ), DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
Signature · 1 line
2.39.5