Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

locking/percpu-rwsem: Trigger contention tracepoints only if contended

We mistakenly always fire lock contention tracepoints in the writer path,
while it should be conditional on the trylock result.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Waiman Long <longman@redhat.com>
Link: https://lore.kernel.org/r/20231108215322.2845536-1-namhyung@kernel.org

authored by

Namhyung Kim and committed by
Ingo Molnar
f3e3620f f22f7132

+8 -3
+8 -3
kernel/locking/percpu-rwsem.c
··· 223 223 224 224 void __sched percpu_down_write(struct percpu_rw_semaphore *sem) 225 225 { 226 + bool contended = false; 227 + 226 228 might_sleep(); 227 229 rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_); 228 - trace_contention_begin(sem, LCB_F_PERCPU | LCB_F_WRITE); 229 230 230 231 /* Notify readers to take the slow path. */ 231 232 rcu_sync_enter(&sem->rss); ··· 235 234 * Try set sem->block; this provides writer-writer exclusion. 236 235 * Having sem->block set makes new readers block. 237 236 */ 238 - if (!__percpu_down_write_trylock(sem)) 237 + if (!__percpu_down_write_trylock(sem)) { 238 + trace_contention_begin(sem, LCB_F_PERCPU | LCB_F_WRITE); 239 239 percpu_rwsem_wait(sem, /* .reader = */ false); 240 + contended = true; 241 + } 240 242 241 243 /* smp_mb() implied by __percpu_down_write_trylock() on success -- D matches A */ 242 244 ··· 251 247 252 248 /* Wait for all active readers to complete. */ 253 249 rcuwait_wait_event(&sem->writer, readers_active_check(sem), TASK_UNINTERRUPTIBLE); 254 - trace_contention_end(sem, 0); 250 + if (contended) 251 + trace_contention_end(sem, 0); 255 252 } 256 253 EXPORT_SYMBOL_GPL(percpu_down_write); 257 254