From 64999e4402099f2993f485b28baa33e638c93fe1 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 23 Mar 2022 16:02:58 -0700 Subject: perf lock: Extend struct lock_key to have print function And use it to print output for each key field. No functional change intended and the output should be identical. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20220323230259.288494-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-lock.c | 91 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 26 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 1ebff88bc5ba..c2ecb6acb87d 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -237,9 +237,43 @@ struct lock_key { * e.g. nr_acquired -> acquired, wait_time_total -> wait_total */ const char *name; + /* header: the string printed on the header line */ + const char *header; + /* len: the printing width of the field */ + int len; + /* key: a pointer to function to compare two lock stats for sorting */ int (*key)(struct lock_stat*, struct lock_stat*); + /* print: a pointer to function to print a given lock stats */ + void (*print)(struct lock_key*, struct lock_stat*); + /* list: list entry to link this */ + struct list_head list; }; +#define PRINT_KEY(member) \ +static void lock_stat_key_print_ ## member(struct lock_key *key, \ + struct lock_stat *ls) \ +{ \ + pr_info("%*llu", key->len, (unsigned long long)ls->member); \ +} + +PRINT_KEY(nr_acquired) +PRINT_KEY(nr_contended) +PRINT_KEY(avg_wait_time) +PRINT_KEY(wait_time_total) +PRINT_KEY(wait_time_max) + +static void lock_stat_key_print_wait_time_min(struct lock_key *key, + struct lock_stat *ls) +{ + u64 wait_time = ls->wait_time_min; + + if (wait_time == ULLONG_MAX) + wait_time = 0; + + pr_info("%*"PRIu64, key->len, wait_time); +} + + static const char *sort_key = "acquired"; static int (*compare)(struct lock_stat *, struct lock_stat *); @@ -247,19 +281,20 @@ static int (*compare)(struct lock_stat *, struct lock_stat *); static struct rb_root sorted; /* place to store intermediate data */ static struct rb_root result; /* place to store sorted data */ -#define DEF_KEY_LOCK(name, fn_suffix) \ - { #name, lock_stat_key_ ## fn_suffix } +static LIST_HEAD(lock_keys); + +#define DEF_KEY_LOCK(name, header, fn_suffix, len) \ + { #name, header, len, lock_stat_key_ ## fn_suffix, lock_stat_key_print_ ## fn_suffix, {} } struct lock_key keys[] = { - DEF_KEY_LOCK(acquired, nr_acquired), - DEF_KEY_LOCK(contended, nr_contended), - DEF_KEY_LOCK(avg_wait, avg_wait_time), - DEF_KEY_LOCK(wait_total, wait_time_total), - DEF_KEY_LOCK(wait_min, wait_time_min), - DEF_KEY_LOCK(wait_max, wait_time_max), + DEF_KEY_LOCK(acquired, "acquired", nr_acquired, 10), + DEF_KEY_LOCK(contended, "contended", nr_contended, 10), + DEF_KEY_LOCK(avg_wait, "avg wait (ns)", avg_wait_time, 15), + DEF_KEY_LOCK(wait_total, "total wait (ns)", wait_time_total, 15), + DEF_KEY_LOCK(wait_max, "max wait (ns)", wait_time_max, 15), + DEF_KEY_LOCK(wait_min, "min wait (ns)", wait_time_min, 15), /* extra comparisons much complicated should be here */ - - { NULL, NULL } + { } }; static int select_key(void) @@ -278,6 +313,16 @@ static int select_key(void) return -1; } +static int setup_output_field(void) +{ + int i; + + for (i = 0; keys[i].name; i++) + list_add_tail(&keys[i].list, &lock_keys); + + return 0; +} + static void combine_lock_stats(struct lock_stat *st) { struct rb_node **rb = &sorted.rb_node; @@ -753,18 +798,13 @@ static void print_bad_events(int bad, int total) static void print_result(void) { struct lock_stat *st; + struct lock_key *key; char cut_name[20]; int bad, total; pr_info("%20s ", "Name"); - pr_info("%10s ", "acquired"); - pr_info("%10s ", "contended"); - - pr_info("%15s ", "avg wait (ns)"); - pr_info("%15s ", "total wait (ns)"); - pr_info("%15s ", "max wait (ns)"); - pr_info("%15s ", "min wait (ns)"); - + list_for_each_entry(key, &lock_keys, list) + pr_info("%*s ", key->len, key->header); pr_info("\n\n"); bad = total = 0; @@ -789,14 +829,10 @@ static void print_result(void) pr_info("%20s ", cut_name); } - pr_info("%10u ", st->nr_acquired); - pr_info("%10u ", st->nr_contended); - - pr_info("%15" PRIu64 " ", st->avg_wait_time); - pr_info("%15" PRIu64 " ", st->wait_time_total); - pr_info("%15" PRIu64 " ", st->wait_time_max); - pr_info("%15" PRIu64 " ", st->wait_time_min == ULLONG_MAX ? - 0 : st->wait_time_min); + list_for_each_entry(key, &lock_keys, list) { + key->print(key, st); + pr_info(" "); + } pr_info("\n"); } @@ -966,6 +1002,9 @@ static int __cmd_report(bool display_info) goto out_delete; } + if (setup_output_field()) + goto out_delete; + if (select_key()) goto out_delete; -- cgit v1.2.3