Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf lock: Add -F/--field option to control output

The -F/--field option is to customize the list of fields to output:

$ perf lock report -F contended,wait_max -k avg_wait
Name contended max wait (ns) avg wait (ns)

slock-AF_INET6 1 23543 23543
&lruvec->lru_lock 5 18317 11254
slock-AF_INET6 1 10379 10379
rcu_node_1 1 2104 2104
&dentry->d_lockr... 1 1844 1844
&dentry->d_lockr... 1 1672 1672
&newf->file_lock 15 2279 1025
&dentry->d_lockr... 1 792 792

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Andi Kleen <ak@linux.intel.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>
Link: https://lore.kernel.org/r/20220323230259.288494-3-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
4bd9cab5 64999e44

+57 -6
+6
tools/perf/Documentation/perf-lock.txt
··· 54 54 Sorting key. Possible values: acquired (default), contended, 55 55 avg_wait, wait_total, wait_max, wait_min. 56 56 57 + -F:: 58 + --field=<value>:: 59 + Output fields. By default it shows all the fields but users can 60 + customize that using this. Possible values: acquired, contended, 61 + avg_wait, wait_total, wait_max, wait_min. 62 + 57 63 -c:: 58 64 --combine-locks:: 59 65 Merge lock instances in the same class (based on name).
+51 -6
tools/perf/builtin-lock.c
··· 282 282 static struct rb_root result; /* place to store sorted data */ 283 283 284 284 static LIST_HEAD(lock_keys); 285 + static const char *output_fields; 285 286 286 287 #define DEF_KEY_LOCK(name, header, fn_suffix, len) \ 287 288 { #name, header, len, lock_stat_key_ ## fn_suffix, lock_stat_key_print_ ## fn_suffix, {} } ··· 305 304 for (i = 0; keys[i].name; i++) { 306 305 if (!strcmp(keys[i].name, sort_key)) { 307 306 compare = keys[i].key; 307 + 308 + /* selected key should be in the output fields */ 309 + if (list_empty(&keys[i].list)) 310 + list_add_tail(&keys[i].list, &lock_keys); 311 + 308 312 return 0; 309 313 } 310 314 } 311 315 312 316 pr_err("Unknown compare key: %s\n", sort_key); 313 - 314 317 return -1; 315 318 } 316 319 317 - static int setup_output_field(void) 320 + static int add_output_field(struct list_head *head, char *name) 318 321 { 319 322 int i; 320 323 321 - for (i = 0; keys[i].name; i++) 322 - list_add_tail(&keys[i].list, &lock_keys); 324 + for (i = 0; keys[i].name; i++) { 325 + if (strcmp(keys[i].name, name)) 326 + continue; 323 327 324 - return 0; 328 + /* prevent double link */ 329 + if (list_empty(&keys[i].list)) 330 + list_add_tail(&keys[i].list, head); 331 + 332 + return 0; 333 + } 334 + 335 + pr_err("Unknown output field: %s\n", name); 336 + return -1; 337 + } 338 + 339 + static int setup_output_field(const char *str) 340 + { 341 + char *tok, *tmp, *orig; 342 + int i, ret = 0; 343 + 344 + /* no output field given: use all of them */ 345 + if (str == NULL) { 346 + for (i = 0; keys[i].name; i++) 347 + list_add_tail(&keys[i].list, &lock_keys); 348 + return 0; 349 + } 350 + 351 + for (i = 0; keys[i].name; i++) 352 + INIT_LIST_HEAD(&keys[i].list); 353 + 354 + orig = tmp = strdup(str); 355 + if (orig == NULL) 356 + return -ENOMEM; 357 + 358 + while ((tok = strsep(&tmp, ",")) != NULL){ 359 + ret = add_output_field(&lock_keys, tok); 360 + if (ret < 0) 361 + break; 362 + } 363 + free(orig); 364 + 365 + return ret; 325 366 } 326 367 327 368 static void combine_lock_stats(struct lock_stat *st) ··· 1045 1002 goto out_delete; 1046 1003 } 1047 1004 1048 - if (setup_output_field()) 1005 + if (setup_output_field(output_fields)) 1049 1006 goto out_delete; 1050 1007 1051 1008 if (select_key()) ··· 1133 1090 const struct option report_options[] = { 1134 1091 OPT_STRING('k', "key", &sort_key, "acquired", 1135 1092 "key for sorting (acquired / contended / avg_wait / wait_total / wait_max / wait_min)"), 1093 + OPT_STRING('F', "field", &output_fields, NULL, 1094 + "output fields (acquired / contended / avg_wait / wait_total / wait_max / wait_min)"), 1136 1095 /* TODO: type */ 1137 1096 OPT_BOOLEAN('c', "combine-locks", &combine_locks, 1138 1097 "combine locks in the same class"),