aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-trace.c199
-rw-r--r--tools/perf/scripts/perl/bin/check-perf-trace-report1
-rw-r--r--tools/perf/scripts/perl/bin/rw-by-file-report2
-rw-r--r--tools/perf/scripts/perl/bin/rw-by-pid-report1
-rw-r--r--tools/perf/scripts/perl/bin/wakeup-latency-report1
-rw-r--r--tools/perf/scripts/perl/bin/workqueue-stats-report1
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
293struct script_desc {
294 struct list_head node;
295 char *name;
296 char *half_liner;
297 char *args;
298};
299
300LIST_HEAD(script_descs);
301
302static 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
312static void script_desc__delete(struct script_desc *s)
313{
314 free(s->name);
315 free(s);
316}
317
318static void script_desc__add(struct script_desc *s)
319{
320 list_add_tail(&s->node, &script_descs);
321}
322
323static 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
333static 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
348out_delete_desc:
349 script_desc__delete(s);
350
351 return NULL;
352}
353
354static 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
368static 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
380static 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
421static 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
277static const char * const annotate_usage[] = { 472static 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
2perf trace -s ~/libexec/perf-core/scripts/perl/check-perf-trace.pl 3perf 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>
2perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $1 4perf 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
2perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl 3perf 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
2perf trace -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl 3perf 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)
2perf trace -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl 3perf trace -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl
3 4
4 5