diff options
-rw-r--r-- | tools/perf/Documentation/perf-lock.txt | 21 | ||||
-rw-r--r-- | tools/perf/builtin-lock.c | 28 |
2 files changed, 48 insertions, 1 deletions
diff --git a/tools/perf/Documentation/perf-lock.txt b/tools/perf/Documentation/perf-lock.txt index b43222229807..656b537b2fba 100644 --- a/tools/perf/Documentation/perf-lock.txt +++ b/tools/perf/Documentation/perf-lock.txt @@ -64,6 +64,27 @@ REPORT OPTIONS --combine-locks:: Merge lock instances in the same class (based on name). +-t:: +--threads:: + The -t option is to show per-thread lock stat like below: + + $ perf lock report -t -F acquired,contended,avg_wait + + Name acquired contended avg wait (ns) + + perf 240569 9 5784 + swapper 106610 19 543 + :15789 17370 2 14538 + ContainerMgr 8981 6 874 + sleep 5275 1 11281 + ContainerThread 4416 4 944 + RootPressureThr 3215 5 1215 + rcu_preempt 2954 0 0 + ContainerMgr 2560 0 0 + unnamed 1873 0 0 + EventManager_De 1845 1 636 + futex-default-S 1609 0 0 + INFO OPTIONS ------------ diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 7ceb12e30719..b1200b7340a6 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -118,6 +118,7 @@ struct thread_stat { static struct rb_root thread_stats; static bool combine_locks; +static bool show_thread_stats; static struct thread_stat *thread_stat_find(u32 tid) { @@ -542,6 +543,10 @@ static int report_lock_acquire_event(struct evsel *evsel, u64 addr = evsel__intval(evsel, sample, "lockdep_addr"); int flag = evsel__intval(evsel, sample, "flags"); + /* abuse ls->addr for tid */ + if (show_thread_stats) + addr = sample->tid; + ls = lock_stat_findnew(addr, name); if (!ls) return -ENOMEM; @@ -611,6 +616,9 @@ static int report_lock_acquired_event(struct evsel *evsel, const char *name = evsel__strval(evsel, sample, "name"); u64 addr = evsel__intval(evsel, sample, "lockdep_addr"); + if (show_thread_stats) + addr = sample->tid; + ls = lock_stat_findnew(addr, name); if (!ls) return -ENOMEM; @@ -670,6 +678,9 @@ static int report_lock_contended_event(struct evsel *evsel, const char *name = evsel__strval(evsel, sample, "name"); u64 addr = evsel__intval(evsel, sample, "lockdep_addr"); + if (show_thread_stats) + addr = sample->tid; + ls = lock_stat_findnew(addr, name); if (!ls) return -ENOMEM; @@ -722,6 +733,9 @@ static int report_lock_release_event(struct evsel *evsel, const char *name = evsel__strval(evsel, sample, "name"); u64 addr = evsel__intval(evsel, sample, "lockdep_addr"); + if (show_thread_stats) + addr = sample->tid; + ls = lock_stat_findnew(addr, name); if (!ls) return -ENOMEM; @@ -848,7 +862,17 @@ static void print_result(void) if (strlen(st->name) < 20) { /* output raw name */ - pr_info("%20s ", st->name); + const char *name = st->name; + + if (show_thread_stats) { + struct thread *t; + + /* st->addr contains tid of thread */ + t = perf_session__findnew(session, st->addr); + name = thread__comm_str(t); + } + + pr_info("%20s ", name); } else { strncpy(cut_name, st->name, 16); cut_name[16] = '.'; @@ -1125,6 +1149,8 @@ int cmd_lock(int argc, const char **argv) /* TODO: type */ OPT_BOOLEAN('c', "combine-locks", &combine_locks, "combine locks in the same class"), + OPT_BOOLEAN('t', "threads", &show_thread_stats, + "show per-thread lock stats"), OPT_PARENT(lock_options) }; |