aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/perf_counter/builtin-top.c
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/perf_counter/builtin-top.c')
-rw-r--r--Documentation/perf_counter/builtin-top.c204
1 files changed, 4 insertions, 200 deletions
diff --git a/Documentation/perf_counter/builtin-top.c b/Documentation/perf_counter/builtin-top.c
index 601bddbc30d5..98e8690b6bcb 100644
--- a/Documentation/perf_counter/builtin-top.c
+++ b/Documentation/perf_counter/builtin-top.c
@@ -28,25 +28,6 @@
28 8.54 - ffffffff805001a3 : ip_queue_xmit 28 8.54 - ffffffff805001a3 : ip_queue_xmit
29 */ 29 */
30 30
31/*
32 * perfstat: /usr/bin/time -alike performance counter statistics utility
33
34 It summarizes the counter events of all tasks (and child tasks),
35 covering all CPUs that the command (or workload) executes on.
36 It only counts the per-task events of the workload started,
37 independent of how many other tasks run on those CPUs.
38
39 Sample output:
40
41 $ ./perfstat -e 1 -e 3 -e 5 ls -lR /usr/include/ >/dev/null
42
43 Performance counter stats for 'ls':
44
45 163516953 instructions
46 2295 cache-misses
47 2855182 branch-misses
48 */
49
50 /* 31 /*
51 * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com> 32 * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
52 * 33 *
@@ -149,7 +130,6 @@ asmlinkage int sys_perf_counter_open(
149 130
150#define EID(type, id) (((__u64)(type) << PERF_COUNTER_TYPE_SHIFT) | (id)) 131#define EID(type, id) (((__u64)(type) << PERF_COUNTER_TYPE_SHIFT) | (id))
151 132
152static int run_perfstat = 0;
153static int system_wide = 0; 133static int system_wide = 0;
154 134
155static int nr_counters = 0; 135static int nr_counters = 0;
@@ -203,7 +183,7 @@ struct source_line {
203static struct source_line *lines; 183static struct source_line *lines;
204static struct source_line **lines_tail; 184static struct source_line **lines_tail;
205 185
206const unsigned int default_count[] = { 186static const unsigned int default_count[] = {
207 1000000, 187 1000000,
208 1000000, 188 1000000,
209 10000, 189 10000,
@@ -291,26 +271,8 @@ static void display_events_help(void)
291 " rNNN: raw PMU events (eventsel+umask)\n\n"); 271 " rNNN: raw PMU events (eventsel+umask)\n\n");
292} 272}
293 273
294static void display_perfstat_help(void)
295{
296 printf(
297 "Usage: perfstat [<events...>] <cmd...>\n\n"
298 "PerfStat Options (up to %d event types can be specified):\n\n",
299 MAX_COUNTERS);
300
301 display_events_help();
302
303 printf(
304 " -l # scale counter values\n"
305 " -a # system-wide collection\n");
306 exit(0);
307}
308
309static void display_help(void) 274static void display_help(void)
310{ 275{
311 if (run_perfstat)
312 return display_perfstat_help();
313
314 printf( 276 printf(
315 "Usage: kerneltop [<options>]\n" 277 "Usage: kerneltop [<options>]\n"
316 " Or: kerneltop -S [<options>] COMMAND [ARGS]\n\n" 278 " Or: kerneltop -S [<options>] COMMAND [ARGS]\n\n"
@@ -320,8 +282,6 @@ static void display_help(void)
320 display_events_help(); 282 display_events_help();
321 283
322 printf( 284 printf(
323 " -S --stat # perfstat COMMAND\n"
324 " -a # system-wide collection (for perfstat)\n\n"
325 " -c CNT --count=CNT # event period to sample\n\n" 285 " -c CNT --count=CNT # event period to sample\n\n"
326 " -C CPU --cpu=CPU # CPU (-1 for all) [default: -1]\n" 286 " -C CPU --cpu=CPU # CPU (-1 for all) [default: -1]\n"
327 " -p PID --pid=PID # PID of sampled task (-1 for all) [default: -1]\n\n" 287 " -p PID --pid=PID # PID of sampled task (-1 for all) [default: -1]\n\n"
@@ -420,151 +380,6 @@ again:
420 return 0; 380 return 0;
421} 381}
422 382
423
424/*
425 * perfstat
426 */
427
428char fault_here[1000000];
429
430static void create_perfstat_counter(int counter)
431{
432 struct perf_counter_hw_event hw_event;
433
434 memset(&hw_event, 0, sizeof(hw_event));
435 hw_event.config = event_id[counter];
436 hw_event.record_type = 0;
437 hw_event.nmi = 0;
438 if (scale)
439 hw_event.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
440 PERF_FORMAT_TOTAL_TIME_RUNNING;
441
442 if (system_wide) {
443 int cpu;
444 for (cpu = 0; cpu < nr_cpus; cpu ++) {
445 fd[cpu][counter] = sys_perf_counter_open(&hw_event, -1, cpu, -1, 0);
446 if (fd[cpu][counter] < 0) {
447 printf("perfstat error: syscall returned with %d (%s)\n",
448 fd[cpu][counter], strerror(errno));
449 exit(-1);
450 }
451 }
452 } else {
453 hw_event.inherit = 1;
454 hw_event.disabled = 1;
455
456 fd[0][counter] = sys_perf_counter_open(&hw_event, 0, -1, -1, 0);
457 if (fd[0][counter] < 0) {
458 printf("perfstat error: syscall returned with %d (%s)\n",
459 fd[0][counter], strerror(errno));
460 exit(-1);
461 }
462 }
463}
464
465int do_perfstat(int argc, char *argv[])
466{
467 unsigned long long t0, t1;
468 int counter;
469 ssize_t res;
470 int status;
471 int pid;
472
473 if (!system_wide)
474 nr_cpus = 1;
475
476 for (counter = 0; counter < nr_counters; counter++)
477 create_perfstat_counter(counter);
478
479 argc -= optind;
480 argv += optind;
481
482 if (!argc)
483 display_help();
484
485 /*
486 * Enable counters and exec the command:
487 */
488 t0 = rdclock();
489 prctl(PR_TASK_PERF_COUNTERS_ENABLE);
490
491 if ((pid = fork()) < 0)
492 perror("failed to fork");
493 if (!pid) {
494 if (execvp(argv[0], argv)) {
495 perror(argv[0]);
496 exit(-1);
497 }
498 }
499 while (wait(&status) >= 0)
500 ;
501 prctl(PR_TASK_PERF_COUNTERS_DISABLE);
502 t1 = rdclock();
503
504 fflush(stdout);
505
506 fprintf(stderr, "\n");
507 fprintf(stderr, " Performance counter stats for \'%s\':\n",
508 argv[0]);
509 fprintf(stderr, "\n");
510
511 for (counter = 0; counter < nr_counters; counter++) {
512 int cpu, nv;
513 __u64 count[3], single_count[3];
514 int scaled;
515
516 count[0] = count[1] = count[2] = 0;
517 nv = scale ? 3 : 1;
518 for (cpu = 0; cpu < nr_cpus; cpu ++) {
519 res = read(fd[cpu][counter],
520 single_count, nv * sizeof(__u64));
521 assert(res == nv * sizeof(__u64));
522
523 count[0] += single_count[0];
524 if (scale) {
525 count[1] += single_count[1];
526 count[2] += single_count[2];
527 }
528 }
529
530 scaled = 0;
531 if (scale) {
532 if (count[2] == 0) {
533 fprintf(stderr, " %14s %-20s\n",
534 "<not counted>", event_name(counter));
535 continue;
536 }
537 if (count[2] < count[1]) {
538 scaled = 1;
539 count[0] = (unsigned long long)
540 ((double)count[0] * count[1] / count[2] + 0.5);
541 }
542 }
543
544 if (event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK) ||
545 event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK)) {
546
547 double msecs = (double)count[0] / 1000000;
548
549 fprintf(stderr, " %14.6f %-20s (msecs)",
550 msecs, event_name(counter));
551 } else {
552 fprintf(stderr, " %14Ld %-20s (events)",
553 count[0], event_name(counter));
554 }
555 if (scaled)
556 fprintf(stderr, " (scaled from %.2f%%)",
557 (double) count[2] / count[1] * 100);
558 fprintf(stderr, "\n");
559 }
560 fprintf(stderr, "\n");
561 fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n",
562 (double)(t1-t0)/1e6);
563 fprintf(stderr, "\n");
564
565 return 0;
566}
567
568/* 383/*
569 * Symbols 384 * Symbols
570 */ 385 */
@@ -805,7 +620,7 @@ static int read_symbol(FILE *in, struct sym_entry *s)
805 return 0; 620 return 0;
806} 621}
807 622
808int compare_addr(const void *__sym1, const void *__sym2) 623static int compare_addr(const void *__sym1, const void *__sym2)
809{ 624{
810 const struct sym_entry *sym1 = __sym1, *sym2 = __sym2; 625 const struct sym_entry *sym1 = __sym1, *sym2 = __sym2;
811 626
@@ -1070,9 +885,6 @@ static void process_options(int argc, char **argv)
1070{ 885{
1071 int error = 0, counter; 886 int error = 0, counter;
1072 887
1073 if (strstr(argv[0], "perfstat"))
1074 run_perfstat = 1;
1075
1076 for (;;) { 888 for (;;) {
1077 int option_index = 0; 889 int option_index = 0;
1078 /** Options for getopt */ 890 /** Options for getopt */
@@ -1134,7 +946,6 @@ static void process_options(int argc, char **argv)
1134 tid = atoi(optarg); break; 946 tid = atoi(optarg); break;
1135 case 'r': realtime_prio = atoi(optarg); break; 947 case 'r': realtime_prio = atoi(optarg); break;
1136 case 's': sym_filter = strdup(optarg); break; 948 case 's': sym_filter = strdup(optarg); break;
1137 case 'S': run_perfstat = 1; break;
1138 case 'x': vmlinux = strdup(optarg); break; 949 case 'x': vmlinux = strdup(optarg); break;
1139 case 'z': zero = 1; break; 950 case 'z': zero = 1; break;
1140 case 'm': mmap_pages = atoi(optarg); break; 951 case 'm': mmap_pages = atoi(optarg); break;
@@ -1147,12 +958,8 @@ static void process_options(int argc, char **argv)
1147 display_help(); 958 display_help();
1148 959
1149 if (!nr_counters) { 960 if (!nr_counters) {
1150 if (run_perfstat) 961 nr_counters = 1;
1151 nr_counters = 8; 962 event_id[0] = 0;
1152 else {
1153 nr_counters = 1;
1154 event_id[0] = 0;
1155 }
1156 } 963 }
1157 964
1158 for (counter = 0; counter < nr_counters; counter++) { 965 for (counter = 0; counter < nr_counters; counter++) {
@@ -1308,9 +1115,6 @@ int cmd_top(int argc, char **argv, const char *prefix)
1308 assert(nr_cpus <= MAX_NR_CPUS); 1115 assert(nr_cpus <= MAX_NR_CPUS);
1309 assert(nr_cpus >= 0); 1116 assert(nr_cpus >= 0);
1310 1117
1311 if (run_perfstat)
1312 return do_perfstat(argc, argv);
1313
1314 if (tid != -1 || profile_cpu != -1) 1118 if (tid != -1 || profile_cpu != -1)
1315 nr_cpus = 1; 1119 nr_cpus = 1;
1316 1120