diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 3af95203208a..89b7f68a1799 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -76,6 +76,9 @@ static int delay_secs = 2; static int zero = 0; static int dump_symtab = 0; +static bool hide_kernel_symbols = false; +static bool hide_user_symbols = false; + /* * Source */ @@ -104,6 +107,7 @@ struct sym_entry { unsigned long snap_count; double weight; int skip; + u8 origin; struct map *map; struct source_line *source; struct source_line *lines; @@ -430,6 +434,13 @@ static void print_sym_table(void) list_for_each_entry_safe_from(syme, n, &active_symbols, node) { syme->snap_count = syme->count[snap]; if (syme->snap_count != 0) { + if ((hide_user_symbols && + syme->origin == PERF_RECORD_MISC_USER) || + (hide_kernel_symbols && + syme->origin == PERF_RECORD_MISC_KERNEL)) { + list_remove_active_sym(syme); + continue; + } syme->weight = sym_weight(syme); rb_insert_active_sym(&tmp, syme); sum_ksamples += syme->snap_count; @@ -637,6 +648,12 @@ static void print_mapped_keys(void) if (nr_counters > 1) fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0); + fprintf(stdout, + "\t[K] hide kernel_symbols symbols. \t(%s)\n", + hide_kernel_symbols ? "yes" : "no"); + fprintf(stdout, + "\t[U] hide user symbols. \t(%s)\n", + hide_user_symbols ? "yes" : "no"); fprintf(stdout, "\t[z] toggle sample zeroing. \t(%d)\n", zero ? 1 : 0); fprintf(stdout, "\t[qQ] quit.\n"); } @@ -650,6 +667,8 @@ static int key_mapped(int c) case 'z': case 'q': case 'Q': + case 'K': + case 'U': return 1; case 'E': case 'w': @@ -727,6 +746,9 @@ static void handle_keypress(int c) case 'F': prompt_percent(&sym_pcnt_filter, "Enter details display event filter (percent)"); break; + case 'K': + hide_kernel_symbols = !hide_kernel_symbols; + break; case 'q': case 'Q': printf("exiting.\n"); @@ -746,6 +768,9 @@ static void handle_keypress(int c) pthread_mutex_unlock(&syme->source_lock); } break; + case 'U': + hide_user_symbols = !hide_user_symbols; + break; case 'w': display_weighted = ~display_weighted; break; @@ -857,11 +882,16 @@ static void event__process_sample(const event_t *self, int counter) struct map *map; struct sym_entry *syme; struct symbol *sym; + u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - switch (self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK) { + switch (origin) { case PERF_RECORD_MISC_USER: { - struct thread *thread = threads__findnew(self->ip.pid); + struct thread *thread; + if (hide_user_symbols) + return; + + thread = threads__findnew(self->ip.pid); if (thread == NULL) return; @@ -885,6 +915,9 @@ static void event__process_sample(const event_t *self, int counter) return; /* Fall thru */ case PERF_RECORD_MISC_KERNEL: + if (hide_kernel_symbols) + return; + sym = kernel_maps__find_symbol(ip, &map); if (sym == NULL) return; @@ -897,6 +930,7 @@ static void event__process_sample(const event_t *self, int counter) if (!syme->skip) { syme->count[counter]++; + syme->origin = origin; record_precise_ip(syme, counter, ip); pthread_mutex_lock(&active_symbols_lock); if (list_empty(&syme->node) || !syme->node.next) @@ -1178,6 +1212,8 @@ static const struct option options[] = { OPT_INTEGER('C', "CPU", &profile_cpu, "CPU to profile on"), OPT_STRING('k', "vmlinux", &vmlinux_name, "file", "vmlinux pathname"), + OPT_BOOLEAN('K', "hide_kernel_symbols", &hide_kernel_symbols, + "hide kernel symbols"), OPT_INTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"), OPT_INTEGER('r', "realtime", &realtime_prio, @@ -1200,6 +1236,8 @@ static const struct option options[] = { "profile at this frequency"), OPT_INTEGER('E', "entries", &print_entries, "display this many functions"), + OPT_BOOLEAN('U', "hide_user_symbols", &hide_user_symbols, + "hide user symbols"), OPT_BOOLEAN('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"), OPT_END()