aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/perf_counter
diff options
context:
space:
mode:
authorMike Galbraith <efault@gmx.de>2009-03-27 07:13:43 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-06 03:30:44 -0400
commit9dd499889bdb12ac0e412ccdd718fe0d348258f2 (patch)
treec3c74684dac1e32aaf413c81e94d0dd15a154199 /Documentation/perf_counter
parent4e935e47177c3b26cf383e79849bae2a464d0160 (diff)
perf_counter tools: kerneltop: add real-time data acquisition thread
Decouple kerneltop display from event acquisition by introducing a separate data acquisition thread. This fixes annnoying kerneltop display refresh jitter and missed events. Also add a -r <prio> option, to switch the data acquisition thread to real-time priority. Signed-off-by: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Orig-LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'Documentation/perf_counter')
-rw-r--r--Documentation/perf_counter/kerneltop.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c
index 430810dae1fe..33b4fcf6e489 100644
--- a/Documentation/perf_counter/kerneltop.c
+++ b/Documentation/perf_counter/kerneltop.c
@@ -77,6 +77,8 @@
77#include <errno.h> 77#include <errno.h>
78#include <ctype.h> 78#include <ctype.h>
79#include <time.h> 79#include <time.h>
80#include <sched.h>
81#include <pthread.h>
80 82
81#include <sys/syscall.h> 83#include <sys/syscall.h>
82#include <sys/ioctl.h> 84#include <sys/ioctl.h>
@@ -181,6 +183,7 @@ static int tid = -1;
181static int profile_cpu = -1; 183static int profile_cpu = -1;
182static int nr_cpus = 0; 184static int nr_cpus = 0;
183static int nmi = 1; 185static int nmi = 1;
186static unsigned int realtime_prio = 0;
184static int group = 0; 187static int group = 0;
185static unsigned int page_size; 188static unsigned int page_size;
186static unsigned int mmap_pages = 16; 189static unsigned int mmap_pages = 16;
@@ -334,6 +337,7 @@ static void display_help(void)
334 " -l # show scale factor for RR events\n" 337 " -l # show scale factor for RR events\n"
335 " -d delay --delay=<seconds> # sampling/display delay [default: 2]\n" 338 " -d delay --delay=<seconds> # sampling/display delay [default: 2]\n"
336 " -f CNT --filter=CNT # min-event-count filter [default: 100]\n\n" 339 " -f CNT --filter=CNT # min-event-count filter [default: 100]\n\n"
340 " -r prio --realtime=<prio> # event acquisition runs with SCHED_FIFO policy\n"
337 " -s symbol --symbol=<symbol> # function to be showed annotated one-shot\n" 341 " -s symbol --symbol=<symbol> # function to be showed annotated one-shot\n"
338 " -x path --vmlinux=<path> # the vmlinux binary, required for -s use\n" 342 " -x path --vmlinux=<path> # the vmlinux binary, required for -s use\n"
339 " -z --zero # zero counts after display\n" 343 " -z --zero # zero counts after display\n"
@@ -620,7 +624,6 @@ static int compare(const void *__sym1, const void *__sym2)
620 return sym_weight(sym1) < sym_weight(sym2); 624 return sym_weight(sym1) < sym_weight(sym2);
621} 625}
622 626
623static time_t last_refresh;
624static long events; 627static long events;
625static long userspace_events; 628static long userspace_events;
626static const char CONSOLE_CLEAR[] = ""; 629static const char CONSOLE_CLEAR[] = "";
@@ -634,6 +637,7 @@ static void print_sym_table(void)
634 float events_per_sec = events/delay_secs; 637 float events_per_sec = events/delay_secs;
635 float kevents_per_sec = (events-userspace_events)/delay_secs; 638 float kevents_per_sec = (events-userspace_events)/delay_secs;
636 639
640 events = userspace_events = 0;
637 memcpy(tmp, sym_table, sizeof(sym_table[0])*sym_table_count); 641 memcpy(tmp, sym_table, sizeof(sym_table[0])*sym_table_count);
638 qsort(tmp, sym_table_count, sizeof(tmp[0]), compare); 642 qsort(tmp, sym_table_count, sizeof(tmp[0]), compare);
639 643
@@ -714,8 +718,6 @@ static void print_sym_table(void)
714 if (sym_filter_entry) 718 if (sym_filter_entry)
715 show_details(sym_filter_entry); 719 show_details(sym_filter_entry);
716 720
717 last_refresh = time(NULL);
718
719 { 721 {
720 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 722 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
721 723
@@ -726,6 +728,16 @@ static void print_sym_table(void)
726 } 728 }
727} 729}
728 730
731static void *display_thread(void *arg)
732{
733 printf("KernelTop refresh period: %d seconds\n", delay_secs);
734
735 while (!sleep(delay_secs))
736 print_sym_table();
737
738 return NULL;
739}
740
729static int read_symbol(FILE *in, struct sym_entry *s) 741static int read_symbol(FILE *in, struct sym_entry *s)
730{ 742{
731 static int filter_match = 0; 743 static int filter_match = 0;
@@ -1081,19 +1093,20 @@ static void process_options(int argc, char *argv[])
1081 {"filter", required_argument, NULL, 'f'}, 1093 {"filter", required_argument, NULL, 'f'},
1082 {"group", required_argument, NULL, 'g'}, 1094 {"group", required_argument, NULL, 'g'},
1083 {"help", no_argument, NULL, 'h'}, 1095 {"help", no_argument, NULL, 'h'},
1084 {"scale", no_argument, NULL, 'l'},
1085 {"nmi", required_argument, NULL, 'n'}, 1096 {"nmi", required_argument, NULL, 'n'},
1097 {"mmap_info", no_argument, NULL, 'M'},
1098 {"mmap_pages", required_argument, NULL, 'm'},
1099 {"munmap_info", no_argument, NULL, 'U'},
1086 {"pid", required_argument, NULL, 'p'}, 1100 {"pid", required_argument, NULL, 'p'},
1087 {"vmlinux", required_argument, NULL, 'x'}, 1101 {"realtime", required_argument, NULL, 'r'},
1102 {"scale", no_argument, NULL, 'l'},
1088 {"symbol", required_argument, NULL, 's'}, 1103 {"symbol", required_argument, NULL, 's'},
1089 {"stat", no_argument, NULL, 'S'}, 1104 {"stat", no_argument, NULL, 'S'},
1105 {"vmlinux", required_argument, NULL, 'x'},
1090 {"zero", no_argument, NULL, 'z'}, 1106 {"zero", no_argument, NULL, 'z'},
1091 {"mmap_pages", required_argument, NULL, 'm'},
1092 {"mmap_info", no_argument, NULL, 'M'},
1093 {"munmap_info", no_argument, NULL, 'U'},
1094 {NULL, 0, NULL, 0 } 1107 {NULL, 0, NULL, 0 }
1095 }; 1108 };
1096 int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hln:m:p:s:Sx:zMU", 1109 int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hln:m:p:r:s:Sx:zMU",
1097 long_options, &option_index); 1110 long_options, &option_index);
1098 if (c == -1) 1111 if (c == -1)
1099 break; 1112 break;
@@ -1127,6 +1140,7 @@ static void process_options(int argc, char *argv[])
1127 profile_cpu = -1; 1140 profile_cpu = -1;
1128 } 1141 }
1129 tid = atoi(optarg); break; 1142 tid = atoi(optarg); break;
1143 case 'r': realtime_prio = atoi(optarg); break;
1130 case 's': sym_filter = strdup(optarg); break; 1144 case 's': sym_filter = strdup(optarg); break;
1131 case 'S': run_perfstat = 1; break; 1145 case 'S': run_perfstat = 1; break;
1132 case 'x': vmlinux = strdup(optarg); break; 1146 case 'x': vmlinux = strdup(optarg); break;
@@ -1289,6 +1303,7 @@ int main(int argc, char *argv[])
1289 struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; 1303 struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS];
1290 struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; 1304 struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
1291 struct perf_counter_hw_event hw_event; 1305 struct perf_counter_hw_event hw_event;
1306 pthread_t thread;
1292 int i, counter, group_fd, nr_poll = 0; 1307 int i, counter, group_fd, nr_poll = 0;
1293 unsigned int cpu; 1308 unsigned int cpu;
1294 int ret; 1309 int ret;
@@ -1363,8 +1378,20 @@ int main(int argc, char *argv[])
1363 } 1378 }
1364 } 1379 }
1365 1380
1366 printf("KernelTop refresh period: %d seconds\n", delay_secs); 1381 if (pthread_create(&thread, NULL, display_thread, NULL)) {
1367 last_refresh = time(NULL); 1382 printf("Could not create display thread.\n");
1383 exit(-1);
1384 }
1385
1386 if (realtime_prio) {
1387 struct sched_param param;
1388
1389 param.sched_priority = realtime_prio;
1390 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
1391 printf("Could not set realtime priority.\n");
1392 exit(-1);
1393 }
1394 }
1368 1395
1369 while (1) { 1396 while (1) {
1370 int hits = events; 1397 int hits = events;
@@ -1374,14 +1401,8 @@ int main(int argc, char *argv[])
1374 mmap_read(&mmap_array[i][counter]); 1401 mmap_read(&mmap_array[i][counter]);
1375 } 1402 }
1376 1403
1377 if (time(NULL) >= last_refresh + delay_secs) {
1378 print_sym_table();
1379 events = userspace_events = 0;
1380 }
1381
1382 if (hits == events) 1404 if (hits == events)
1383 ret = poll(event_array, nr_poll, 1000); 1405 ret = poll(event_array, nr_poll, 100);
1384 hits = events;
1385 } 1406 }
1386 1407
1387 return 0; 1408 return 0;