On Thu, 17 Nov 2022 16:26:47 +0800 Yicong Yang <yangyicong@xxxxxxxxxx> wrote: > From: Anshuman Khandual <khandual@xxxxxxxxxxxxxxxxxx> > > The entire scheme of deferred TLB flush in reclaim path rests on the > fact that the cost to refill TLB entries is less than flushing out > individual entries by sending IPI to remote CPUs. But architecture > can have different ways to evaluate that. Hence apart from checking > TTU_BATCH_FLUSH in the TTU flags, rest of the decision should be > architecture specific. > > ... > > --- a/arch/x86/include/asm/tlbflush.h > +++ b/arch/x86/include/asm/tlbflush.h > @@ -240,6 +240,18 @@ static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long a) > flush_tlb_mm_range(vma->vm_mm, a, a + PAGE_SIZE, PAGE_SHIFT, false); > } > > +static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm) > +{ > + bool should_defer = false; > + > + /* If remote CPUs need to be flushed then defer batch the flush */ > + if (cpumask_any_but(mm_cpumask(mm), get_cpu()) < nr_cpu_ids) > + should_defer = true; > + put_cpu(); > + > + return should_defer; > +} > + > static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) > { > /* > diff --git a/mm/rmap.c b/mm/rmap.c > index 2ec925e5fa6a..a9ab10bc0144 100644 > --- a/mm/rmap.c > +++ b/mm/rmap.c > @@ -685,17 +685,10 @@ static void set_tlb_ubc_flush_pending(struct mm_struct *mm, bool writable) > */ > static bool should_defer_flush(struct mm_struct *mm, enum ttu_flags flags) > { > - bool should_defer = false; > - > if (!(flags & TTU_BATCH_FLUSH)) > return false; > > - /* If remote CPUs need to be flushed then defer batch the flush */ > - if (cpumask_any_but(mm_cpumask(mm), get_cpu()) < nr_cpu_ids) > - should_defer = true; > - put_cpu(); > - > - return should_defer; > + return arch_tlbbatch_should_defer(mm); > } I think this conversion could have been done better. should_defer_flush() is compiled if CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH. So the patch implicitly assumes that only x86 implements CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH. Presently true, but what happens if sparc (for example) wants to set CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH? Now sparc needs its private version of arch_tlbbatch_should_defer(), even if that is identical to x86's. Wouldn't it be better to make arch_tlbbatch_should_defer() a __weak function in rmap.c, or a static inline inside #ifndef ARCH_HAS_ARCH_TLBBATCH_SHOULD_DEFER, or whatever technique best fits?