aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-top.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r--tools/perf/builtin-top.c1125
1 files changed, 397 insertions, 728 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index b513e40974f4..f2f3f4937aa2 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -20,15 +20,22 @@
20 20
21#include "perf.h" 21#include "perf.h"
22 22
23#include "util/annotate.h"
24#include "util/cache.h"
23#include "util/color.h" 25#include "util/color.h"
26#include "util/evlist.h"
27#include "util/evsel.h"
24#include "util/session.h" 28#include "util/session.h"
25#include "util/symbol.h" 29#include "util/symbol.h"
26#include "util/thread.h" 30#include "util/thread.h"
31#include "util/thread_map.h"
32#include "util/top.h"
27#include "util/util.h" 33#include "util/util.h"
28#include <linux/rbtree.h> 34#include <linux/rbtree.h>
29#include "util/parse-options.h" 35#include "util/parse-options.h"
30#include "util/parse-events.h" 36#include "util/parse-events.h"
31#include "util/cpumap.h" 37#include "util/cpumap.h"
38#include "util/xyarray.h"
32 39
33#include "util/debug.h" 40#include "util/debug.h"
34 41
@@ -38,11 +45,11 @@
38#include <stdio.h> 45#include <stdio.h>
39#include <termios.h> 46#include <termios.h>
40#include <unistd.h> 47#include <unistd.h>
48#include <inttypes.h>
41 49
42#include <errno.h> 50#include <errno.h>
43#include <time.h> 51#include <time.h>
44#include <sched.h> 52#include <sched.h>
45#include <pthread.h>
46 53
47#include <sys/syscall.h> 54#include <sys/syscall.h>
48#include <sys/ioctl.h> 55#include <sys/ioctl.h>
@@ -55,88 +62,44 @@
55#include <linux/unistd.h> 62#include <linux/unistd.h>
56#include <linux/types.h> 63#include <linux/types.h>
57 64
58static int *fd[MAX_NR_CPUS][MAX_COUNTERS]; 65static struct perf_top top = {
66 .count_filter = 5,
67 .delay_secs = 2,
68 .display_weighted = -1,
69 .target_pid = -1,
70 .target_tid = -1,
71 .active_symbols = LIST_HEAD_INIT(top.active_symbols),
72 .active_symbols_lock = PTHREAD_MUTEX_INITIALIZER,
73 .active_symbols_cond = PTHREAD_COND_INITIALIZER,
74 .freq = 1000, /* 1 KHz */
75};
59 76
60static bool system_wide = false; 77static bool system_wide = false;
61 78
62static int default_interval = 0; 79static bool use_tui, use_stdio;
63 80
64static int count_filter = 5; 81static int default_interval = 0;
65static int print_entries;
66 82
67static int target_pid = -1; 83static bool kptr_restrict_warned;
68static int target_tid = -1; 84static bool vmlinux_warned;
69static pid_t *all_tids = NULL;
70static int thread_num = 0;
71static bool inherit = false; 85static bool inherit = false;
72static int profile_cpu = -1;
73static int nr_cpus = 0;
74static int realtime_prio = 0; 86static int realtime_prio = 0;
75static bool group = false; 87static bool group = false;
76static unsigned int page_size; 88static unsigned int page_size;
77static unsigned int mmap_pages = 16; 89static unsigned int mmap_pages = 128;
78static int freq = 1000; /* 1 KHz */
79 90
80static int delay_secs = 2;
81static bool zero = false;
82static bool dump_symtab = false; 91static bool dump_symtab = false;
83 92
84static bool hide_kernel_symbols = false;
85static bool hide_user_symbols = false;
86static struct winsize winsize; 93static struct winsize winsize;
87 94
88/*
89 * Source
90 */
91
92struct source_line {
93 u64 eip;
94 unsigned long count[MAX_COUNTERS];
95 char *line;
96 struct source_line *next;
97};
98
99static const char *sym_filter = NULL; 95static const char *sym_filter = NULL;
100struct sym_entry *sym_filter_entry = NULL;
101struct sym_entry *sym_filter_entry_sched = NULL; 96struct sym_entry *sym_filter_entry_sched = NULL;
102static int sym_pcnt_filter = 5; 97static int sym_pcnt_filter = 5;
103static int sym_counter = 0;
104static int display_weighted = -1;
105static const char *cpu_list;
106
107/*
108 * Symbols
109 */
110
111struct sym_entry_source {
112 struct source_line *source;
113 struct source_line *lines;
114 struct source_line **lines_tail;
115 pthread_mutex_t lock;
116};
117
118struct sym_entry {
119 struct rb_node rb_node;
120 struct list_head node;
121 unsigned long snap_count;
122 double weight;
123 int skip;
124 u16 name_len;
125 u8 origin;
126 struct map *map;
127 struct sym_entry_source *src;
128 unsigned long count[0];
129};
130 98
131/* 99/*
132 * Source functions 100 * Source functions
133 */ 101 */
134 102
135static inline struct symbol *sym_entry__symbol(struct sym_entry *self)
136{
137 return ((void *)self) + symbol_conf.priv_size;
138}
139
140void get_term_dimensions(struct winsize *ws) 103void get_term_dimensions(struct winsize *ws)
141{ 104{
142 char *s = getenv("LINES"); 105 char *s = getenv("LINES");
@@ -161,10 +124,10 @@ void get_term_dimensions(struct winsize *ws)
161 124
162static void update_print_entries(struct winsize *ws) 125static void update_print_entries(struct winsize *ws)
163{ 126{
164 print_entries = ws->ws_row; 127 top.print_entries = ws->ws_row;
165 128
166 if (print_entries > 9) 129 if (top.print_entries > 9)
167 print_entries -= 9; 130 top.print_entries -= 9;
168} 131}
169 132
170static void sig_winch_handler(int sig __used) 133static void sig_winch_handler(int sig __used)
@@ -176,12 +139,9 @@ static void sig_winch_handler(int sig __used)
176static int parse_source(struct sym_entry *syme) 139static int parse_source(struct sym_entry *syme)
177{ 140{
178 struct symbol *sym; 141 struct symbol *sym;
179 struct sym_entry_source *source; 142 struct annotation *notes;
180 struct map *map; 143 struct map *map;
181 FILE *file; 144 int err = -1;
182 char command[PATH_MAX*2];
183 const char *path;
184 u64 len;
185 145
186 if (!syme) 146 if (!syme)
187 return -1; 147 return -1;
@@ -192,408 +152,137 @@ static int parse_source(struct sym_entry *syme)
192 /* 152 /*
193 * We can't annotate with just /proc/kallsyms 153 * We can't annotate with just /proc/kallsyms
194 */ 154 */
195 if (map->dso->origin == DSO__ORIG_KERNEL) 155 if (map->dso->symtab_type == SYMTAB__KALLSYMS) {
156 pr_err("Can't annotate %s: No vmlinux file was found in the "
157 "path\n", sym->name);
158 sleep(1);
196 return -1; 159 return -1;
197
198 if (syme->src == NULL) {
199 syme->src = zalloc(sizeof(*source));
200 if (syme->src == NULL)
201 return -1;
202 pthread_mutex_init(&syme->src->lock, NULL);
203 } 160 }
204 161
205 source = syme->src; 162 notes = symbol__annotation(sym);
206 163 if (notes->src != NULL) {
207 if (source->lines) { 164 pthread_mutex_lock(&notes->lock);
208 pthread_mutex_lock(&source->lock);
209 goto out_assign; 165 goto out_assign;
210 } 166 }
211 path = map->dso->long_name;
212
213 len = sym->end - sym->start;
214
215 sprintf(command,
216 "objdump --start-address=%#0*Lx --stop-address=%#0*Lx -dS %s",
217 BITS_PER_LONG / 4, map__rip_2objdump(map, sym->start),
218 BITS_PER_LONG / 4, map__rip_2objdump(map, sym->end), path);
219
220 file = popen(command, "r");
221 if (!file)
222 return -1;
223
224 pthread_mutex_lock(&source->lock);
225 source->lines_tail = &source->lines;
226 while (!feof(file)) {
227 struct source_line *src;
228 size_t dummy = 0;
229 char *c, *sep;
230
231 src = malloc(sizeof(struct source_line));
232 assert(src != NULL);
233 memset(src, 0, sizeof(struct source_line));
234
235 if (getline(&src->line, &dummy, file) < 0)
236 break;
237 if (!src->line)
238 break;
239 167
240 c = strchr(src->line, '\n'); 168 pthread_mutex_lock(&notes->lock);
241 if (c)
242 *c = 0;
243 169
244 src->next = NULL; 170 if (symbol__alloc_hist(sym, top.evlist->nr_entries) < 0) {
245 *source->lines_tail = src; 171 pthread_mutex_unlock(&notes->lock);
246 source->lines_tail = &src->next; 172 pr_err("Not enough memory for annotating '%s' symbol!\n",
247 173 sym->name);
248 src->eip = strtoull(src->line, &sep, 16); 174 sleep(1);
249 if (*sep == ':') 175 return err;
250 src->eip = map__objdump_2ip(map, src->eip);
251 else /* this line has no ip info (e.g. source line) */
252 src->eip = 0;
253 } 176 }
254 pclose(file); 177
178 err = symbol__annotate(sym, syme->map, 0);
179 if (err == 0) {
255out_assign: 180out_assign:
256 sym_filter_entry = syme; 181 top.sym_filter_entry = syme;
257 pthread_mutex_unlock(&source->lock); 182 }
258 return 0; 183
184 pthread_mutex_unlock(&notes->lock);
185 return err;
259} 186}
260 187
261static void __zero_source_counters(struct sym_entry *syme) 188static void __zero_source_counters(struct sym_entry *syme)
262{ 189{
263 int i; 190 struct symbol *sym = sym_entry__symbol(syme);
264 struct source_line *line; 191 symbol__annotate_zero_histograms(sym);
265
266 line = syme->src->lines;
267 while (line) {
268 for (i = 0; i < nr_counters; i++)
269 line->count[i] = 0;
270 line = line->next;
271 }
272} 192}
273 193
274static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip) 194static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip)
275{ 195{
276 struct source_line *line; 196 struct annotation *notes;
277 197 struct symbol *sym;
278 if (syme != sym_filter_entry)
279 return;
280 198
281 if (pthread_mutex_trylock(&syme->src->lock)) 199 if (syme != top.sym_filter_entry)
282 return; 200 return;
283 201
284 if (syme->src == NULL || syme->src->source == NULL) 202 sym = sym_entry__symbol(syme);
285 goto out_unlock; 203 notes = symbol__annotation(sym);
286
287 for (line = syme->src->lines; line; line = line->next) {
288 /* skip lines without IP info */
289 if (line->eip == 0)
290 continue;
291 if (line->eip == ip) {
292 line->count[counter]++;
293 break;
294 }
295 if (line->eip > ip)
296 break;
297 }
298out_unlock:
299 pthread_mutex_unlock(&syme->src->lock);
300}
301
302#define PATTERN_LEN (BITS_PER_LONG / 4 + 2)
303
304static void lookup_sym_source(struct sym_entry *syme)
305{
306 struct symbol *symbol = sym_entry__symbol(syme);
307 struct source_line *line;
308 char pattern[PATTERN_LEN + 1];
309
310 sprintf(pattern, "%0*Lx <", BITS_PER_LONG / 4,
311 map__rip_2objdump(syme->map, symbol->start));
312
313 pthread_mutex_lock(&syme->src->lock);
314 for (line = syme->src->lines; line; line = line->next) {
315 if (memcmp(line->line, pattern, PATTERN_LEN) == 0) {
316 syme->src->source = line;
317 break;
318 }
319 }
320 pthread_mutex_unlock(&syme->src->lock);
321}
322 204
323static void show_lines(struct source_line *queue, int count, int total) 205 if (pthread_mutex_trylock(&notes->lock))
324{ 206 return;
325 int i;
326 struct source_line *line;
327 207
328 line = queue; 208 ip = syme->map->map_ip(syme->map, ip);
329 for (i = 0; i < count; i++) { 209 symbol__inc_addr_samples(sym, syme->map, counter, ip);
330 float pcnt = 100.0*(float)line->count[sym_counter]/(float)total;
331 210
332 printf("%8li %4.1f%%\t%s\n", line->count[sym_counter], pcnt, line->line); 211 pthread_mutex_unlock(&notes->lock);
333 line = line->next;
334 }
335} 212}
336 213
337#define TRACE_COUNT 3
338
339static void show_details(struct sym_entry *syme) 214static void show_details(struct sym_entry *syme)
340{ 215{
216 struct annotation *notes;
341 struct symbol *symbol; 217 struct symbol *symbol;
342 struct source_line *line; 218 int more;
343 struct source_line *line_queue = NULL;
344 int displayed = 0;
345 int line_queue_count = 0, total = 0, more = 0;
346 219
347 if (!syme) 220 if (!syme)
348 return; 221 return;
349 222
350 if (!syme->src->source)
351 lookup_sym_source(syme);
352
353 if (!syme->src->source)
354 return;
355
356 symbol = sym_entry__symbol(syme); 223 symbol = sym_entry__symbol(syme);
357 printf("Showing %s for %s\n", event_name(sym_counter), symbol->name); 224 notes = symbol__annotation(symbol);
358 printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter);
359
360 pthread_mutex_lock(&syme->src->lock);
361 line = syme->src->source;
362 while (line) {
363 total += line->count[sym_counter];
364 line = line->next;
365 }
366
367 line = syme->src->source;
368 while (line) {
369 float pcnt = 0.0;
370
371 if (!line_queue_count)
372 line_queue = line;
373 line_queue_count++;
374
375 if (line->count[sym_counter])
376 pcnt = 100.0 * line->count[sym_counter] / (float)total;
377 if (pcnt >= (float)sym_pcnt_filter) {
378 if (displayed <= print_entries)
379 show_lines(line_queue, line_queue_count, total);
380 else more++;
381 displayed += line_queue_count;
382 line_queue_count = 0;
383 line_queue = NULL;
384 } else if (line_queue_count > TRACE_COUNT) {
385 line_queue = line_queue->next;
386 line_queue_count--;
387 }
388
389 line->count[sym_counter] = zero ? 0 : line->count[sym_counter] * 7 / 8;
390 line = line->next;
391 }
392 pthread_mutex_unlock(&syme->src->lock);
393 if (more)
394 printf("%d lines not displayed, maybe increase display entries [e]\n", more);
395}
396
397/*
398 * Symbols will be added here in event__process_sample and will get out
399 * after decayed.
400 */
401static LIST_HEAD(active_symbols);
402static pthread_mutex_t active_symbols_lock = PTHREAD_MUTEX_INITIALIZER;
403
404/*
405 * Ordering weight: count-1 * count-2 * ... / count-n
406 */
407static double sym_weight(const struct sym_entry *sym)
408{
409 double weight = sym->snap_count;
410 int counter;
411 225
412 if (!display_weighted) 226 pthread_mutex_lock(&notes->lock);
413 return weight;
414 227
415 for (counter = 1; counter < nr_counters-1; counter++) 228 if (notes->src == NULL)
416 weight *= sym->count[counter]; 229 goto out_unlock;
417 230
418 weight /= (sym->count[counter] + 1); 231 printf("Showing %s for %s\n", event_name(top.sym_evsel), symbol->name);
232 printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter);
419 233
420 return weight; 234 more = symbol__annotate_printf(symbol, syme->map, top.sym_evsel->idx,
235 0, sym_pcnt_filter, top.print_entries, 4);
236 if (top.zero)
237 symbol__annotate_zero_histogram(symbol, top.sym_evsel->idx);
238 else
239 symbol__annotate_decay_histogram(symbol, top.sym_evsel->idx);
240 if (more != 0)
241 printf("%d lines not displayed, maybe increase display entries [e]\n", more);
242out_unlock:
243 pthread_mutex_unlock(&notes->lock);
421} 244}
422 245
423static long samples;
424static long kernel_samples, us_samples;
425static long exact_samples;
426static long guest_us_samples, guest_kernel_samples;
427static const char CONSOLE_CLEAR[] = ""; 246static const char CONSOLE_CLEAR[] = "";
428 247
429static void __list_insert_active_sym(struct sym_entry *syme) 248static void __list_insert_active_sym(struct sym_entry *syme)
430{ 249{
431 list_add(&syme->node, &active_symbols); 250 list_add(&syme->node, &top.active_symbols);
432}
433
434static void list_remove_active_sym(struct sym_entry *syme)
435{
436 pthread_mutex_lock(&active_symbols_lock);
437 list_del_init(&syme->node);
438 pthread_mutex_unlock(&active_symbols_lock);
439}
440
441static void rb_insert_active_sym(struct rb_root *tree, struct sym_entry *se)
442{
443 struct rb_node **p = &tree->rb_node;
444 struct rb_node *parent = NULL;
445 struct sym_entry *iter;
446
447 while (*p != NULL) {
448 parent = *p;
449 iter = rb_entry(parent, struct sym_entry, rb_node);
450
451 if (se->weight > iter->weight)
452 p = &(*p)->rb_left;
453 else
454 p = &(*p)->rb_right;
455 }
456
457 rb_link_node(&se->rb_node, parent, p);
458 rb_insert_color(&se->rb_node, tree);
459} 251}
460 252
461static void print_sym_table(void) 253static void print_sym_table(struct perf_session *session)
462{ 254{
463 int printed = 0, j; 255 char bf[160];
464 int counter, snap = !display_weighted ? sym_counter : 0; 256 int printed = 0;
465 float samples_per_sec = samples/delay_secs;
466 float ksamples_per_sec = kernel_samples/delay_secs;
467 float us_samples_per_sec = (us_samples)/delay_secs;
468 float guest_kernel_samples_per_sec = (guest_kernel_samples)/delay_secs;
469 float guest_us_samples_per_sec = (guest_us_samples)/delay_secs;
470 float esamples_percent = (100.0*exact_samples)/samples;
471 float sum_ksamples = 0.0;
472 struct sym_entry *syme, *n;
473 struct rb_root tmp = RB_ROOT;
474 struct rb_node *nd; 257 struct rb_node *nd;
475 int sym_width = 0, dso_width = 0, dso_short_width = 0; 258 struct sym_entry *syme;
259 struct rb_root tmp = RB_ROOT;
476 const int win_width = winsize.ws_col - 1; 260 const int win_width = winsize.ws_col - 1;
477 261 int sym_width, dso_width, dso_short_width;
478 samples = us_samples = kernel_samples = exact_samples = 0; 262 float sum_ksamples = perf_top__decay_samples(&top, &tmp);
479 guest_kernel_samples = guest_us_samples = 0;
480
481 /* Sort the active symbols */
482 pthread_mutex_lock(&active_symbols_lock);
483 syme = list_entry(active_symbols.next, struct sym_entry, node);
484 pthread_mutex_unlock(&active_symbols_lock);
485
486 list_for_each_entry_safe_from(syme, n, &active_symbols, node) {
487 syme->snap_count = syme->count[snap];
488 if (syme->snap_count != 0) {
489
490 if ((hide_user_symbols &&
491 syme->origin == PERF_RECORD_MISC_USER) ||
492 (hide_kernel_symbols &&
493 syme->origin == PERF_RECORD_MISC_KERNEL)) {
494 list_remove_active_sym(syme);
495 continue;
496 }
497 syme->weight = sym_weight(syme);
498 rb_insert_active_sym(&tmp, syme);
499 sum_ksamples += syme->snap_count;
500
501 for (j = 0; j < nr_counters; j++)
502 syme->count[j] = zero ? 0 : syme->count[j] * 7 / 8;
503 } else
504 list_remove_active_sym(syme);
505 }
506 263
507 puts(CONSOLE_CLEAR); 264 puts(CONSOLE_CLEAR);
508 265
509 printf("%-*.*s\n", win_width, win_width, graph_dotted_line); 266 perf_top__header_snprintf(&top, bf, sizeof(bf));
510 if (!perf_guest) { 267 printf("%s\n", bf);
511 printf(" PerfTop:%8.0f irqs/sec kernel:%4.1f%%"
512 " exact: %4.1f%% [",
513 samples_per_sec,
514 100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) /
515 samples_per_sec)),
516 esamples_percent);
517 } else {
518 printf(" PerfTop:%8.0f irqs/sec kernel:%4.1f%% us:%4.1f%%"
519 " guest kernel:%4.1f%% guest us:%4.1f%%"
520 " exact: %4.1f%% [",
521 samples_per_sec,
522 100.0 - (100.0 * ((samples_per_sec-ksamples_per_sec) /
523 samples_per_sec)),
524 100.0 - (100.0 * ((samples_per_sec-us_samples_per_sec) /
525 samples_per_sec)),
526 100.0 - (100.0 * ((samples_per_sec -
527 guest_kernel_samples_per_sec) /
528 samples_per_sec)),
529 100.0 - (100.0 * ((samples_per_sec -
530 guest_us_samples_per_sec) /
531 samples_per_sec)),
532 esamples_percent);
533 }
534
535 if (nr_counters == 1 || !display_weighted) {
536 printf("%Ld", (u64)attrs[0].sample_period);
537 if (freq)
538 printf("Hz ");
539 else
540 printf(" ");
541 }
542
543 if (!display_weighted)
544 printf("%s", event_name(sym_counter));
545 else for (counter = 0; counter < nr_counters; counter++) {
546 if (counter)
547 printf("/");
548
549 printf("%s", event_name(counter));
550 }
551 268
552 printf( "], "); 269 perf_top__reset_sample_counters(&top);
553
554 if (target_pid != -1)
555 printf(" (target_pid: %d", target_pid);
556 else if (target_tid != -1)
557 printf(" (target_tid: %d", target_tid);
558 else
559 printf(" (all");
560
561 if (profile_cpu != -1)
562 printf(", cpu: %d)\n", profile_cpu);
563 else {
564 if (target_tid != -1)
565 printf(")\n");
566 else
567 printf(", %d CPUs)\n", nr_cpus);
568 }
569 270
570 printf("%-*.*s\n", win_width, win_width, graph_dotted_line); 271 printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
571 272
572 if (sym_filter_entry) { 273 if (session->hists.stats.total_lost != 0) {
573 show_details(sym_filter_entry); 274 color_fprintf(stdout, PERF_COLOR_RED, "WARNING:");
574 return; 275 printf(" LOST %" PRIu64 " events, Check IO/CPU overload\n",
276 session->hists.stats.total_lost);
575 } 277 }
576 278
577 /* 279 if (top.sym_filter_entry) {
578 * Find the longest symbol name that will be displayed 280 show_details(top.sym_filter_entry);
579 */ 281 return;
580 for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
581 syme = rb_entry(nd, struct sym_entry, rb_node);
582 if (++printed > print_entries ||
583 (int)syme->snap_count < count_filter)
584 continue;
585
586 if (syme->map->dso->long_name_len > dso_width)
587 dso_width = syme->map->dso->long_name_len;
588
589 if (syme->map->dso->short_name_len > dso_short_width)
590 dso_short_width = syme->map->dso->short_name_len;
591
592 if (syme->name_len > sym_width)
593 sym_width = syme->name_len;
594 } 282 }
595 283
596 printed = 0; 284 perf_top__find_widths(&top, &tmp, &dso_width, &dso_short_width,
285 &sym_width);
597 286
598 if (sym_width + dso_width > winsize.ws_col - 29) { 287 if (sym_width + dso_width > winsize.ws_col - 29) {
599 dso_width = dso_short_width; 288 dso_width = dso_short_width;
@@ -601,7 +290,7 @@ static void print_sym_table(void)
601 sym_width = winsize.ws_col - dso_width - 29; 290 sym_width = winsize.ws_col - dso_width - 29;
602 } 291 }
603 putchar('\n'); 292 putchar('\n');
604 if (nr_counters == 1) 293 if (top.evlist->nr_entries == 1)
605 printf(" samples pcnt"); 294 printf(" samples pcnt");
606 else 295 else
607 printf(" weight samples pcnt"); 296 printf(" weight samples pcnt");
@@ -610,7 +299,7 @@ static void print_sym_table(void)
610 printf(" RIP "); 299 printf(" RIP ");
611 printf(" %-*.*s DSO\n", sym_width, sym_width, "function"); 300 printf(" %-*.*s DSO\n", sym_width, sym_width, "function");
612 printf(" %s _______ _____", 301 printf(" %s _______ _____",
613 nr_counters == 1 ? " " : "______"); 302 top.evlist->nr_entries == 1 ? " " : "______");
614 if (verbose) 303 if (verbose)
615 printf(" ________________"); 304 printf(" ________________");
616 printf(" %-*.*s", sym_width, sym_width, graph_line); 305 printf(" %-*.*s", sym_width, sym_width, graph_line);
@@ -623,20 +312,21 @@ static void print_sym_table(void)
623 312
624 syme = rb_entry(nd, struct sym_entry, rb_node); 313 syme = rb_entry(nd, struct sym_entry, rb_node);
625 sym = sym_entry__symbol(syme); 314 sym = sym_entry__symbol(syme);
626 if (++printed > print_entries || (int)syme->snap_count < count_filter) 315 if (++printed > top.print_entries ||
316 (int)syme->snap_count < top.count_filter)
627 continue; 317 continue;
628 318
629 pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / 319 pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) /
630 sum_ksamples)); 320 sum_ksamples));
631 321
632 if (nr_counters == 1 || !display_weighted) 322 if (top.evlist->nr_entries == 1 || !top.display_weighted)
633 printf("%20.2f ", syme->weight); 323 printf("%20.2f ", syme->weight);
634 else 324 else
635 printf("%9.1f %10ld ", syme->weight, syme->snap_count); 325 printf("%9.1f %10ld ", syme->weight, syme->snap_count);
636 326
637 percent_color_fprintf(stdout, "%4.1f%%", pcnt); 327 percent_color_fprintf(stdout, "%4.1f%%", pcnt);
638 if (verbose) 328 if (verbose)
639 printf(" %016llx", sym->start); 329 printf(" %016" PRIx64, sym->start);
640 printf(" %-*.*s", sym_width, sym_width, sym->name); 330 printf(" %-*.*s", sym_width, sym_width, sym->name);
641 printf(" %-*.*s\n", dso_width, dso_width, 331 printf(" %-*.*s\n", dso_width, dso_width,
642 dso_width >= syme->map->dso->long_name_len ? 332 dso_width >= syme->map->dso->long_name_len ?
@@ -688,10 +378,8 @@ static void prompt_symbol(struct sym_entry **target, const char *msg)
688 378
689 /* zero counters of active symbol */ 379 /* zero counters of active symbol */
690 if (syme) { 380 if (syme) {
691 pthread_mutex_lock(&syme->src->lock);
692 __zero_source_counters(syme); 381 __zero_source_counters(syme);
693 *target = NULL; 382 *target = NULL;
694 pthread_mutex_unlock(&syme->src->lock);
695 } 383 }
696 384
697 fprintf(stdout, "\n%s: ", msg); 385 fprintf(stdout, "\n%s: ", msg);
@@ -702,11 +390,11 @@ static void prompt_symbol(struct sym_entry **target, const char *msg)
702 if (p) 390 if (p)
703 *p = 0; 391 *p = 0;
704 392
705 pthread_mutex_lock(&active_symbols_lock); 393 pthread_mutex_lock(&top.active_symbols_lock);
706 syme = list_entry(active_symbols.next, struct sym_entry, node); 394 syme = list_entry(top.active_symbols.next, struct sym_entry, node);
707 pthread_mutex_unlock(&active_symbols_lock); 395 pthread_mutex_unlock(&top.active_symbols_lock);
708 396
709 list_for_each_entry_safe_from(syme, n, &active_symbols, node) { 397 list_for_each_entry_safe_from(syme, n, &top.active_symbols, node) {
710 struct symbol *sym = sym_entry__symbol(syme); 398 struct symbol *sym = sym_entry__symbol(syme);
711 399
712 if (!strcmp(buf, sym->name)) { 400 if (!strcmp(buf, sym->name)) {
@@ -730,34 +418,34 @@ static void print_mapped_keys(void)
730{ 418{
731 char *name = NULL; 419 char *name = NULL;
732 420
733 if (sym_filter_entry) { 421 if (top.sym_filter_entry) {
734 struct symbol *sym = sym_entry__symbol(sym_filter_entry); 422 struct symbol *sym = sym_entry__symbol(top.sym_filter_entry);
735 name = sym->name; 423 name = sym->name;
736 } 424 }
737 425
738 fprintf(stdout, "\nMapped keys:\n"); 426 fprintf(stdout, "\nMapped keys:\n");
739 fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", delay_secs); 427 fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", top.delay_secs);
740 fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries); 428 fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", top.print_entries);
741 429
742 if (nr_counters > 1) 430 if (top.evlist->nr_entries > 1)
743 fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_counter)); 431 fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(top.sym_evsel));
744 432
745 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter); 433 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", top.count_filter);
746 434
747 fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter); 435 fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter);
748 fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL"); 436 fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL");
749 fprintf(stdout, "\t[S] stop annotation.\n"); 437 fprintf(stdout, "\t[S] stop annotation.\n");
750 438
751 if (nr_counters > 1) 439 if (top.evlist->nr_entries > 1)
752 fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0); 440 fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", top.display_weighted ? 1 : 0);
753 441
754 fprintf(stdout, 442 fprintf(stdout,
755 "\t[K] hide kernel_symbols symbols. \t(%s)\n", 443 "\t[K] hide kernel_symbols symbols. \t(%s)\n",
756 hide_kernel_symbols ? "yes" : "no"); 444 top.hide_kernel_symbols ? "yes" : "no");
757 fprintf(stdout, 445 fprintf(stdout,
758 "\t[U] hide user symbols. \t(%s)\n", 446 "\t[U] hide user symbols. \t(%s)\n",
759 hide_user_symbols ? "yes" : "no"); 447 top.hide_user_symbols ? "yes" : "no");
760 fprintf(stdout, "\t[z] toggle sample zeroing. \t(%d)\n", zero ? 1 : 0); 448 fprintf(stdout, "\t[z] toggle sample zeroing. \t(%d)\n", top.zero ? 1 : 0);
761 fprintf(stdout, "\t[qQ] quit.\n"); 449 fprintf(stdout, "\t[qQ] quit.\n");
762} 450}
763 451
@@ -778,7 +466,7 @@ static int key_mapped(int c)
778 return 1; 466 return 1;
779 case 'E': 467 case 'E':
780 case 'w': 468 case 'w':
781 return nr_counters > 1 ? 1 : 0; 469 return top.evlist->nr_entries > 1 ? 1 : 0;
782 default: 470 default:
783 break; 471 break;
784 } 472 }
@@ -813,43 +501,50 @@ static void handle_keypress(struct perf_session *session, int c)
813 501
814 switch (c) { 502 switch (c) {
815 case 'd': 503 case 'd':
816 prompt_integer(&delay_secs, "Enter display delay"); 504 prompt_integer(&top.delay_secs, "Enter display delay");
817 if (delay_secs < 1) 505 if (top.delay_secs < 1)
818 delay_secs = 1; 506 top.delay_secs = 1;
819 break; 507 break;
820 case 'e': 508 case 'e':
821 prompt_integer(&print_entries, "Enter display entries (lines)"); 509 prompt_integer(&top.print_entries, "Enter display entries (lines)");
822 if (print_entries == 0) { 510 if (top.print_entries == 0) {
823 sig_winch_handler(SIGWINCH); 511 sig_winch_handler(SIGWINCH);
824 signal(SIGWINCH, sig_winch_handler); 512 signal(SIGWINCH, sig_winch_handler);
825 } else 513 } else
826 signal(SIGWINCH, SIG_DFL); 514 signal(SIGWINCH, SIG_DFL);
827 break; 515 break;
828 case 'E': 516 case 'E':
829 if (nr_counters > 1) { 517 if (top.evlist->nr_entries > 1) {
830 int i; 518 /* Select 0 as the default event: */
519 int counter = 0;
831 520
832 fprintf(stderr, "\nAvailable events:"); 521 fprintf(stderr, "\nAvailable events:");
833 for (i = 0; i < nr_counters; i++)
834 fprintf(stderr, "\n\t%d %s", i, event_name(i));
835 522
836 prompt_integer(&sym_counter, "Enter details event counter"); 523 list_for_each_entry(top.sym_evsel, &top.evlist->entries, node)
524 fprintf(stderr, "\n\t%d %s", top.sym_evsel->idx, event_name(top.sym_evsel));
525
526 prompt_integer(&counter, "Enter details event counter");
837 527
838 if (sym_counter >= nr_counters) { 528 if (counter >= top.evlist->nr_entries) {
839 fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(0)); 529 top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
840 sym_counter = 0; 530 fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(top.sym_evsel));
841 sleep(1); 531 sleep(1);
532 break;
842 } 533 }
843 } else sym_counter = 0; 534 list_for_each_entry(top.sym_evsel, &top.evlist->entries, node)
535 if (top.sym_evsel->idx == counter)
536 break;
537 } else
538 top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
844 break; 539 break;
845 case 'f': 540 case 'f':
846 prompt_integer(&count_filter, "Enter display event count filter"); 541 prompt_integer(&top.count_filter, "Enter display event count filter");
847 break; 542 break;
848 case 'F': 543 case 'F':
849 prompt_percent(&sym_pcnt_filter, "Enter details display event filter (percent)"); 544 prompt_percent(&sym_pcnt_filter, "Enter details display event filter (percent)");
850 break; 545 break;
851 case 'K': 546 case 'K':
852 hide_kernel_symbols = !hide_kernel_symbols; 547 top.hide_kernel_symbols = !top.hide_kernel_symbols;
853 break; 548 break;
854 case 'q': 549 case 'q':
855 case 'Q': 550 case 'Q':
@@ -858,34 +553,50 @@ static void handle_keypress(struct perf_session *session, int c)
858 perf_session__fprintf_dsos(session, stderr); 553 perf_session__fprintf_dsos(session, stderr);
859 exit(0); 554 exit(0);
860 case 's': 555 case 's':
861 prompt_symbol(&sym_filter_entry, "Enter details symbol"); 556 prompt_symbol(&top.sym_filter_entry, "Enter details symbol");
862 break; 557 break;
863 case 'S': 558 case 'S':
864 if (!sym_filter_entry) 559 if (!top.sym_filter_entry)
865 break; 560 break;
866 else { 561 else {
867 struct sym_entry *syme = sym_filter_entry; 562 struct sym_entry *syme = top.sym_filter_entry;
868 563
869 pthread_mutex_lock(&syme->src->lock); 564 top.sym_filter_entry = NULL;
870 sym_filter_entry = NULL;
871 __zero_source_counters(syme); 565 __zero_source_counters(syme);
872 pthread_mutex_unlock(&syme->src->lock);
873 } 566 }
874 break; 567 break;
875 case 'U': 568 case 'U':
876 hide_user_symbols = !hide_user_symbols; 569 top.hide_user_symbols = !top.hide_user_symbols;
877 break; 570 break;
878 case 'w': 571 case 'w':
879 display_weighted = ~display_weighted; 572 top.display_weighted = ~top.display_weighted;
880 break; 573 break;
881 case 'z': 574 case 'z':
882 zero = !zero; 575 top.zero = !top.zero;
883 break; 576 break;
884 default: 577 default:
885 break; 578 break;
886 } 579 }
887} 580}
888 581
582static void *display_thread_tui(void *arg __used)
583{
584 int err = 0;
585 pthread_mutex_lock(&top.active_symbols_lock);
586 while (list_empty(&top.active_symbols)) {
587 err = pthread_cond_wait(&top.active_symbols_cond,
588 &top.active_symbols_lock);
589 if (err)
590 break;
591 }
592 pthread_mutex_unlock(&top.active_symbols_lock);
593 if (!err)
594 perf_top__tui_browser(&top);
595 exit_browser(0);
596 exit(0);
597 return NULL;
598}
599
889static void *display_thread(void *arg __used) 600static void *display_thread(void *arg __used)
890{ 601{
891 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 602 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
@@ -900,13 +611,13 @@ static void *display_thread(void *arg __used)
900 tc.c_cc[VTIME] = 0; 611 tc.c_cc[VTIME] = 0;
901 612
902repeat: 613repeat:
903 delay_msecs = delay_secs * 1000; 614 delay_msecs = top.delay_secs * 1000;
904 tcsetattr(0, TCSANOW, &tc); 615 tcsetattr(0, TCSANOW, &tc);
905 /* trash return*/ 616 /* trash return*/
906 getc(stdin); 617 getc(stdin);
907 618
908 do { 619 do {
909 print_sym_table(); 620 print_sym_table(session);
910 } while (!poll(&stdin_poll, 1, delay_msecs) == 1); 621 } while (!poll(&stdin_poll, 1, delay_msecs) == 1);
911 622
912 c = getc(stdin); 623 c = getc(stdin);
@@ -921,6 +632,7 @@ repeat:
921/* Tag samples to be skipped. */ 632/* Tag samples to be skipped. */
922static const char *skip_symbols[] = { 633static const char *skip_symbols[] = {
923 "default_idle", 634 "default_idle",
635 "native_safe_halt",
924 "cpu_idle", 636 "cpu_idle",
925 "enter_idle", 637 "enter_idle",
926 "exit_idle", 638 "exit_idle",
@@ -956,9 +668,9 @@ static int symbol_filter(struct map *map, struct symbol *sym)
956 668
957 syme = symbol__priv(sym); 669 syme = symbol__priv(sym);
958 syme->map = map; 670 syme->map = map;
959 syme->src = NULL; 671 symbol__annotate_init(map, sym);
960 672
961 if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) { 673 if (!top.sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) {
962 /* schedule initial sym_filter_entry setup */ 674 /* schedule initial sym_filter_entry setup */
963 sym_filter_entry_sched = syme; 675 sym_filter_entry_sched = syme;
964 sym_filter = NULL; 676 sym_filter = NULL;
@@ -966,48 +678,45 @@ static int symbol_filter(struct map *map, struct symbol *sym)
966 678
967 for (i = 0; skip_symbols[i]; i++) { 679 for (i = 0; skip_symbols[i]; i++) {
968 if (!strcmp(skip_symbols[i], name)) { 680 if (!strcmp(skip_symbols[i], name)) {
969 syme->skip = 1; 681 sym->ignore = true;
970 break; 682 break;
971 } 683 }
972 } 684 }
973 685
974 if (!syme->skip)
975 syme->name_len = strlen(sym->name);
976
977 return 0; 686 return 0;
978} 687}
979 688
980static void event__process_sample(const event_t *self, 689static void perf_event__process_sample(const union perf_event *event,
981 struct perf_session *session, int counter) 690 struct perf_sample *sample,
691 struct perf_session *session)
982{ 692{
983 u64 ip = self->ip.ip; 693 u64 ip = event->ip.ip;
984 struct sym_entry *syme; 694 struct sym_entry *syme;
985 struct addr_location al; 695 struct addr_location al;
986 struct sample_data data;
987 struct machine *machine; 696 struct machine *machine;
988 u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 697 u8 origin = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
989 698
990 ++samples; 699 ++top.samples;
991 700
992 switch (origin) { 701 switch (origin) {
993 case PERF_RECORD_MISC_USER: 702 case PERF_RECORD_MISC_USER:
994 ++us_samples; 703 ++top.us_samples;
995 if (hide_user_symbols) 704 if (top.hide_user_symbols)
996 return; 705 return;
997 machine = perf_session__find_host_machine(session); 706 machine = perf_session__find_host_machine(session);
998 break; 707 break;
999 case PERF_RECORD_MISC_KERNEL: 708 case PERF_RECORD_MISC_KERNEL:
1000 ++kernel_samples; 709 ++top.kernel_samples;
1001 if (hide_kernel_symbols) 710 if (top.hide_kernel_symbols)
1002 return; 711 return;
1003 machine = perf_session__find_host_machine(session); 712 machine = perf_session__find_host_machine(session);
1004 break; 713 break;
1005 case PERF_RECORD_MISC_GUEST_KERNEL: 714 case PERF_RECORD_MISC_GUEST_KERNEL:
1006 ++guest_kernel_samples; 715 ++top.guest_kernel_samples;
1007 machine = perf_session__find_machine(session, self->ip.pid); 716 machine = perf_session__find_machine(session, event->ip.pid);
1008 break; 717 break;
1009 case PERF_RECORD_MISC_GUEST_USER: 718 case PERF_RECORD_MISC_GUEST_USER:
1010 ++guest_us_samples; 719 ++top.guest_us_samples;
1011 /* 720 /*
1012 * TODO: we don't process guest user from host side 721 * TODO: we don't process guest user from host side
1013 * except simple counting. 722 * except simple counting.
@@ -1019,19 +728,34 @@ static void event__process_sample(const event_t *self,
1019 728
1020 if (!machine && perf_guest) { 729 if (!machine && perf_guest) {
1021 pr_err("Can't find guest [%d]'s kernel information\n", 730 pr_err("Can't find guest [%d]'s kernel information\n",
1022 self->ip.pid); 731 event->ip.pid);
1023 return; 732 return;
1024 } 733 }
1025 734
1026 if (self->header.misc & PERF_RECORD_MISC_EXACT_IP) 735 if (event->header.misc & PERF_RECORD_MISC_EXACT_IP)
1027 exact_samples++; 736 top.exact_samples++;
1028 737
1029 if (event__preprocess_sample(self, session, &al, &data, 738 if (perf_event__preprocess_sample(event, session, &al, sample,
1030 symbol_filter) < 0 || 739 symbol_filter) < 0 ||
1031 al.filtered) 740 al.filtered)
1032 return; 741 return;
1033 742
743 if (!kptr_restrict_warned &&
744 symbol_conf.kptr_restrict &&
745 al.cpumode == PERF_RECORD_MISC_KERNEL) {
746 ui__warning(
747"Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n"
748"Check /proc/sys/kernel/kptr_restrict.\n\n"
749"Kernel%s samples will not be resolved.\n",
750 !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ?
751 " modules" : "");
752 if (use_browser <= 0)
753 sleep(5);
754 kptr_restrict_warned = true;
755 }
756
1034 if (al.sym == NULL) { 757 if (al.sym == NULL) {
758 const char *msg = "Kernel samples will not be resolved.\n";
1035 /* 759 /*
1036 * As we do lazy loading of symtabs we only will know if the 760 * As we do lazy loading of symtabs we only will know if the
1037 * specified vmlinux file is invalid when we actually have a 761 * specified vmlinux file is invalid when we actually have a
@@ -1043,11 +767,20 @@ static void event__process_sample(const event_t *self,
1043 * --hide-kernel-symbols, even if the user specifies an 767 * --hide-kernel-symbols, even if the user specifies an
1044 * invalid --vmlinux ;-) 768 * invalid --vmlinux ;-)
1045 */ 769 */
1046 if (al.map == machine->vmlinux_maps[MAP__FUNCTION] && 770 if (!kptr_restrict_warned && !vmlinux_warned &&
771 al.map == machine->vmlinux_maps[MAP__FUNCTION] &&
1047 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { 772 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
1048 pr_err("The %s file can't be used\n", 773 if (symbol_conf.vmlinux_name) {
1049 symbol_conf.vmlinux_name); 774 ui__warning("The %s file can't be used.\n%s",
1050 exit(1); 775 symbol_conf.vmlinux_name, msg);
776 } else {
777 ui__warning("A vmlinux file was not found.\n%s",
778 msg);
779 }
780
781 if (use_browser <= 0)
782 sleep(5);
783 vmlinux_warned = true;
1051 } 784 }
1052 785
1053 return; 786 return;
@@ -1055,13 +788,13 @@ static void event__process_sample(const event_t *self,
1055 788
1056 /* let's see, whether we need to install initial sym_filter_entry */ 789 /* let's see, whether we need to install initial sym_filter_entry */
1057 if (sym_filter_entry_sched) { 790 if (sym_filter_entry_sched) {
1058 sym_filter_entry = sym_filter_entry_sched; 791 top.sym_filter_entry = sym_filter_entry_sched;
1059 sym_filter_entry_sched = NULL; 792 sym_filter_entry_sched = NULL;
1060 if (parse_source(sym_filter_entry) < 0) { 793 if (parse_source(top.sym_filter_entry) < 0) {
1061 struct symbol *sym = sym_entry__symbol(sym_filter_entry); 794 struct symbol *sym = sym_entry__symbol(top.sym_filter_entry);
1062 795
1063 pr_err("Can't annotate %s", sym->name); 796 pr_err("Can't annotate %s", sym->name);
1064 if (sym_filter_entry->map->dso->origin == DSO__ORIG_KERNEL) { 797 if (top.sym_filter_entry->map->dso->symtab_type == SYMTAB__KALLSYMS) {
1065 pr_err(": No vmlinux file was found in the path:\n"); 798 pr_err(": No vmlinux file was found in the path:\n");
1066 machine__fprintf_vmlinux_path(machine, stderr); 799 machine__fprintf_vmlinux_path(machine, stderr);
1067 } else 800 } else
@@ -1071,226 +804,158 @@ static void event__process_sample(const event_t *self,
1071 } 804 }
1072 805
1073 syme = symbol__priv(al.sym); 806 syme = symbol__priv(al.sym);
1074 if (!syme->skip) { 807 if (!al.sym->ignore) {
1075 syme->count[counter]++; 808 struct perf_evsel *evsel;
1076 syme->origin = origin; 809
1077 record_precise_ip(syme, counter, ip); 810 evsel = perf_evlist__id2evsel(top.evlist, sample->id);
1078 pthread_mutex_lock(&active_symbols_lock); 811 assert(evsel != NULL);
1079 if (list_empty(&syme->node) || !syme->node.next) 812 syme->count[evsel->idx]++;
813 record_precise_ip(syme, evsel->idx, ip);
814 pthread_mutex_lock(&top.active_symbols_lock);
815 if (list_empty(&syme->node) || !syme->node.next) {
816 static bool first = true;
1080 __list_insert_active_sym(syme); 817 __list_insert_active_sym(syme);
1081 pthread_mutex_unlock(&active_symbols_lock); 818 if (first) {
819 pthread_cond_broadcast(&top.active_symbols_cond);
820 first = false;
821 }
822 }
823 pthread_mutex_unlock(&top.active_symbols_lock);
1082 } 824 }
1083} 825}
1084 826
1085struct mmap_data { 827static void perf_session__mmap_read_idx(struct perf_session *self, int idx)
1086 int counter;
1087 void *base;
1088 int mask;
1089 unsigned int prev;
1090};
1091
1092static unsigned int mmap_read_head(struct mmap_data *md)
1093{
1094 struct perf_event_mmap_page *pc = md->base;
1095 int head;
1096
1097 head = pc->data_head;
1098 rmb();
1099
1100 return head;
1101}
1102
1103static void perf_session__mmap_read_counter(struct perf_session *self,
1104 struct mmap_data *md)
1105{ 828{
1106 unsigned int head = mmap_read_head(md); 829 struct perf_sample sample;
1107 unsigned int old = md->prev; 830 union perf_event *event;
1108 unsigned char *data = md->base + page_size; 831 int ret;
1109 int diff;
1110
1111 /*
1112 * If we're further behind than half the buffer, there's a chance
1113 * the writer will bite our tail and mess up the samples under us.
1114 *
1115 * If we somehow ended up ahead of the head, we got messed up.
1116 *
1117 * In either case, truncate and restart at head.
1118 */
1119 diff = head - old;
1120 if (diff > md->mask / 2 || diff < 0) {
1121 fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
1122
1123 /*
1124 * head points to a known good entry, start there.
1125 */
1126 old = head;
1127 }
1128
1129 for (; old != head;) {
1130 event_t *event = (event_t *)&data[old & md->mask];
1131
1132 event_t event_copy;
1133
1134 size_t size = event->header.size;
1135 832
1136 /* 833 while ((event = perf_evlist__mmap_read(top.evlist, idx)) != NULL) {
1137 * Event straddles the mmap boundary -- header should always 834 ret = perf_session__parse_sample(self, event, &sample);
1138 * be inside due to u64 alignment of output. 835 if (ret) {
1139 */ 836 pr_err("Can't parse sample, err = %d\n", ret);
1140 if ((old & md->mask) + size != ((old + size) & md->mask)) { 837 continue;
1141 unsigned int offset = old;
1142 unsigned int len = min(sizeof(*event), size), cpy;
1143 void *dst = &event_copy;
1144
1145 do {
1146 cpy = min(md->mask + 1 - (offset & md->mask), len);
1147 memcpy(dst, &data[offset & md->mask], cpy);
1148 offset += cpy;
1149 dst += cpy;
1150 len -= cpy;
1151 } while (len);
1152
1153 event = &event_copy;
1154 } 838 }
1155 839
1156 if (event->header.type == PERF_RECORD_SAMPLE) 840 if (event->header.type == PERF_RECORD_SAMPLE)
1157 event__process_sample(event, self, md->counter); 841 perf_event__process_sample(event, &sample, self);
1158 else 842 else
1159 event__process(event, self); 843 perf_event__process(event, &sample, self);
1160 old += size;
1161 } 844 }
1162
1163 md->prev = old;
1164} 845}
1165 846
1166static struct pollfd *event_array;
1167static struct mmap_data *mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
1168
1169static void perf_session__mmap_read(struct perf_session *self) 847static void perf_session__mmap_read(struct perf_session *self)
1170{ 848{
1171 int i, counter, thread_index; 849 int i;
1172
1173 for (i = 0; i < nr_cpus; i++) {
1174 for (counter = 0; counter < nr_counters; counter++)
1175 for (thread_index = 0;
1176 thread_index < thread_num;
1177 thread_index++) {
1178 perf_session__mmap_read_counter(self,
1179 &mmap_array[i][counter][thread_index]);
1180 }
1181 }
1182}
1183 850
1184int nr_poll; 851 for (i = 0; i < top.evlist->nr_mmaps; i++)
1185int group_fd; 852 perf_session__mmap_read_idx(self, i);
853}
1186 854
1187static void start_counter(int i, int counter) 855static void start_counters(struct perf_evlist *evlist)
1188{ 856{
1189 struct perf_event_attr *attr; 857 struct perf_evsel *counter;
1190 int cpu;
1191 int thread_index;
1192
1193 cpu = profile_cpu;
1194 if (target_tid == -1 && profile_cpu == -1)
1195 cpu = cpumap[i];
1196 858
1197 attr = attrs + counter; 859 list_for_each_entry(counter, &evlist->entries, node) {
860 struct perf_event_attr *attr = &counter->attr;
1198 861
1199 attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; 862 attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
1200 863
1201 if (freq) { 864 if (top.freq) {
1202 attr->sample_type |= PERF_SAMPLE_PERIOD; 865 attr->sample_type |= PERF_SAMPLE_PERIOD;
1203 attr->freq = 1; 866 attr->freq = 1;
1204 attr->sample_freq = freq; 867 attr->sample_freq = top.freq;
1205 } 868 }
1206 869
1207 attr->inherit = (cpu < 0) && inherit; 870 if (evlist->nr_entries > 1) {
1208 attr->mmap = 1; 871 attr->sample_type |= PERF_SAMPLE_ID;
872 attr->read_format |= PERF_FORMAT_ID;
873 }
1209 874
1210 for (thread_index = 0; thread_index < thread_num; thread_index++) { 875 attr->mmap = 1;
876 attr->inherit = inherit;
1211try_again: 877try_again:
1212 fd[i][counter][thread_index] = sys_perf_event_open(attr, 878 if (perf_evsel__open(counter, top.evlist->cpus,
1213 all_tids[thread_index], cpu, group_fd, 0); 879 top.evlist->threads, group) < 0) {
1214
1215 if (fd[i][counter][thread_index] < 0) {
1216 int err = errno; 880 int err = errno;
1217 881
1218 if (err == EPERM || err == EACCES) 882 if (err == EPERM || err == EACCES) {
1219 die("No permission - are you root?\n"); 883 ui__warning_paranoid();
884 goto out_err;
885 }
1220 /* 886 /*
1221 * If it's cycles then fall back to hrtimer 887 * If it's cycles then fall back to hrtimer
1222 * based cpu-clock-tick sw counter, which 888 * based cpu-clock-tick sw counter, which
1223 * is always available even if no PMU support: 889 * is always available even if no PMU support:
1224 */ 890 */
1225 if (attr->type == PERF_TYPE_HARDWARE 891 if (attr->type == PERF_TYPE_HARDWARE &&
1226 && attr->config == PERF_COUNT_HW_CPU_CYCLES) { 892 attr->config == PERF_COUNT_HW_CPU_CYCLES) {
1227
1228 if (verbose) 893 if (verbose)
1229 warning(" ... trying to fall back to cpu-clock-ticks\n"); 894 ui__warning("Cycles event not supported,\n"
895 "trying to fall back to cpu-clock-ticks\n");
1230 896
1231 attr->type = PERF_TYPE_SOFTWARE; 897 attr->type = PERF_TYPE_SOFTWARE;
1232 attr->config = PERF_COUNT_SW_CPU_CLOCK; 898 attr->config = PERF_COUNT_SW_CPU_CLOCK;
1233 goto try_again; 899 goto try_again;
1234 } 900 }
1235 printf("\n"); 901
1236 error("perfcounter syscall returned with %d (%s)\n", 902 if (err == ENOENT) {
1237 fd[i][counter][thread_index], strerror(err)); 903 ui__warning("The %s event is not supported.\n",
1238 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 904 event_name(counter));
1239 exit(-1); 905 goto out_err;
906 }
907
908 ui__warning("The sys_perf_event_open() syscall "
909 "returned with %d (%s). /bin/dmesg "
910 "may provide additional information.\n"
911 "No CONFIG_PERF_EVENTS=y kernel support "
912 "configured?\n", err, strerror(err));
913 goto out_err;
1240 } 914 }
1241 assert(fd[i][counter][thread_index] >= 0); 915 }
1242 fcntl(fd[i][counter][thread_index], F_SETFL, O_NONBLOCK);
1243 916
1244 /* 917 if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) {
1245 * First counter acts as the group leader: 918 ui__warning("Failed to mmap with %d (%s)\n",
1246 */ 919 errno, strerror(errno));
1247 if (group && group_fd == -1) 920 goto out_err;
1248 group_fd = fd[i][counter][thread_index];
1249
1250 event_array[nr_poll].fd = fd[i][counter][thread_index];
1251 event_array[nr_poll].events = POLLIN;
1252 nr_poll++;
1253
1254 mmap_array[i][counter][thread_index].counter = counter;
1255 mmap_array[i][counter][thread_index].prev = 0;
1256 mmap_array[i][counter][thread_index].mask = mmap_pages*page_size - 1;
1257 mmap_array[i][counter][thread_index].base = mmap(NULL, (mmap_pages+1)*page_size,
1258 PROT_READ, MAP_SHARED, fd[i][counter][thread_index], 0);
1259 if (mmap_array[i][counter][thread_index].base == MAP_FAILED)
1260 die("failed to mmap with %d (%s)\n", errno, strerror(errno));
1261 } 921 }
922
923 return;
924
925out_err:
926 exit_browser(0);
927 exit(0);
1262} 928}
1263 929
1264static int __cmd_top(void) 930static int __cmd_top(void)
1265{ 931{
1266 pthread_t thread; 932 pthread_t thread;
1267 int i, counter; 933 int ret __used;
1268 int ret;
1269 /* 934 /*
1270 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this 935 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
1271 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. 936 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
1272 */ 937 */
1273 struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false); 938 struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
1274 if (session == NULL) 939 if (session == NULL)
1275 return -ENOMEM; 940 return -ENOMEM;
1276 941
1277 if (target_tid != -1) 942 if (top.target_tid != -1)
1278 event__synthesize_thread(target_tid, event__process, session); 943 perf_event__synthesize_thread_map(top.evlist->threads,
944 perf_event__process, session);
1279 else 945 else
1280 event__synthesize_threads(event__process, session); 946 perf_event__synthesize_threads(perf_event__process, session);
1281 947
1282 for (i = 0; i < nr_cpus; i++) { 948 start_counters(top.evlist);
1283 group_fd = -1; 949 session->evlist = top.evlist;
1284 for (counter = 0; counter < nr_counters; counter++) 950 perf_session__update_sample_type(session);
1285 start_counter(i, counter);
1286 }
1287 951
1288 /* Wait for a minimal set of events before starting the snapshot */ 952 /* Wait for a minimal set of events before starting the snapshot */
1289 poll(&event_array[0], nr_poll, 100); 953 poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
1290 954
1291 perf_session__mmap_read(session); 955 perf_session__mmap_read(session);
1292 956
1293 if (pthread_create(&thread, NULL, display_thread, session)) { 957 if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui :
958 display_thread), session)) {
1294 printf("Could not create display thread.\n"); 959 printf("Could not create display thread.\n");
1295 exit(-1); 960 exit(-1);
1296 } 961 }
@@ -1306,12 +971,12 @@ static int __cmd_top(void)
1306 } 971 }
1307 972
1308 while (1) { 973 while (1) {
1309 int hits = samples; 974 u64 hits = top.samples;
1310 975
1311 perf_session__mmap_read(session); 976 perf_session__mmap_read(session);
1312 977
1313 if (hits == samples) 978 if (hits == top.samples)
1314 ret = poll(event_array, nr_poll, 100); 979 ret = poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
1315 } 980 }
1316 981
1317 return 0; 982 return 0;
@@ -1323,31 +988,31 @@ static const char * const top_usage[] = {
1323}; 988};
1324 989
1325static const struct option options[] = { 990static const struct option options[] = {
1326 OPT_CALLBACK('e', "event", NULL, "event", 991 OPT_CALLBACK('e', "event", &top.evlist, "event",
1327 "event selector. use 'perf list' to list available events", 992 "event selector. use 'perf list' to list available events",
1328 parse_events), 993 parse_events),
1329 OPT_INTEGER('c', "count", &default_interval, 994 OPT_INTEGER('c', "count", &default_interval,
1330 "event period to sample"), 995 "event period to sample"),
1331 OPT_INTEGER('p', "pid", &target_pid, 996 OPT_INTEGER('p', "pid", &top.target_pid,
1332 "profile events on existing process id"), 997 "profile events on existing process id"),
1333 OPT_INTEGER('t', "tid", &target_tid, 998 OPT_INTEGER('t', "tid", &top.target_tid,
1334 "profile events on existing thread id"), 999 "profile events on existing thread id"),
1335 OPT_BOOLEAN('a', "all-cpus", &system_wide, 1000 OPT_BOOLEAN('a', "all-cpus", &system_wide,
1336 "system-wide collection from all CPUs"), 1001 "system-wide collection from all CPUs"),
1337 OPT_STRING('C', "cpu", &cpu_list, "cpu", 1002 OPT_STRING('C', "cpu", &top.cpu_list, "cpu",
1338 "list of cpus to monitor"), 1003 "list of cpus to monitor"),
1339 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 1004 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
1340 "file", "vmlinux pathname"), 1005 "file", "vmlinux pathname"),
1341 OPT_BOOLEAN('K', "hide_kernel_symbols", &hide_kernel_symbols, 1006 OPT_BOOLEAN('K', "hide_kernel_symbols", &top.hide_kernel_symbols,
1342 "hide kernel symbols"), 1007 "hide kernel symbols"),
1343 OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"), 1008 OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"),
1344 OPT_INTEGER('r', "realtime", &realtime_prio, 1009 OPT_INTEGER('r', "realtime", &realtime_prio,
1345 "collect data with this RT SCHED_FIFO priority"), 1010 "collect data with this RT SCHED_FIFO priority"),
1346 OPT_INTEGER('d', "delay", &delay_secs, 1011 OPT_INTEGER('d', "delay", &top.delay_secs,
1347 "number of seconds to delay between refreshes"), 1012 "number of seconds to delay between refreshes"),
1348 OPT_BOOLEAN('D', "dump-symtab", &dump_symtab, 1013 OPT_BOOLEAN('D', "dump-symtab", &dump_symtab,
1349 "dump the symbol table used for profiling"), 1014 "dump the symbol table used for profiling"),
1350 OPT_INTEGER('f', "count-filter", &count_filter, 1015 OPT_INTEGER('f', "count-filter", &top.count_filter,
1351 "only display functions with more events than this"), 1016 "only display functions with more events than this"),
1352 OPT_BOOLEAN('g', "group", &group, 1017 OPT_BOOLEAN('g', "group", &group,
1353 "put the counters into a counter group"), 1018 "put the counters into a counter group"),
@@ -1355,14 +1020,16 @@ static const struct option options[] = {
1355 "child tasks inherit counters"), 1020 "child tasks inherit counters"),
1356 OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name", 1021 OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name",
1357 "symbol to annotate"), 1022 "symbol to annotate"),
1358 OPT_BOOLEAN('z', "zero", &zero, 1023 OPT_BOOLEAN('z', "zero", &top.zero,
1359 "zero history across updates"), 1024 "zero history across updates"),
1360 OPT_INTEGER('F', "freq", &freq, 1025 OPT_INTEGER('F', "freq", &top.freq,
1361 "profile at this frequency"), 1026 "profile at this frequency"),
1362 OPT_INTEGER('E', "entries", &print_entries, 1027 OPT_INTEGER('E', "entries", &top.print_entries,
1363 "display this many functions"), 1028 "display this many functions"),
1364 OPT_BOOLEAN('U', "hide_user_symbols", &hide_user_symbols, 1029 OPT_BOOLEAN('U', "hide_user_symbols", &top.hide_user_symbols,
1365 "hide user symbols"), 1030 "hide user symbols"),
1031 OPT_BOOLEAN(0, "tui", &use_tui, "Use the TUI interface"),
1032 OPT_BOOLEAN(0, "stdio", &use_stdio, "Use the stdio interface"),
1366 OPT_INCR('v', "verbose", &verbose, 1033 OPT_INCR('v', "verbose", &verbose,
1367 "be more verbose (show counter open errors, etc)"), 1034 "be more verbose (show counter open errors, etc)"),
1368 OPT_END() 1035 OPT_END()
@@ -1370,8 +1037,12 @@ static const struct option options[] = {
1370 1037
1371int cmd_top(int argc, const char **argv, const char *prefix __used) 1038int cmd_top(int argc, const char **argv, const char *prefix __used)
1372{ 1039{
1373 int counter; 1040 struct perf_evsel *pos;
1374 int i,j; 1041 int status = -ENOMEM;
1042
1043 top.evlist = perf_evlist__new(NULL, NULL);
1044 if (top.evlist == NULL)
1045 return -ENOMEM;
1375 1046
1376 page_size = sysconf(_SC_PAGE_SIZE); 1047 page_size = sysconf(_SC_PAGE_SIZE);
1377 1048
@@ -1379,92 +1050,90 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1379 if (argc) 1050 if (argc)
1380 usage_with_options(top_usage, options); 1051 usage_with_options(top_usage, options);
1381 1052
1382 if (target_pid != -1) { 1053 /*
1383 target_tid = target_pid; 1054 * XXX For now start disabled, only using TUI if explicitely asked for.
1384 thread_num = find_all_tid(target_pid, &all_tids); 1055 * Change that when handle_keys equivalent gets written, live annotation
1385 if (thread_num <= 0) { 1056 * done, etc.
1386 fprintf(stderr, "Can't find all threads of pid %d\n", 1057 */
1387 target_pid); 1058 use_browser = 0;
1388 usage_with_options(top_usage, options);
1389 }
1390 } else {
1391 all_tids=malloc(sizeof(pid_t));
1392 if (!all_tids)
1393 return -ENOMEM;
1394 1059
1395 all_tids[0] = target_tid; 1060 if (use_stdio)
1396 thread_num = 1; 1061 use_browser = 0;
1397 } 1062 else if (use_tui)
1063 use_browser = 1;
1398 1064
1399 for (i = 0; i < MAX_NR_CPUS; i++) { 1065 setup_browser(false);
1400 for (j = 0; j < MAX_COUNTERS; j++) {
1401 fd[i][j] = malloc(sizeof(int)*thread_num);
1402 mmap_array[i][j] = zalloc(
1403 sizeof(struct mmap_data)*thread_num);
1404 if (!fd[i][j] || !mmap_array[i][j])
1405 return -ENOMEM;
1406 }
1407 }
1408 event_array = malloc(
1409 sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num);
1410 if (!event_array)
1411 return -ENOMEM;
1412 1066
1413 /* CPU and PID are mutually exclusive */ 1067 /* CPU and PID are mutually exclusive */
1414 if (target_tid > 0 && cpu_list) { 1068 if (top.target_tid > 0 && top.cpu_list) {
1415 printf("WARNING: PID switch overriding CPU\n"); 1069 printf("WARNING: PID switch overriding CPU\n");
1416 sleep(1); 1070 sleep(1);
1417 cpu_list = NULL; 1071 top.cpu_list = NULL;
1418 } 1072 }
1419 1073
1420 if (!nr_counters) 1074 if (top.target_pid != -1)
1421 nr_counters = 1; 1075 top.target_tid = top.target_pid;
1422 1076
1423 symbol_conf.priv_size = (sizeof(struct sym_entry) + 1077 if (perf_evlist__create_maps(top.evlist, top.target_pid,
1424 (nr_counters + 1) * sizeof(unsigned long)); 1078 top.target_tid, top.cpu_list) < 0)
1079 usage_with_options(top_usage, options);
1425 1080
1426 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); 1081 if (!top.evlist->nr_entries &&
1427 if (symbol__init() < 0) 1082 perf_evlist__add_default(top.evlist) < 0) {
1428 return -1; 1083 pr_err("Not enough memory for event selector list\n");
1084 return -ENOMEM;
1085 }
1429 1086
1430 if (delay_secs < 1) 1087 if (top.delay_secs < 1)
1431 delay_secs = 1; 1088 top.delay_secs = 1;
1432 1089
1433 /* 1090 /*
1434 * User specified count overrides default frequency. 1091 * User specified count overrides default frequency.
1435 */ 1092 */
1436 if (default_interval) 1093 if (default_interval)
1437 freq = 0; 1094 top.freq = 0;
1438 else if (freq) { 1095 else if (top.freq) {
1439 default_interval = freq; 1096 default_interval = top.freq;
1440 } else { 1097 } else {
1441 fprintf(stderr, "frequency and count are zero, aborting\n"); 1098 fprintf(stderr, "frequency and count are zero, aborting\n");
1442 exit(EXIT_FAILURE); 1099 exit(EXIT_FAILURE);
1443 } 1100 }
1444 1101
1445 /* 1102 list_for_each_entry(pos, &top.evlist->entries, node) {
1446 * Fill in the ones not specifically initialized via -c: 1103 if (perf_evsel__alloc_fd(pos, top.evlist->cpus->nr,
1447 */ 1104 top.evlist->threads->nr) < 0)
1448 for (counter = 0; counter < nr_counters; counter++) { 1105 goto out_free_fd;
1449 if (attrs[counter].sample_period) 1106 /*
1107 * Fill in the ones not specifically initialized via -c:
1108 */
1109 if (pos->attr.sample_period)
1450 continue; 1110 continue;
1451 1111
1452 attrs[counter].sample_period = default_interval; 1112 pos->attr.sample_period = default_interval;
1453 } 1113 }
1454 1114
1455 if (target_tid != -1) 1115 if (perf_evlist__alloc_pollfd(top.evlist) < 0 ||
1456 nr_cpus = 1; 1116 perf_evlist__alloc_mmap(top.evlist) < 0)
1457 else 1117 goto out_free_fd;
1458 nr_cpus = read_cpu_map(cpu_list);
1459 1118
1460 if (nr_cpus < 1) 1119 top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
1461 usage_with_options(top_usage, options); 1120
1121 symbol_conf.priv_size = (sizeof(struct sym_entry) + sizeof(struct annotation) +
1122 (top.evlist->nr_entries + 1) * sizeof(unsigned long));
1123
1124 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
1125 if (symbol__init() < 0)
1126 return -1;
1462 1127
1463 get_term_dimensions(&winsize); 1128 get_term_dimensions(&winsize);
1464 if (print_entries == 0) { 1129 if (top.print_entries == 0) {
1465 update_print_entries(&winsize); 1130 update_print_entries(&winsize);
1466 signal(SIGWINCH, sig_winch_handler); 1131 signal(SIGWINCH, sig_winch_handler);
1467 } 1132 }
1468 1133
1469 return __cmd_top(); 1134 status = __cmd_top();
1135out_free_fd:
1136 perf_evlist__delete(top.evlist);
1137
1138 return status;
1470} 1139}