From: Namhyung Kim <namhyung@kernel.org>
To: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@kernel.org>, Will Deacon <will@kernel.org>,
Waiman Long <longman@redhat.com>,
Boqun Feng <boqun.feng@gmail.com>
Cc: LKML <linux-kernel@vger.kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
Steven Rostedt <rostedt@goodmis.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Byungchul Park <byungchul.park@lge.com>,
"Paul E. McKenney" <paulmck@kernel.org>,
Arnd Bergmann <arnd@arndb.de>,
linux-arch@vger.kernel.org, bpf@vger.kernel.org,
Radoslaw Burny <rburny@google.com>
Subject: [PATCH 2/4] locking: Apply contention tracepoints in the slow path
Date: Mon, 28 Feb 2022 17:04:10 -0800 [thread overview]
Message-ID: <20220301010412.431299-3-namhyung@kernel.org> (raw)
In-Reply-To: <20220301010412.431299-1-namhyung@kernel.org>
Adding the lock contention tracepoints in various lock function slow
paths. Note that each arch can define spinlock differently, I only
added it only to the generic qspinlock for now.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
include/asm-generic/qrwlock.h | 5 +++++
include/asm-generic/qspinlock.h | 3 +++
include/trace/events/lock.h | 1 +
kernel/locking/mutex.c | 4 ++++
kernel/locking/percpu-rwsem.c | 11 ++++++++++-
kernel/locking/rtmutex.c | 12 +++++++++++-
kernel/locking/rwbase_rt.c | 11 ++++++++++-
kernel/locking/rwsem.c | 16 ++++++++++++++--
8 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/include/asm-generic/qrwlock.h b/include/asm-generic/qrwlock.h
index 7ae0ece07b4e..9735c39b05bb 100644
--- a/include/asm-generic/qrwlock.h
+++ b/include/asm-generic/qrwlock.h
@@ -12,6 +12,7 @@
#include <linux/atomic.h>
#include <asm/barrier.h>
#include <asm/processor.h>
+#include <linux/lock_trace.h>
#include <asm-generic/qrwlock_types.h>
@@ -80,7 +81,9 @@ static inline void queued_read_lock(struct qrwlock *lock)
return;
/* The slowpath will decrement the reader count, if necessary. */
+ LOCK_CONTENTION_BEGIN(lock, LCB_F_READ);
queued_read_lock_slowpath(lock);
+ LOCK_CONTENTION_END(lock);
}
/**
@@ -94,7 +97,9 @@ static inline void queued_write_lock(struct qrwlock *lock)
if (likely(atomic_try_cmpxchg_acquire(&lock->cnts, &cnts, _QW_LOCKED)))
return;
+ LOCK_CONTENTION_BEGIN(lock, LCB_F_WRITE);
queued_write_lock_slowpath(lock);
+ LOCK_CONTENTION_END(lock);
}
/**
diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h
index d74b13825501..986b96fadbf9 100644
--- a/include/asm-generic/qspinlock.h
+++ b/include/asm-generic/qspinlock.h
@@ -12,6 +12,7 @@
#include <asm-generic/qspinlock_types.h>
#include <linux/atomic.h>
+#include <linux/lock_trace.h>
#ifndef queued_spin_is_locked
/**
@@ -82,7 +83,9 @@ static __always_inline void queued_spin_lock(struct qspinlock *lock)
if (likely(atomic_try_cmpxchg_acquire(&lock->val, &val, _Q_LOCKED_VAL)))
return;
+ LOCK_CONTENTION_BEGIN(lock, 0);
queued_spin_lock_slowpath(lock, val);
+ LOCK_CONTENTION_END(lock);
}
#endif
diff --git a/include/trace/events/lock.h b/include/trace/events/lock.h
index 7bca0a537dbd..9b285083f88f 100644
--- a/include/trace/events/lock.h
+++ b/include/trace/events/lock.h
@@ -6,6 +6,7 @@
#define _TRACE_LOCK_H
#include <linux/tracepoint.h>
+#include <linux/lock_trace.h>
#ifdef CONFIG_LOCKDEP
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index 5e3585950ec8..756624c14dfd 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -30,6 +30,8 @@
#include <linux/debug_locks.h>
#include <linux/osq_lock.h>
+#include <trace/events/lock.h>
+
#ifndef CONFIG_PREEMPT_RT
#include "mutex.h"
@@ -626,6 +628,7 @@ __mutex_lock_common(struct mutex *lock, unsigned int state, unsigned int subclas
waiter.ww_ctx = ww_ctx;
lock_contended(&lock->dep_map, ip);
+ trace_contention_begin(lock, ip, state);
if (!use_ww_ctx) {
/* add waiting tasks to the end of the waitqueue (FIFO): */
@@ -688,6 +691,7 @@ __mutex_lock_common(struct mutex *lock, unsigned int state, unsigned int subclas
}
raw_spin_lock(&lock->wait_lock);
acquired:
+ trace_contention_end(lock);
__set_current_state(TASK_RUNNING);
if (ww_ctx) {
diff --git a/kernel/locking/percpu-rwsem.c b/kernel/locking/percpu-rwsem.c
index c9fdae94e098..4049b79b3dcc 100644
--- a/kernel/locking/percpu-rwsem.c
+++ b/kernel/locking/percpu-rwsem.c
@@ -9,6 +9,7 @@
#include <linux/sched/task.h>
#include <linux/sched/debug.h>
#include <linux/errno.h>
+#include <trace/events/lock.h>
int __percpu_init_rwsem(struct percpu_rw_semaphore *sem,
const char *name, struct lock_class_key *key)
@@ -171,9 +172,12 @@ bool __sched __percpu_down_read(struct percpu_rw_semaphore *sem, bool try)
if (try)
return false;
+ trace_contention_begin(sem, _RET_IP_,
+ LCB_F_READ | LCB_F_PERCPU | TASK_UNINTERRUPTIBLE);
preempt_enable();
percpu_rwsem_wait(sem, /* .reader = */ true);
preempt_disable();
+ trace_contention_end(sem);
return true;
}
@@ -224,8 +228,13 @@ 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)) {
+ unsigned int flags = LCB_F_WRITE | LCB_F_PERCPU | TASK_UNINTERRUPTIBLE;
+
+ trace_contention_begin(sem, _RET_IP_, flags);
percpu_rwsem_wait(sem, /* .reader = */ false);
+ trace_contention_end(sem);
+ }
/* smp_mb() implied by __percpu_down_write_trylock() on success -- D matches A */
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
index 8555c4efe97c..e49f5d2a232b 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -24,6 +24,8 @@
#include <linux/sched/wake_q.h>
#include <linux/ww_mutex.h>
+#include <trace/events/lock.h>
+
#include "rtmutex_common.h"
#ifndef WW_RT
@@ -1652,10 +1654,16 @@ static int __sched rt_mutex_slowlock(struct rt_mutex_base *lock,
static __always_inline int __rt_mutex_lock(struct rt_mutex_base *lock,
unsigned int state)
{
+ int ret;
+
if (likely(rt_mutex_cmpxchg_acquire(lock, NULL, current)))
return 0;
- return rt_mutex_slowlock(lock, NULL, state);
+ trace_contention_begin(lock, _RET_IP_, LCB_F_RT | state);
+ ret = rt_mutex_slowlock(lock, NULL, state);
+ trace_contention_end(lock);
+
+ return ret;
}
#endif /* RT_MUTEX_BUILD_MUTEX */
@@ -1718,9 +1726,11 @@ static __always_inline void __sched rtlock_slowlock(struct rt_mutex_base *lock)
{
unsigned long flags;
+ trace_contention_begin(lock, _RET_IP_, LCB_F_RT | TASK_RTLOCK_WAIT);
raw_spin_lock_irqsave(&lock->wait_lock, flags);
rtlock_slowlock_locked(lock);
raw_spin_unlock_irqrestore(&lock->wait_lock, flags);
+ trace_contention_end(lock);
}
#endif /* RT_MUTEX_BUILD_SPINLOCKS */
diff --git a/kernel/locking/rwbase_rt.c b/kernel/locking/rwbase_rt.c
index 6fd3162e4098..8a28f1195c58 100644
--- a/kernel/locking/rwbase_rt.c
+++ b/kernel/locking/rwbase_rt.c
@@ -136,10 +136,16 @@ static int __sched __rwbase_read_lock(struct rwbase_rt *rwb,
static __always_inline int rwbase_read_lock(struct rwbase_rt *rwb,
unsigned int state)
{
+ int ret;
+
if (rwbase_read_trylock(rwb))
return 0;
- return __rwbase_read_lock(rwb, state);
+ trace_contention_begin(rwb, _RET_IP_, LCB_F_READ | LCB_F_RT | state);
+ ret = __rwbase_read_lock(rwb, state);
+ trace_contention_end(rwb);
+
+ return ret;
}
static void __sched __rwbase_read_unlock(struct rwbase_rt *rwb,
@@ -246,12 +252,14 @@ static int __sched rwbase_write_lock(struct rwbase_rt *rwb,
if (__rwbase_write_trylock(rwb))
goto out_unlock;
+ trace_contention_begin(rwb, _RET_IP_, LCB_F_WRITE | LCB_F_RT | state);
rwbase_set_and_save_current_state(state);
for (;;) {
/* Optimized out for rwlocks */
if (rwbase_signal_pending_state(state, current)) {
rwbase_restore_current_state();
__rwbase_write_unlock(rwb, 0, flags);
+ trace_contention_end(rwb);
return -EINTR;
}
@@ -265,6 +273,7 @@ static int __sched rwbase_write_lock(struct rwbase_rt *rwb,
set_current_state(state);
}
rwbase_restore_current_state();
+ trace_contention_end(rwb);
out_unlock:
raw_spin_unlock_irqrestore(&rtm->wait_lock, flags);
diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c
index acde5d6f1254..a1a17af7f747 100644
--- a/kernel/locking/rwsem.c
+++ b/kernel/locking/rwsem.c
@@ -27,6 +27,7 @@
#include <linux/export.h>
#include <linux/rwsem.h>
#include <linux/atomic.h>
+#include <trace/events/lock.h>
#ifndef CONFIG_PREEMPT_RT
#include "lock_events.h"
@@ -1209,9 +1210,14 @@ static struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem)
static inline int __down_read_common(struct rw_semaphore *sem, int state)
{
long count;
+ void *ret;
if (!rwsem_read_trylock(sem, &count)) {
- if (IS_ERR(rwsem_down_read_slowpath(sem, count, state)))
+ trace_contention_begin(sem, _RET_IP_, LCB_F_READ | state);
+ ret = rwsem_down_read_slowpath(sem, count, state);
+ trace_contention_end(sem);
+
+ if (IS_ERR(ret))
return -EINTR;
DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem);
}
@@ -1255,8 +1261,14 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
*/
static inline int __down_write_common(struct rw_semaphore *sem, int state)
{
+ void *ret;
+
if (unlikely(!rwsem_write_trylock(sem))) {
- if (IS_ERR(rwsem_down_write_slowpath(sem, state)))
+ trace_contention_begin(sem, _RET_IP_, LCB_F_WRITE | state);
+ ret = rwsem_down_write_slowpath(sem, state);
+ trace_contention_end(sem);
+
+ if (IS_ERR(ret))
return -EINTR;
}
--
2.35.1.574.g5d30c73bfb-goog
next prev parent reply other threads:[~2022-03-01 1:04 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-01 1:04 [RFC 0/4] locking: Add new lock contention tracepoints (v2) Namhyung Kim
2022-03-01 1:04 ` [PATCH 1/4] locking: Add lock contention tracepoints Namhyung Kim
2022-03-01 1:04 ` Namhyung Kim [this message]
2022-03-01 8:43 ` [PATCH 2/4] locking: Apply contention tracepoints in the slow path Peter Zijlstra
2022-03-01 18:03 ` Namhyung Kim
2022-03-01 9:03 ` Peter Zijlstra
2022-03-01 14:45 ` Steven Rostedt
2022-03-01 18:14 ` Namhyung Kim
2022-03-01 18:11 ` Namhyung Kim
2022-03-14 21:44 ` Namhyung Kim
2022-03-01 1:04 ` [PATCH 3/4] locking/mutex: Pass proper call-site ip Namhyung Kim
2022-03-01 9:05 ` Peter Zijlstra
2022-03-01 14:53 ` Steven Rostedt
2022-03-01 19:47 ` Peter Zijlstra
2022-03-04 7:28 ` Namhyung Kim
2022-03-01 18:25 ` Namhyung Kim
2022-03-01 1:04 ` [PATCH 4/4] locking/rwsem: " Namhyung Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220301010412.431299-3-namhyung@kernel.org \
--to=namhyung@kernel.org \
--cc=arnd@arndb.de \
--cc=boqun.feng@gmail.com \
--cc=bpf@vger.kernel.org \
--cc=byungchul.park@lge.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=longman@redhat.com \
--cc=mathieu.desnoyers@efficios.com \
--cc=mingo@kernel.org \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=rburny@google.com \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®