aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-stat.c
diff options
context:
space:
mode:
authorStephane Eranian <eranian@google.com>2011-02-14 04:20:01 -0500
committerIngo Molnar <mingo@elte.hu>2011-02-16 07:30:48 -0500
commit023695d96ee06f36cf5014e286edcd623e9fb847 (patch)
treeff7483b7a1aa0cfd5de95475ed059822d2a35499 /tools/perf/builtin-stat.c
parente5d1367f17ba6a6fed5fd8b74e4d5720923e0c25 (diff)
perf tool: Add cgroup support
This patch adds the ability to filter monitoring based on container groups (cgroups) for both perf stat and perf record. It is possible to monitor multiple cgroup in parallel. There is one cgroup per event. The cgroups to monitor are passed via a new -G option followed by a comma separated list of cgroup names. The cgroup filesystem has to be mounted. Given a cgroup name, the perf tool finds the corresponding directory in the cgroup filesystem and opens it. It then passes that file descriptor to the kernel. Example: $ perf stat -B -a -e cycles:u,cycles:u,cycles:u -G test1,,test2 -- sleep 1 Performance counter stats for 'sleep 1': 2,368,667,414 cycles test1 2,369,661,459 cycles <not counted> cycles test2 1.001856890 seconds time elapsed Signed-off-by: Stephane Eranian <eranian@google.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <4d590290.825bdf0a.7d0a.4890@mx.google.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r--tools/perf/builtin-stat.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 806a9998fcd5..21c025222496 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -390,6 +390,9 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
390 390
391 fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(evsel)); 391 fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(evsel));
392 392
393 if (evsel->cgrp)
394 fprintf(stderr, "%s%s", csv_sep, evsel->cgrp->name);
395
393 if (csv_output) 396 if (csv_output)
394 return; 397 return;
395 398
@@ -420,6 +423,9 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
420 423
421 fprintf(stderr, fmt, cpustr, avg, csv_sep, event_name(evsel)); 424 fprintf(stderr, fmt, cpustr, avg, csv_sep, event_name(evsel));
422 425
426 if (evsel->cgrp)
427 fprintf(stderr, "%s%s", csv_sep, evsel->cgrp->name);
428
423 if (csv_output) 429 if (csv_output)
424 return; 430 return;
425 431
@@ -460,9 +466,17 @@ static void print_counter_aggr(struct perf_evsel *counter)
460 int scaled = counter->counts->scaled; 466 int scaled = counter->counts->scaled;
461 467
462 if (scaled == -1) { 468 if (scaled == -1) {
463 fprintf(stderr, "%*s%s%-24s\n", 469 fprintf(stderr, "%*s%s%*s",
464 csv_output ? 0 : 18, 470 csv_output ? 0 : 18,
465 "<not counted>", csv_sep, event_name(counter)); 471 "<not counted>",
472 csv_sep,
473 csv_output ? 0 : -24,
474 event_name(counter));
475
476 if (counter->cgrp)
477 fprintf(stderr, "%s%s", csv_sep, counter->cgrp->name);
478
479 fputc('\n', stderr);
466 return; 480 return;
467 } 481 }
468 482
@@ -487,7 +501,6 @@ static void print_counter_aggr(struct perf_evsel *counter)
487 fprintf(stderr, " (scaled from %.2f%%)", 501 fprintf(stderr, " (scaled from %.2f%%)",
488 100 * avg_running / avg_enabled); 502 100 * avg_running / avg_enabled);
489 } 503 }
490
491 fprintf(stderr, "\n"); 504 fprintf(stderr, "\n");
492} 505}
493 506
@@ -505,14 +518,18 @@ static void print_counter(struct perf_evsel *counter)
505 ena = counter->counts->cpu[cpu].ena; 518 ena = counter->counts->cpu[cpu].ena;
506 run = counter->counts->cpu[cpu].run; 519 run = counter->counts->cpu[cpu].run;
507 if (run == 0 || ena == 0) { 520 if (run == 0 || ena == 0) {
508 fprintf(stderr, "CPU%*d%s%*s%s%-24s", 521 fprintf(stderr, "CPU%*d%s%*s%s%*s",
509 csv_output ? 0 : -4, 522 csv_output ? 0 : -4,
510 evsel_list->cpus->map[cpu], csv_sep, 523 evsel_list->cpus->map[cpu], csv_sep,
511 csv_output ? 0 : 18, 524 csv_output ? 0 : 18,
512 "<not counted>", csv_sep, 525 "<not counted>", csv_sep,
526 csv_output ? 0 : -24,
513 event_name(counter)); 527 event_name(counter));
514 528
515 fprintf(stderr, "\n"); 529 if (counter->cgrp)
530 fprintf(stderr, "%s%s", csv_sep, counter->cgrp->name);
531
532 fputc('\n', stderr);
516 continue; 533 continue;
517 } 534 }
518 535
@@ -529,7 +546,7 @@ static void print_counter(struct perf_evsel *counter)
529 100.0 * run / ena); 546 100.0 * run / ena);
530 } 547 }
531 } 548 }
532 fprintf(stderr, "\n"); 549 fputc('\n', stderr);
533 } 550 }
534} 551}
535 552
@@ -642,6 +659,9 @@ static const struct option options[] = {
642 "disable CPU count aggregation"), 659 "disable CPU count aggregation"),
643 OPT_STRING('x', "field-separator", &csv_sep, "separator", 660 OPT_STRING('x', "field-separator", &csv_sep, "separator",
644 "print counts with custom separator"), 661 "print counts with custom separator"),
662 OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
663 "monitor event in cgroup name only",
664 parse_cgroups),
645 OPT_END() 665 OPT_END()
646}; 666};
647 667
@@ -682,9 +702,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
682 if (run_count <= 0) 702 if (run_count <= 0)
683 usage_with_options(stat_usage, options); 703 usage_with_options(stat_usage, options);
684 704
685 /* no_aggr is for system-wide only */ 705 /* no_aggr, cgroup are for system-wide only */
686 if (no_aggr && !system_wide) 706 if ((no_aggr || nr_cgroups) && !system_wide) {
707 fprintf(stderr, "both cgroup and no-aggregation "
708 "modes only available in system-wide mode\n");
709
687 usage_with_options(stat_usage, options); 710 usage_with_options(stat_usage, options);
711 }
688 712
689 /* Set attrs and nr_counters if no event is selected and !null_run */ 713 /* Set attrs and nr_counters if no event is selected and !null_run */
690 if (!null_run && !evsel_list->nr_entries) { 714 if (!null_run && !evsel_list->nr_entries) {