Message ID | 1493213240-5260-1-git-send-email-mpe@ellerman.id.au (mailing list archive) |
---|---|
State | Accepted |
Commit | 5a9853946c2e7a5ef9ef5302ecada64fbe543565 |
Headers | show |
On Wed, 2017-04-26 at 13:27:19 UTC, Michael Ellerman wrote: > Currently we implement flushing of the page walk cache (PWC) by calling > _tlbiel_pid() with a RIC (Radix Invalidation Control) value of 1 which says to > only flush the PWC. > > But _tlbiel_pid() loops over each set (congruence class) of the TLB, which is > not necessary when we're just flushing the PWC. > > In fact the set argument is ignored for a PWC flush, so essentially we're just > flushing the PWC 127 extra times for no benefit. > > Fix it by adding tlbiel_pwc() which just does a single flush of the PWC. > > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> > [mpe: Split out of combined patch, drop _ in name, rewrite change log] > Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Series applied to powerpc next. https://git.kernel.org/powerpc/c/5a9853946c2e7a5ef9ef5302ecada6 cheers
diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c index b68b5219cf45..ae2e799822bd 100644 --- a/arch/powerpc/mm/tlb-radix.c +++ b/arch/powerpc/mm/tlb-radix.c @@ -53,6 +53,17 @@ static inline void _tlbiel_pid(unsigned long pid, unsigned long ric) asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); } +static inline void tlbiel_pwc(unsigned long pid) +{ + asm volatile("ptesync": : :"memory"); + + /* For PWC flush, we don't look at set number */ + __tlbiel_pid(pid, 0, RIC_FLUSH_PWC); + + asm volatile("ptesync": : :"memory"); + asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); +} + static inline void _tlbie_pid(unsigned long pid, unsigned long ric) { unsigned long rb,rs,prs,r; @@ -140,7 +151,7 @@ void radix__local_flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr) pid = mm->context.id; if (pid != MMU_NO_CONTEXT) - _tlbiel_pid(pid, RIC_FLUSH_PWC); + tlbiel_pwc(pid); preempt_enable(); } @@ -222,7 +233,7 @@ void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr) if (lock_tlbie) raw_spin_unlock(&native_tlbie_lock); } else - _tlbiel_pid(pid, RIC_FLUSH_PWC); + tlbiel_pwc(pid); no_context: preempt_enable(); }