diff options
| author | Tom Zanussi <tzanussi@gmail.com> | 2009-12-15 03:53:38 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-12-15 04:31:32 -0500 |
| commit | 4b9c0c596ea826ef784eb83f663c5351ed01ba6d (patch) | |
| tree | 8e22badb64e744d61d2ed4f6d12a0ebeb05a61c3 | |
| parent | 8f11d85a0e7e9025acea7493e6864089c8b52f42 (diff) | |
perf trace/scripting: List available scripts
Lists the available perf trace scripts, one per line e.g.:
root@tropicana:~# perf trace -l
List of available trace scripts:
workqueue-stats workqueue stats (ins/exe/create/destroy)
wakeup-latency system-wide min/max/avg wakeup latency
rw-by-file <comm> r/w activity for a program, by file
check-perf-trace useless but exhaustive test script
rw-by-pid system-wide r/w activity
To be consistent with the other listing options in perf, the
current latency trace option was changed to '-L', and '-l' is
now used to access the script listing as:
To create the list, it searches each scripts/*/bin directory for
files ending with "-report" and reads information found in
certain comment lines contained in those shell scripts:
- if the comment line starts with "description:", the rest of the
line is used as a 'half-line' description. To keep each line in
the list to a single line, the description should be limited to 40
characters (the rest of the line contains the script name and
args)
- if the comment line starts with "args:", the rest of the line
names the args the script supports. Required args should be
surrounded by <> brackets, optional args by [] brackets.
The current scripts in scripts/perl/bin have also been updated
with description: and args: comments.
Signed-off-by: Tom Zanussi <tzanussi@gmail.com>
Cc: fweisbec@gmail.com
Cc: rostedt@goodmis.org
LKML-Reference: <1260867220-15699-5-git-send-email-tzanussi@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | tools/perf/builtin-trace.c | 199 | ||||
| -rw-r--r-- | tools/perf/scripts/perl/bin/check-perf-trace-report | 1 | ||||
| -rw-r--r-- | tools/perf/scripts/perl/bin/rw-by-file-report | 2 | ||||
| -rw-r--r-- | tools/perf/scripts/perl/bin/rw-by-pid-report | 1 | ||||
| -rw-r--r-- | tools/perf/scripts/perl/bin/wakeup-latency-report | 1 | ||||
| -rw-r--r-- | tools/perf/scripts/perl/bin/workqueue-stats-report | 1 |
6 files changed, 204 insertions, 1 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 88b0353d4019..7674153c4bbe 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -274,6 +274,201 @@ static int parse_scriptname(const struct option *opt __used, | |||
| 274 | return 0; | 274 | return 0; |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | #define for_each_lang(scripts_dir, lang_dirent, lang_next) \ | ||
| 278 | while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ | ||
| 279 | lang_next) \ | ||
| 280 | if (lang_dirent.d_type == DT_DIR && \ | ||
| 281 | (strcmp(lang_dirent.d_name, ".")) && \ | ||
| 282 | (strcmp(lang_dirent.d_name, ".."))) | ||
| 283 | |||
| 284 | #define for_each_script(lang_dir, script_dirent, script_next) \ | ||
| 285 | while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ | ||
| 286 | script_next) \ | ||
| 287 | if (script_dirent.d_type != DT_DIR) | ||
| 288 | |||
| 289 | |||
| 290 | #define RECORD_SUFFIX "-record" | ||
| 291 | #define REPORT_SUFFIX "-report" | ||
| 292 | |||
| 293 | struct script_desc { | ||
| 294 | struct list_head node; | ||
| 295 | char *name; | ||
| 296 | char *half_liner; | ||
| 297 | char *args; | ||
| 298 | }; | ||
| 299 | |||
| 300 | LIST_HEAD(script_descs); | ||
| 301 | |||
| 302 | static struct script_desc *script_desc__new(const char *name) | ||
| 303 | { | ||
| 304 | struct script_desc *s = zalloc(sizeof(*s)); | ||
| 305 | |||
| 306 | if (s != NULL) | ||
| 307 | s->name = strdup(name); | ||
| 308 | |||
| 309 | return s; | ||
| 310 | } | ||
| 311 | |||
| 312 | static void script_desc__delete(struct script_desc *s) | ||
| 313 | { | ||
| 314 | free(s->name); | ||
| 315 | free(s); | ||
| 316 | } | ||
| 317 | |||
| 318 | static void script_desc__add(struct script_desc *s) | ||
| 319 | { | ||
| 320 | list_add_tail(&s->node, &script_descs); | ||
| 321 | } | ||
| 322 | |||
| 323 | static struct script_desc *script_desc__find(const char *name) | ||
| 324 | { | ||
| 325 | struct script_desc *s; | ||
| 326 | |||
| 327 | list_for_each_entry(s, &script_descs, node) | ||
| 328 | if (strcasecmp(s->name, name) == 0) | ||
| 329 | return s; | ||
| 330 | return NULL; | ||
| 331 | } | ||
| 332 | |||
| 333 | static struct script_desc *script_desc__findnew(const char *name) | ||
| 334 | { | ||
| 335 | struct script_desc *s = script_desc__find(name); | ||
| 336 | |||
| 337 | if (s) | ||
| 338 | return s; | ||
| 339 | |||
| 340 | s = script_desc__new(name); | ||
| 341 | if (!s) | ||
| 342 | goto out_delete_desc; | ||
| 343 | |||
| 344 | script_desc__add(s); | ||
| 345 | |||
| 346 | return s; | ||
| 347 | |||
| 348 | out_delete_desc: | ||
| 349 | script_desc__delete(s); | ||
| 350 | |||
| 351 | return NULL; | ||
| 352 | } | ||
| 353 | |||
| 354 | static char *ends_with(char *str, const char *suffix) | ||
| 355 | { | ||
| 356 | size_t suffix_len = strlen(suffix); | ||
| 357 | char *p = str; | ||
| 358 | |||
| 359 | if (strlen(str) > suffix_len) { | ||
| 360 | p = str + strlen(str) - suffix_len; | ||
| 361 | if (!strncmp(p, suffix, suffix_len)) | ||
| 362 | return p; | ||
| 363 | } | ||
| 364 | |||
| 365 | return NULL; | ||
| 366 | } | ||
| 367 | |||
| 368 | static char *ltrim(char *str) | ||
| 369 | { | ||
| 370 | int len = strlen(str); | ||
| 371 | |||
| 372 | while (len && isspace(*str)) { | ||
| 373 | len--; | ||
| 374 | str++; | ||
| 375 | } | ||
| 376 | |||
| 377 | return str; | ||
| 378 | } | ||
| 379 | |||
| 380 | static int read_script_info(struct script_desc *desc, const char *filename) | ||
| 381 | { | ||
| 382 | char line[BUFSIZ], *p; | ||
| 383 | FILE *fp; | ||
| 384 | |||
| 385 | fp = fopen(filename, "r"); | ||
| 386 | if (!fp) | ||
| 387 | return -1; | ||
| 388 | |||
| 389 | while (fgets(line, sizeof(line), fp)) { | ||
| 390 | p = ltrim(line); | ||
| 391 | if (strlen(p) == 0) | ||
| 392 | continue; | ||
| 393 | if (*p != '#') | ||
| 394 | continue; | ||
| 395 | p++; | ||
| 396 | if (strlen(p) && *p == '!') | ||
| 397 | continue; | ||
| 398 | |||
| 399 | p = ltrim(p); | ||
| 400 | if (strlen(p) && p[strlen(p) - 1] == '\n') | ||
| 401 | p[strlen(p) - 1] = '\0'; | ||
| 402 | |||
| 403 | if (!strncmp(p, "description:", strlen("description:"))) { | ||
| 404 | p += strlen("description:"); | ||
| 405 | desc->half_liner = strdup(ltrim(p)); | ||
| 406 | continue; | ||
| 407 | } | ||
| 408 | |||
| 409 | if (!strncmp(p, "args:", strlen("args:"))) { | ||
| 410 | p += strlen("args:"); | ||
| 411 | desc->args = strdup(ltrim(p)); | ||
| 412 | continue; | ||
| 413 | } | ||
| 414 | } | ||
| 415 | |||
| 416 | fclose(fp); | ||
| 417 | |||
| 418 | return 0; | ||
| 419 | } | ||
| 420 | |||
| 421 | static int list_available_scripts(const struct option *opt __used, | ||
| 422 | const char *s __used, int unset __used) | ||
| 423 | { | ||
| 424 | struct dirent *script_next, *lang_next, script_dirent, lang_dirent; | ||
| 425 | char scripts_path[MAXPATHLEN]; | ||
| 426 | DIR *scripts_dir, *lang_dir; | ||
| 427 | char script_path[MAXPATHLEN]; | ||
| 428 | char lang_path[MAXPATHLEN]; | ||
| 429 | struct script_desc *desc; | ||
| 430 | char first_half[BUFSIZ]; | ||
| 431 | char *script_root; | ||
| 432 | char *str; | ||
| 433 | |||
| 434 | snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); | ||
| 435 | |||
| 436 | scripts_dir = opendir(scripts_path); | ||
| 437 | if (!scripts_dir) | ||
| 438 | return -1; | ||
| 439 | |||
| 440 | for_each_lang(scripts_dir, lang_dirent, lang_next) { | ||
| 441 | snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, | ||
| 442 | lang_dirent.d_name); | ||
| 443 | lang_dir = opendir(lang_path); | ||
| 444 | if (!lang_dir) | ||
| 445 | continue; | ||
| 446 | |||
| 447 | for_each_script(lang_dir, script_dirent, script_next) { | ||
| 448 | script_root = strdup(script_dirent.d_name); | ||
| 449 | str = ends_with(script_root, REPORT_SUFFIX); | ||
| 450 | if (str) { | ||
| 451 | *str = '\0'; | ||
| 452 | desc = script_desc__findnew(script_root); | ||
| 453 | snprintf(script_path, MAXPATHLEN, "%s/%s", | ||
| 454 | lang_path, script_dirent.d_name); | ||
| 455 | read_script_info(desc, script_path); | ||
| 456 | } | ||
| 457 | free(script_root); | ||
| 458 | } | ||
| 459 | } | ||
| 460 | |||
| 461 | fprintf(stdout, "List of available trace scripts:\n"); | ||
| 462 | list_for_each_entry(desc, &script_descs, node) { | ||
| 463 | sprintf(first_half, "%s %s", desc->name, | ||
| 464 | desc->args ? desc->args : ""); | ||
| 465 | fprintf(stdout, " %-36s %s\n", first_half, | ||
| 466 | desc->half_liner ? desc->half_liner : ""); | ||
| 467 | } | ||
| 468 | |||
| 469 | exit(0); | ||
| 470 | } | ||
| 471 | |||
| 277 | static const char * const annotate_usage[] = { | 472 | static const char * const annotate_usage[] = { |
| 278 | "perf trace [<options>] <command>", | 473 | "perf trace [<options>] <command>", |
| 279 | NULL | 474 | NULL |
| @@ -284,8 +479,10 @@ static const struct option options[] = { | |||
| 284 | "dump raw trace in ASCII"), | 479 | "dump raw trace in ASCII"), |
| 285 | OPT_BOOLEAN('v', "verbose", &verbose, | 480 | OPT_BOOLEAN('v', "verbose", &verbose, |
| 286 | "be more verbose (show symbol address, etc)"), | 481 | "be more verbose (show symbol address, etc)"), |
| 287 | OPT_BOOLEAN('l', "latency", &latency_format, | 482 | OPT_BOOLEAN('L', "Latency", &latency_format, |
| 288 | "show latency attributes (irqs/preemption disabled, etc)"), | 483 | "show latency attributes (irqs/preemption disabled, etc)"), |
| 484 | OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts", | ||
| 485 | list_available_scripts), | ||
| 289 | OPT_CALLBACK('s', "script", NULL, "name", | 486 | OPT_CALLBACK('s', "script", NULL, "name", |
| 290 | "script file name (lang:script name, script name, or *)", | 487 | "script file name (lang:script name, script name, or *)", |
| 291 | parse_scriptname), | 488 | parse_scriptname), |
diff --git a/tools/perf/scripts/perl/bin/check-perf-trace-report b/tools/perf/scripts/perl/bin/check-perf-trace-report index 89948b015020..7fc4a033dd49 100644 --- a/tools/perf/scripts/perl/bin/check-perf-trace-report +++ b/tools/perf/scripts/perl/bin/check-perf-trace-report | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # description: useless but exhaustive test script | ||
| 2 | perf trace -s ~/libexec/perf-core/scripts/perl/check-perf-trace.pl | 3 | perf trace -s ~/libexec/perf-core/scripts/perl/check-perf-trace.pl |
| 3 | 4 | ||
| 4 | 5 | ||
diff --git a/tools/perf/scripts/perl/bin/rw-by-file-report b/tools/perf/scripts/perl/bin/rw-by-file-report index 1c0567516aba..eddb9ccce6a5 100644 --- a/tools/perf/scripts/perl/bin/rw-by-file-report +++ b/tools/perf/scripts/perl/bin/rw-by-file-report | |||
| @@ -1,4 +1,6 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # description: r/w activity for a program, by file | ||
| 3 | # args: <comm> | ||
| 2 | perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $1 | 4 | perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $1 |
| 3 | 5 | ||
| 4 | 6 | ||
diff --git a/tools/perf/scripts/perl/bin/rw-by-pid-report b/tools/perf/scripts/perl/bin/rw-by-pid-report index cea16f78a3a2..7f44c25cc857 100644 --- a/tools/perf/scripts/perl/bin/rw-by-pid-report +++ b/tools/perf/scripts/perl/bin/rw-by-pid-report | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # description: system-wide r/w activity | ||
| 2 | perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl | 3 | perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl |
| 3 | 4 | ||
| 4 | 5 | ||
diff --git a/tools/perf/scripts/perl/bin/wakeup-latency-report b/tools/perf/scripts/perl/bin/wakeup-latency-report index 85769dc456eb..fce3adcb3249 100644 --- a/tools/perf/scripts/perl/bin/wakeup-latency-report +++ b/tools/perf/scripts/perl/bin/wakeup-latency-report | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # description: system-wide min/max/avg wakeup latency | ||
| 2 | perf trace -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl | 3 | perf trace -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl |
| 3 | 4 | ||
| 4 | 5 | ||
diff --git a/tools/perf/scripts/perl/bin/workqueue-stats-report b/tools/perf/scripts/perl/bin/workqueue-stats-report index aa68435be926..71cfbd182fb9 100644 --- a/tools/perf/scripts/perl/bin/workqueue-stats-report +++ b/tools/perf/scripts/perl/bin/workqueue-stats-report | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # description: workqueue stats (ins/exe/create/destroy) | ||
| 2 | perf trace -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl | 3 | perf trace -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl |
| 3 | 4 | ||
| 4 | 5 | ||
