[RFC 5/6] powerpc/mm: Rework nohash TLB broadcast locking
From: Ritesh Harjani (IBM)
Date: Mon Sep 28 2026 - 06:46:12 EST
Clang's context analysis reports:
mmu_context.c:141:2: error: releasing raw_spinlock 'context_lock' that was not held [-Werror,-Wthread-safety-analysis]
mmu_context.c:147:1: error: raw_spinlock 'context_lock' is not held on every path through here [-Werror,-Wthread-safety-analysis]
tlb.c:257:4: error: raw_spinlock 'tlbivax_lock' is not held on every path through here [-Werror,-Wthread-safety-analysis]
tlb.c:259:5: error: releasing raw_spinlock 'tlbivax_lock' that was not held [-Werror,-Wthread-safety-analysis]
This reworks the locking in __flush_tlb_page() a bit to satisfy clang
context analyzer requirement.
Also steal_context_smp() drops the context_lock, so it needs to be
annotated with __must_hold to inform the clang analyzer that this
function holds the context_lock.
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@xxxxxxxxx>
---
arch/powerpc/mm/nohash/mmu_context.c | 1 +
arch/powerpc/mm/nohash/tlb.c | 8 +++++---
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/mm/nohash/mmu_context.c b/arch/powerpc/mm/nohash/mmu_context.c
index 28a96a10c907..bdbe1f55f388 100644
--- a/arch/powerpc/mm/nohash/mmu_context.c
+++ b/arch/powerpc/mm/nohash/mmu_context.c
@@ -95,6 +95,7 @@ static DEFINE_RAW_SPINLOCK(context_lock);
* -- benh
*/
static unsigned int steal_context_smp(unsigned int id)
+ __must_hold(&context_lock)
{
struct mm_struct *mm;
unsigned int cpu, max, i;
diff --git a/arch/powerpc/mm/nohash/tlb.c b/arch/powerpc/mm/nohash/tlb.c
index 07a2db16c2b1..9297549aef41 100644
--- a/arch/powerpc/mm/nohash/tlb.c
+++ b/arch/powerpc/mm/nohash/tlb.c
@@ -252,11 +252,13 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
/* If broadcast tlbivax is supported, use it */
if (mmu_has_feature(MMU_FTR_USE_TLBIVAX_BCAST)) {
int lock = mmu_has_feature(MMU_FTR_LOCK_BCAST_INVAL);
- if (lock)
+ if (lock) {
raw_spin_lock(&tlbivax_lock);
- _tlbivax_bcast(vmaddr, pid, tsize, ind);
- if (lock)
+ _tlbivax_bcast(vmaddr, pid, tsize, ind);
raw_spin_unlock(&tlbivax_lock);
+ } else {
+ _tlbivax_bcast(vmaddr, pid, tsize, ind);
+ }
goto bail;
} else {
struct tlb_flush_param p = {
--
2.39.5