diff options
author | Namhyung Kim <namhyung@kernel.org> | 2022-12-09 11:07:25 -0800 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2022-12-14 11:24:31 -0300 |
commit | eca949b2b4addd941d369d4c2014b87f3c3e203b (patch) | |
tree | 722907c1e3f3b8a96b48c83eaed99f4df6621029 /tools/perf/util/bpf_lock_contention.c | |
parent | fd507d3e359c7e06d74321cd3d8a5ec8769d05a9 (diff) | |
download | lwn-eca949b2b4addd941d369d4c2014b87f3c3e203b.tar.gz lwn-eca949b2b4addd941d369d4c2014b87f3c3e203b.zip |
perf lock contention: Implement -t/--threads option for BPF
The BPF didn't show the per-thread stat properly. Use task's thread id (PID)
as a key instead of stack_id and add a task_data map to save task comm names.
$ sudo ./perf lock con -abt -E 5 sleep 1
contended total wait max wait avg wait pid comm
1 740.66 ms 740.66 ms 740.66 ms 1950 nv_queue
3 305.50 ms 298.19 ms 101.83 ms 1884 nvidia-modeset/
1 25.14 us 25.14 us 25.14 us 2725038 EventManager_De
12 23.09 us 9.30 us 1.92 us 0 swapper
1 20.18 us 20.18 us 20.18 us 2725033 EventManager_De
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Blake Jones <blakejones@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: bpf@vger.kernel.org
Link: https://lore.kernel.org/r/20221209190727.759804-3-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/bpf_lock_contention.c')
-rw-r--r-- | tools/perf/util/bpf_lock_contention.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index b6a8eb7164b3..1590a9f05145 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -5,6 +5,7 @@ #include "util/map.h" #include "util/symbol.h" #include "util/target.h" +#include "util/thread.h" #include "util/thread_map.h" #include "util/lock-contention.h" #include <linux/zalloc.h> @@ -30,10 +31,17 @@ int lock_contention_prepare(struct lock_contention *con) } bpf_map__set_value_size(skel->maps.stacks, con->max_stack * sizeof(u64)); - bpf_map__set_max_entries(skel->maps.stacks, con->map_nr_entries); bpf_map__set_max_entries(skel->maps.lock_stat, con->map_nr_entries); bpf_map__set_max_entries(skel->maps.tstamp, con->map_nr_entries); + if (con->aggr_mode == LOCK_AGGR_TASK) { + bpf_map__set_max_entries(skel->maps.task_data, con->map_nr_entries); + bpf_map__set_max_entries(skel->maps.stacks, 1); + } else { + bpf_map__set_max_entries(skel->maps.task_data, 1); + bpf_map__set_max_entries(skel->maps.stacks, con->map_nr_entries); + } + if (target__has_cpu(target)) ncpus = perf_cpu_map__nr(evlist->core.user_requested_cpus); if (target__has_task(target)) @@ -82,7 +90,9 @@ int lock_contention_prepare(struct lock_contention *con) bpf_map_update_elem(fd, &pid, &val, BPF_ANY); } + /* these don't work well if in the rodata section */ skel->bss->stack_skip = con->stack_skip; + skel->bss->aggr_mode = con->aggr_mode; lock_contention_bpf__attach(skel); return 0; @@ -102,7 +112,7 @@ int lock_contention_stop(void) int lock_contention_read(struct lock_contention *con) { - int fd, stack, err = 0; + int fd, stack, task_fd, err = 0; struct contention_key *prev_key, key; struct contention_data data = {}; struct lock_stat *st = NULL; @@ -112,6 +122,7 @@ int lock_contention_read(struct lock_contention *con) fd = bpf_map__fd(skel->maps.lock_stat); stack = bpf_map__fd(skel->maps.stacks); + task_fd = bpf_map__fd(skel->maps.task_data); con->lost = skel->bss->lost; @@ -119,6 +130,13 @@ int lock_contention_read(struct lock_contention *con) if (stack_trace == NULL) return -1; + if (con->aggr_mode == LOCK_AGGR_TASK) { + struct thread *idle = __machine__findnew_thread(machine, + /*pid=*/0, + /*tid=*/0); + thread__set_comm(idle, "swapper", /*timestamp=*/0); + } + prev_key = NULL; while (!bpf_map_get_next_key(fd, prev_key, &key)) { struct map *kmap; @@ -143,6 +161,22 @@ int lock_contention_read(struct lock_contention *con) st->flags = data.flags; + if (con->aggr_mode == LOCK_AGGR_TASK) { + struct contention_task_data task; + struct thread *t; + + st->addr = key.stack_or_task_id; + + /* do not update idle comm which contains CPU number */ + if (st->addr) { + bpf_map_lookup_elem(task_fd, &key, &task); + t = __machine__findnew_thread(machine, /*pid=*/-1, + key.stack_or_task_id); + thread__set_comm(t, task.comm, /*timestamp=*/0); + } + goto next; + } + bpf_map_lookup_elem(stack, &key, stack_trace); /* skip lock internal functions */ @@ -175,7 +209,7 @@ int lock_contention_read(struct lock_contention *con) if (st->callstack == NULL) break; } - +next: hlist_add_head(&st->hash_entry, con->result); prev_key = &key; |