35 #include <linux/rbtree.h>
58 #include <sys/syscall.h>
59 #include <sys/ioctl.h>
61 #include <sys/prctl.h>
64 #include <sys/utsname.h>
68 #include <linux/types.h>
72 char *
s = getenv(
"LINES");
76 s = getenv(
"COLUMNS");
92 static void perf_top__update_print_entries(
struct perf_top *
top)
111 perf_top__update_print_entries(top);
121 if (!he || !he->
ms.sym)
131 pr_err(
"Can't annotate %s: No vmlinux file was found in the "
132 "path\n", sym->
name);
137 notes = symbol__annotation(sym);
139 pthread_mutex_lock(¬es->
lock);
143 pthread_mutex_lock(¬es->
lock);
146 pthread_mutex_unlock(¬es->
lock);
147 pr_err(
"Not enough memory for annotating '%s' symbol!\n",
159 pthread_mutex_unlock(¬es->
lock);
163 static void __zero_source_counters(
struct hist_entry *he)
169 static void ui__warn_map_erange(
struct map *map,
struct symbol *sym,
u64 ip)
172 int err = uname(&
uts);
182 "Not all samples will be on the annotation output.\n\n"
188 err ?
"[unknown]" :
uts.machine,
196 static void perf_top__record_precise_ip(
struct perf_top *top,
210 notes = symbol__annotation(sym);
212 if (pthread_mutex_trylock(¬es->
lock))
216 pthread_mutex_unlock(¬es->
lock);
217 pr_err(
"Not enough memory for annotating '%s' symbol!\n",
223 ip = he->
ms.map->map_ip(he->
ms.map, ip);
226 pthread_mutex_unlock(¬es->
lock);
228 if (err == -
ERANGE && !he->
ms.map->erange_warned)
229 ui__warn_map_erange(he->
ms.map, sym, ip);
232 static void perf_top__show_details(
struct perf_top *top)
243 notes = symbol__annotation(symbol);
245 pthread_mutex_lock(¬es->
lock);
260 printf(
"%d lines not displayed, maybe increase display entries [e]\n", more);
262 pthread_mutex_unlock(¬es->
lock);
265 static const char CONSOLE_CLEAR[] =
"[H[2J";
281 static void perf_top__print_sym_table(
struct perf_top *top)
285 const int win_width = top->
winsize.ws_col - 1;
296 if (top->
sym_evsel->hists.stats.nr_lost_warned !=
298 top->
sym_evsel->hists.stats.nr_lost_warned =
301 "WARNING: LOST %d chunks, Check IO/CPU overload",
302 top->
sym_evsel->hists.stats.nr_lost_warned);
307 perf_top__show_details(top);
320 top->
winsize.ws_row - 4 - printed, win_width, stdout);
323 static void prompt_integer(
int *
target,
const char *
msg)
329 fprintf(stdout,
"\n%s: ", msg);
330 if (getline(&buf, &dummy, stdin) < 0)
343 tmp = strtoul(buf,
NULL, 10);
349 static void prompt_percent(
int *target,
const char *msg)
353 prompt_integer(&tmp, msg);
354 if (tmp >= 0 && tmp <= 100)
358 static void perf_top__prompt_symbol(
struct perf_top *top,
const char *msg)
367 __zero_source_counters(syme);
371 fprintf(stdout,
"\n%s: ", msg);
372 if (getline(&buf, &dummy, stdin) < 0)
390 fprintf(stderr,
"Sorry, %s is not active.\n", buf);
393 perf_top__parse_source(top, found);
399 static void perf_top__print_mapped_keys(
struct perf_top *top)
408 fprintf(stdout,
"\nMapped keys:\n");
412 if (top->
evlist->nr_entries > 1)
418 fprintf(stdout,
"\t[s] annotate symbol. \t(%s)\n", name?:
"NULL");
419 fprintf(stdout,
"\t[S] stop annotation.\n");
422 "\t[K] hide kernel_symbols symbols. \t(%s)\n",
425 "\t[U] hide user symbols. \t(%s)\n",
427 fprintf(stdout,
"\t[z] toggle sample zeroing. \t(%d)\n", top->
zero ? 1 : 0);
428 fprintf(stdout,
"\t[qQ] quit.\n");
431 static int perf_top__key_mapped(
struct perf_top *top,
int c)
447 return top->
evlist->nr_entries > 1 ? 1 : 0;
455 static void perf_top__handle_keypress(
struct perf_top *top,
int c)
457 if (!perf_top__key_mapped(top, c)) {
461 perf_top__print_mapped_keys(top);
462 fprintf(stdout,
"\nEnter selection, or unmapped key to continue: ");
472 poll(&stdin_poll, 1, -1);
476 if (!perf_top__key_mapped(top, c))
482 prompt_integer(&top->
delay_secs,
"Enter display delay");
487 prompt_integer(&top->
print_entries,
"Enter display entries (lines)");
490 .sa_sigaction = perf_top__sig_winch,
501 if (top->
evlist->nr_entries > 1) {
505 fprintf(stderr,
"\nAvailable events:");
510 prompt_integer(&counter, "Enter details
event counter");
512 if (counter >= top->evlist->nr_entries) {
519 if (top->sym_evsel->idx == counter)
522 top->sym_evsel = perf_evlist__first(top->evlist);
528 prompt_percent(&top->sym_pcnt_filter,
532 top->hide_kernel_symbols = !top->hide_kernel_symbols;
537 if (top->dump_symtab)
541 perf_top__prompt_symbol(top, "Enter details symbol");
544 if (!top->sym_filter_entry)
547 struct hist_entry *syme = top->sym_filter_entry;
549 top->sym_filter_entry =
NULL;
550 __zero_source_counters(syme);
564 static void perf_top__sort_new_samples(
void *arg)
579 static void *display_thread_tui(
void *arg)
583 const char *help =
"For a higher level overview, try: perf top --sort comm,dso";
585 perf_top__sort_new_samples(top);
593 pos->
hists.uid_filter_str = top->target.uid_str;
596 perf_top__sort_new_samples,
604 static
void *display_thread(
void *arg)
625 perf_top__print_sym_table(top);
630 switch (
poll(&stdin_poll, 1, delay_msecs)) {
645 perf_top__handle_keypress(top, c);
652 static const char *skip_symbols[] = {
660 "mwait_idle_with_hints",
662 "ppc64_runlatch_off",
663 "pseries_dedicated_idle_sleep",
667 static int symbol_filter(
struct map *map __maybe_unused,
struct symbol *sym)
669 const char *name = sym->
name;
679 if (!
strcmp(name,
"_text") ||
680 !
strcmp(name,
"_etext") ||
681 !
strcmp(name,
"_sinittext") ||
682 !
strncmp(
"init_module", name, 11) ||
683 !
strncmp(
"cleanup_module", name, 14) ||
684 strstr(name,
"_text_start") ||
685 strstr(name,
"_text_end"))
688 for (i = 0; skip_symbols[
i]; i++) {
689 if (!
strcmp(skip_symbols[i], name)) {
698 static void perf_event__process_sample(
struct perf_tool *
tool,
706 u64 ip =
event->ip.ip;
716 if (!intlist__has_entry(seen, event->
ip.pid)) {
717 pr_err(
"Can't find guest [%d]'s kernel information\n",
725 pr_err(
"%u unprocessable samples recorded.",
726 top->
session->hists.stats.nr_unprocessable_samples++);
734 symbol_filter) < 0 ||
742 "Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n"
743 "Check /proc/sys/kernel/kptr_restrict.\n\n"
744 "Kernel%s samples will not be resolved.\n",
752 if (al.
sym == NULL) {
753 const char *msg =
"Kernel samples will not be resolved.\n";
782 if (al.
sym == NULL || !al.
sym->ignore) {
795 he = perf_evsel__add_hist_entry(evsel, &al, sample);
797 pr_err(
"Problem incrementing symbol period, skipping event\n");
809 perf_top__record_precise_ip(top, he, evsel->
idx, ip);
815 static void perf_top__mmap_read_idx(
struct perf_top *top,
int idx)
828 pr_err(
"Can't parse sample, err = %d\n", ret);
845 machine = perf_session__find_host_machine(session);
851 machine = perf_session__find_host_machine(session);
855 machine = perf_session__find_machine(session, event->
ip.pid);
870 perf_event__process_sample(&top->
tool, event, evsel,
876 ++session->
hists.stats.nr_unknown_events;
880 static void perf_top__mmap_read(
struct perf_top *top)
884 for (i = 0; i < top->
evlist->nr_mmaps; i++)
885 perf_top__mmap_read_idx(top, i);
888 static void perf_top__start_counters(
struct perf_top *top)
912 if (perf_target__has_cpu(&top->
target))
921 fallback_missing_features:
928 top->
evlist->threads) < 0) {
934 }
else if (err ==
EINVAL) {
937 pr_debug(
"Old kernel, cannot exclude "
938 "guest or host samples.\n");
940 goto fallback_missing_features;
946 goto retry_sample_id;
960 "trying to fall back to cpu-clock-ticks\n");
972 ui__error(
"The %s event is not supported.\n",
975 }
else if (err ==
EMFILE) {
976 ui__error(
"Too many events are opened.\n"
977 "Try again after reducing the number of events\n");
981 ui__error(
"The sys_perf_event_open() syscall "
982 "returned with %d (%s). /bin/dmesg "
983 "may provide additional information.\n"
984 "No CONFIG_PERF_EVENTS=y kernel support "
985 "configured?\n", err,
strerror(err));
991 ui__error(
"Failed to mmap with %d (%s)\n",
1003 static int perf_top__setup_sample_type(
struct perf_top *top)
1007 ui__error(
"Selected -g but \"sym\" not present in --sort/-s.");
1012 ui__error(
"Can't register callchain params.\n");
1020 static int __cmd_top(
struct perf_top *top)
1032 ret = perf_top__setup_sample_type(top);
1036 if (perf_target__has_task(&top->
target))
1043 perf_top__start_counters(top);
1050 perf_top__mmap_read(top);
1052 if (pthread_create(&thread, NULL, (
use_browser > 0 ? display_thread_tui :
1053 display_thread), top)) {
1054 ui__error(
"Could not create display thread.\n");
1063 ui__error(
"Could not set realtime priority.\n");
1071 perf_top__mmap_read(top);
1085 parse_callchain_opt(
const struct option *
opt,
const char *arg,
int unset)
1104 tok = strtok((
char *)arg,
",");
1127 tok = strtok(NULL,
",");
1136 tok2 = strtok(NULL,
",");
1140 if (tok2[0] !=
'c') {
1142 tok2 = strtok(NULL,
",");
1148 if (!
strcmp(tok2,
"caller"))
1150 else if (!
strcmp(tok2,
"callee"))
1156 fprintf(stderr,
"Can't register callchain params\n");
1166 char errbuf[BUFSIZ];
1172 .sym_pcnt_filter = 5,
1177 char callchain_default_opt[] =
"fractal,0.5,callee";
1178 const struct option options[] = {
1180 "event selector. use 'perf list' to list available events",
1183 "event period to sample"),
1185 "profile events on existing process id"),
1187 "profile events on existing thread id"),
1189 "system-wide collection from all CPUs"),
1191 "list of cpus to monitor"),
1193 "file",
"vmlinux pathname"),
1195 "hide kernel symbols"),
1198 "collect data with this RT SCHED_FIFO priority"),
1200 "number of seconds to delay between refreshes"),
1202 "dump the symbol table used for profiling"),
1204 "only display functions with more events than this"),
1206 "put the counters into a counter group"),
1208 "child tasks inherit counters"),
1210 "symbol to annotate"),
1212 "zero history across updates"),
1214 "profile at this frequency"),
1216 "display this many functions"),
1218 "hide user symbols"),
1222 "be more verbose (show counter open errors, etc)"),
1224 "sort by key(s): pid, comm, dso, symbol, parent"),
1226 "Show a column with the number of samples"),
1228 "Display callchains using output_type (graph, flat, fractal, or none), min percent threshold and callchain order. "
1229 "Default: fractal,0.5,callee", &parse_callchain_opt,
1230 callchain_default_opt),
1232 "Show a column with the sum of periods"),
1234 "only consider symbols in these dsos"),
1236 "only consider symbols in these comms"),
1238 "only consider these symbols"),
1240 "Interleave source code with assembly code (default)"),
1242 "Display raw encoding of assembly instructions (default)"),
1244 "Specify disassembler style (e.g. -M intel for intel syntax)"),
1248 const char *
const top_usage[] = {
1249 "perf top [<options>]",
1289 goto out_delete_evlist;
1292 if (perf_target__none(&top.
target))
1293 top.
target.system_wide =
true;
1298 if (!top.
evlist->nr_entries &&
1300 ui__error(
"Not enough memory for event selector list\n");
1314 else if (top.
freq) {
1317 ui__error(
"frequency and count are zero, aborting\n");
1325 if (!pos->
attr.sample_period)
1350 .sa_sigaction = perf_top__sig_winch,
1353 perf_top__update_print_entries(&top);
1357 status = __cmd_top(&top);