Clang's context analysis reports: hash_native.c:851:2: error: raw_spinlock 'native_tlbie_lock' is not held on every path through here [-Werror,-Wthread-safety-analysis] hash_native.c:868:3: error: releasing raw_spinlock 'native_tlbie_lock' that was not held [-Werror,-Wthread-safety-analysis]
This patch reworks the native_flush_hash_range() function to remove the conditional locking. It fixes the clang context analysis reported errors. However, this also simplifies the code in native_flush_hash_range() due to various if conditions. No functional change intended. Signed-off-by: Ritesh Harjani (IBM) <[email protected]> --- arch/powerpc/mm/book3s64/hash_native.c | 88 ++++++++++++++++---------- 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/arch/powerpc/mm/book3s64/hash_native.c b/arch/powerpc/mm/book3s64/hash_native.c index 6bad0545b57a..9b4eea35b540 100644 --- a/arch/powerpc/mm/book3s64/hash_native.c +++ b/arch/powerpc/mm/book3s64/hash_native.c @@ -792,6 +792,54 @@ static notrace void native_hpte_clear(void) asm volatile("eieio; tlbsync; ptesync":::"memory"); } +static void native_flush_hash_range_tlbiel(struct ppc64_tlb_batch *batch, + unsigned long number) +{ + unsigned long vpn = 0, index, shift; + real_pte_t pte; + unsigned long psize = batch->psize; + int ssize = batch->ssize; + unsigned long i; + + asm volatile("ptesync":::"memory"); + for (i = 0; i < number; i++) { + vpn = batch->vpn[i]; + pte = batch->pte[i]; + + pte_iterate_hashed_subpages(pte, psize, + vpn, index, shift) { + __tlbiel(vpn, psize, psize, ssize); + } pte_iterate_hashed_end(); + } + ppc_after_tlbiel_barrier(); +} + +static void native_flush_hash_range_tlbie(struct ppc64_tlb_batch *batch, + unsigned long number) +{ + unsigned long vpn = 0, index, shift; + real_pte_t pte; + unsigned long psize = batch->psize; + int ssize = batch->ssize; + unsigned long i; + + asm volatile("ptesync":::"memory"); + for (i = 0; i < number; i++) { + vpn = batch->vpn[i]; + pte = batch->pte[i]; + + pte_iterate_hashed_subpages(pte, psize, + vpn, index, shift) { + __tlbie(vpn, psize, psize, ssize); + } pte_iterate_hashed_end(); + } + /* + * Just do one more with the last used values. + */ + fixup_tlbie_vpn(vpn, psize, psize, ssize); + asm volatile("eieio; tlbsync; ptesync":::"memory"); +} + /* * Batched hash table flush, we batch the tlbie's to avoid taking/releasing * the lock all the time @@ -845,41 +893,13 @@ static void native_flush_hash_range(unsigned long number, int local) if (mmu_has_feature(MMU_FTR_TLBIEL) && mmu_psize_defs[psize].tlbiel && local) { - asm volatile("ptesync":::"memory"); - for (i = 0; i < number; i++) { - vpn = batch->vpn[i]; - pte = batch->pte[i]; - - pte_iterate_hashed_subpages(pte, psize, - vpn, index, shift) { - __tlbiel(vpn, psize, psize, ssize); - } pte_iterate_hashed_end(); - } - ppc_after_tlbiel_barrier(); + native_flush_hash_range_tlbiel(batch, number); + } else if (!mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE)) { + raw_spin_lock(&native_tlbie_lock); + native_flush_hash_range_tlbie(batch, number); + raw_spin_unlock(&native_tlbie_lock); } else { - int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); - - if (lock_tlbie) - raw_spin_lock(&native_tlbie_lock); - - asm volatile("ptesync":::"memory"); - for (i = 0; i < number; i++) { - vpn = batch->vpn[i]; - pte = batch->pte[i]; - - pte_iterate_hashed_subpages(pte, psize, - vpn, index, shift) { - __tlbie(vpn, psize, psize, ssize); - } pte_iterate_hashed_end(); - } - /* - * Just do one more with the last used values. - */ - fixup_tlbie_vpn(vpn, psize, psize, ssize); - asm volatile("eieio; tlbsync; ptesync":::"memory"); - - if (lock_tlbie) - raw_spin_unlock(&native_tlbie_lock); + native_flush_hash_range_tlbie(batch, number); } local_irq_restore(flags); -- 2.39.5
