Save cgroup info and display cgroup names if requested. This is a preparation for the next patch. Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx> --- tools/perf/builtin-lock.c | 1 + tools/perf/util/bpf_lock_contention.c | 26 +++++++++++++++++++++++++- tools/perf/util/lock-contention.h | 9 +++++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index b141f2134274..69086d94f588 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -2040,6 +2040,7 @@ static int __cmd_contention(int argc, const char **argv) .filters = &filters, .save_callstack = needs_callstack(), .owner = show_lock_owner, + .cgroups = RB_ROOT, }; lockhash_table = calloc(LOCKHASH_SIZE, sizeof(*lockhash_table)); diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index e7dddf0127bc..9d36b07eccf5 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include "util/cgroup.h" #include "util/debug.h" #include "util/evlist.h" #include "util/machine.h" @@ -151,6 +152,10 @@ int lock_contention_prepare(struct lock_contention *con) skel->bss->needs_callstack = con->save_callstack; skel->bss->lock_owner = con->owner; + if (con->use_cgroup) { + read_all_cgroups(&con->cgroups); + } + bpf_program__set_autoload(skel->progs.collect_lock_syms, false); lock_contention_bpf__attach(skel); @@ -222,6 +227,17 @@ static const char *lock_contention_get_name(struct lock_contention *con, return ""; } + if (con->use_cgroup) { + u64 cgrp_id = key->lock_addr_or_cgroup; + struct cgroup *cgrp = __cgroup__find(&con->cgroups, cgrp_id); + + if (cgrp) + return cgrp->name; + + snprintf(name_buf, sizeof(name_buf), "cgroup:%lu", cgrp_id); + return name_buf; + } + /* LOCK_AGGR_CALLER: skip lock internal functions */ while (machine__is_lock_function(machine, stack_trace[idx]) && idx < con->max_stack - 1) @@ -364,12 +380,20 @@ int lock_contention_read(struct lock_contention *con) return err; } -int lock_contention_finish(void) +int lock_contention_finish(struct lock_contention *con) { if (skel) { skel->bss->enabled = 0; lock_contention_bpf__destroy(skel); } + while (!RB_EMPTY_ROOT(&con->cgroups)) { + struct rb_node *node = rb_first(&con->cgroups); + struct cgroup *cgrp = rb_entry(node, struct cgroup, node); + + rb_erase(node, &con->cgroups); + cgroup__put(cgrp); + } + return 0; } diff --git a/tools/perf/util/lock-contention.h b/tools/perf/util/lock-contention.h index fa16532c971c..70423966d778 100644 --- a/tools/perf/util/lock-contention.h +++ b/tools/perf/util/lock-contention.h @@ -136,6 +136,7 @@ struct lock_contention { struct hlist_head *result; struct lock_filter *filters; struct lock_contention_fails fails; + struct rb_root cgroups; unsigned long map_nr_entries; int max_stack; int stack_skip; @@ -143,6 +144,7 @@ struct lock_contention { int owner; int nr_filtered; bool save_callstack; + bool use_cgroup; }; #ifdef HAVE_BPF_SKEL @@ -151,7 +153,7 @@ int lock_contention_prepare(struct lock_contention *con); int lock_contention_start(void); int lock_contention_stop(void); int lock_contention_read(struct lock_contention *con); -int lock_contention_finish(void); +int lock_contention_finish(struct lock_contention *con); #else /* !HAVE_BPF_SKEL */ @@ -162,7 +164,10 @@ static inline int lock_contention_prepare(struct lock_contention *con __maybe_un static inline int lock_contention_start(void) { return 0; } static inline int lock_contention_stop(void) { return 0; } -static inline int lock_contention_finish(void) { return 0; } +static inline int lock_contention_finish(struct lock_contention *con __maybe_unused) +{ + return 0; +} static inline int lock_contention_read(struct lock_contention *con __maybe_unused) { -- 2.42.0.283.g2d96d420d3-goog