locking/percpu-rwsem: Trigger contention tracepoints only if contended
authorNamhyung Kim <namhyung@kernel.org>
Wed, 8 Nov 2023 21:53:22 +0000 (13:53 -0800)
committerIngo Molnar <mingo@kernel.org>
Wed, 28 Feb 2024 12:10:29 +0000 (13:10 +0100)
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
kernel/locking/percpu-rwsem.c

index 185bd1c906b0113f3921385bdd00d7950100023c..6083883c4fe09444a5f770eb7ee0f092d1ad8d4e 100644 (file)
@@ -223,9 +223,10 @@ static bool readers_active_check(struct percpu_rw_semaphore *sem)
 
 void __sched percpu_down_write(struct percpu_rw_semaphore *sem)
 {
+       bool contended = false;
+
        might_sleep();
        rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
-       trace_contention_begin(sem, LCB_F_PERCPU | LCB_F_WRITE);
 
        /* Notify readers to take the slow path. */
        rcu_sync_enter(&sem->rss);
@@ -234,8 +235,11 @@ void __sched percpu_down_write(struct percpu_rw_semaphore *sem)
         * Try set sem->block; this provides writer-writer exclusion.
         * Having sem->block set makes new readers block.
         */
-       if (!__percpu_down_write_trylock(sem))
+       if (!__percpu_down_write_trylock(sem)) {
+               trace_contention_begin(sem, LCB_F_PERCPU | LCB_F_WRITE);
                percpu_rwsem_wait(sem, /* .reader = */ false);
+               contended = true;
+       }
 
        /* smp_mb() implied by __percpu_down_write_trylock() on success -- D matches A */
 
@@ -247,7 +251,8 @@ void __sched percpu_down_write(struct percpu_rw_semaphore *sem)
 
        /* Wait for all active readers to complete. */
        rcuwait_wait_event(&sem->writer, readers_active_check(sem), TASK_UNINTERRUPTIBLE);
-       trace_contention_end(sem, 0);
+       if (contended)
+               trace_contention_end(sem, 0);
 }
 EXPORT_SYMBOL_GPL(percpu_down_write);