diff options
author | Namhyung Kim <namhyung@kernel.org> | 2023-02-06 16:24:03 -0800 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2023-02-08 10:35:17 -0300 |
commit | 1bece1351c653c3d36bf761513e21ac8428449b4 (patch) | |
tree | f56c4c851d5d777d6df2dba2cbae00f6dd7cbfce /tools/perf | |
parent | 3477f079fe70b3c97a619788d89ac357e207f302 (diff) |
perf lock contention: Support old rw_semaphore type
The old kernel has a different type of the owner field in rwsem. We can
check it using bpf_core_type_matches() builtin in clang but it also
needs its own version check since it's available on recent versions.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Hao Luo <haoluo@google.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Song Liu <song@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Will Deacon <will@kernel.org>
Cc: bpf@vger.kernel.org
Link: https://lore.kernel.org/r/20230207002403.63590-4-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/util/bpf_skel/lock_contention.bpf.c | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/tools/perf/util/bpf_skel/lock_contention.bpf.c b/tools/perf/util/bpf_skel/lock_contention.bpf.c index c5556606134e..e6007eaeda1a 100644 --- a/tools/perf/util/bpf_skel/lock_contention.bpf.c +++ b/tools/perf/util/bpf_skel/lock_contention.bpf.c @@ -84,6 +84,14 @@ struct { __uint(max_entries, 1); } addr_filter SEC(".maps"); +struct rw_semaphore___old { + struct task_struct *owner; +} __attribute__((preserve_access_index)); + +struct rw_semaphore___new { + atomic_long_t owner; +} __attribute__((preserve_access_index)); + /* control flags */ int enabled; int has_cpu; @@ -161,6 +169,41 @@ static inline int update_task_data(struct task_struct *task) return 0; } +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +static inline struct task_struct *get_lock_owner(__u64 lock, __u32 flags) +{ + struct task_struct *task; + __u64 owner = 0; + + if (flags & LCB_F_MUTEX) { + struct mutex *mutex = (void *)lock; + owner = BPF_CORE_READ(mutex, owner.counter); + } else if (flags == LCB_F_READ || flags == LCB_F_WRITE) { +#if __has_builtin(bpf_core_type_matches) + if (bpf_core_type_matches(struct rw_semaphore___old)) { + struct rw_semaphore___old *rwsem = (void *)lock; + owner = (unsigned long)BPF_CORE_READ(rwsem, owner); + } else if (bpf_core_type_matches(struct rw_semaphore___new)) { + struct rw_semaphore___new *rwsem = (void *)lock; + owner = BPF_CORE_READ(rwsem, owner.counter); + } +#else + /* assume new struct */ + struct rw_semaphore *rwsem = (void *)lock; + owner = BPF_CORE_READ(rwsem, owner.counter); +#endif + } + + if (!owner) + return NULL; + + task = (void *)(owner & ~7UL); + return task; +} + SEC("tp_btf/contention_begin") int contention_begin(u64 *ctx) { @@ -199,19 +242,7 @@ int contention_begin(u64 *ctx) struct task_struct *task; if (lock_owner) { - if (pelem->flags & LCB_F_MUTEX) { - struct mutex *lock = (void *)pelem->lock; - unsigned long owner = BPF_CORE_READ(lock, owner.counter); - - task = (void *)(owner & ~7UL); - } else if (pelem->flags == LCB_F_READ || pelem->flags == LCB_F_WRITE) { - struct rw_semaphore *lock = (void *)pelem->lock; - unsigned long owner = BPF_CORE_READ(lock, owner.counter); - - task = (void *)(owner & ~7UL); - } else { - task = NULL; - } + task = get_lock_owner(pelem->lock, pelem->flags); /* The flags is not used anymore. Pass the owner pid. */ if (task) |