186470930SIngo Molnar /* 286470930SIngo Molnar * builtin-top.c 386470930SIngo Molnar * 486470930SIngo Molnar * Builtin top command: Display a continuously updated profile of 586470930SIngo Molnar * any workload, CPU or specific PID. 686470930SIngo Molnar * 786470930SIngo Molnar * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com> 8ab81f3fdSArnaldo Carvalho de Melo * 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 986470930SIngo Molnar * 1086470930SIngo Molnar * Improvements and fixes by: 1186470930SIngo Molnar * 1286470930SIngo Molnar * Arjan van de Ven <arjan@linux.intel.com> 1386470930SIngo Molnar * Yanmin Zhang <yanmin.zhang@intel.com> 1486470930SIngo Molnar * Wu Fengguang <fengguang.wu@intel.com> 1586470930SIngo Molnar * Mike Galbraith <efault@gmx.de> 1686470930SIngo Molnar * Paul Mackerras <paulus@samba.org> 1786470930SIngo Molnar * 1886470930SIngo Molnar * Released under the GPL v2. (and only v2, not any later version) 1986470930SIngo Molnar */ 2086470930SIngo Molnar #include "builtin.h" 2186470930SIngo Molnar 2286470930SIngo Molnar #include "perf.h" 2386470930SIngo Molnar 2436532461SArnaldo Carvalho de Melo #include "util/annotate.h" 2541840d21STaeung Song #include "util/config.h" 2686470930SIngo Molnar #include "util/color.h" 275d8bb1ecSMathieu Poirier #include "util/drv_configs.h" 28361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h" 2969aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h" 305ab8c689SArnaldo Carvalho de Melo #include "util/event.h" 31b0a7d1a0SArnaldo Carvalho de Melo #include "util/machine.h" 32b3165f41SArnaldo Carvalho de Melo #include "util/session.h" 33b3165f41SArnaldo Carvalho de Melo #include "util/symbol.h" 34439d473bSArnaldo Carvalho de Melo #include "util/thread.h" 35fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 368c3e10ebSArnaldo Carvalho de Melo #include "util/top.h" 3743cbcd8aSArnaldo Carvalho de Melo #include <linux/rbtree.h> 384b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h> 3986470930SIngo Molnar #include "util/parse-events.h" 40a12b51c4SPaul Mackerras #include "util/cpumap.h" 4169aad6f1SArnaldo Carvalho de Melo #include "util/xyarray.h" 42ab81f3fdSArnaldo Carvalho de Melo #include "util/sort.h" 43b0742e90SArnaldo Carvalho de Melo #include "util/term.h" 446b118e92SDavid Ahern #include "util/intlist.h" 45a18b027eSAndi Kleen #include "util/parse-branch-options.h" 460d3942dbSSukadev Bhattiprolu #include "arch/common.h" 4786470930SIngo Molnar 488f28827aSFrederic Weisbecker #include "util/debug.h" 4916c66bc1SJiri Olsa #include "util/ordered-events.h" 508f28827aSFrederic Weisbecker 5186470930SIngo Molnar #include <assert.h> 5231d68e7bSArnaldo Carvalho de Melo #include <elf.h> 5386470930SIngo Molnar #include <fcntl.h> 5486470930SIngo Molnar 5586470930SIngo Molnar #include <stdio.h> 56923c42c1SMike Galbraith #include <termios.h> 57923c42c1SMike Galbraith #include <unistd.h> 589486aa38SArnaldo Carvalho de Melo #include <inttypes.h> 5986470930SIngo Molnar 6086470930SIngo Molnar #include <errno.h> 6186470930SIngo Molnar #include <time.h> 6286470930SIngo Molnar #include <sched.h> 639607ad3aSArnaldo Carvalho de Melo #include <signal.h> 6486470930SIngo Molnar 6586470930SIngo Molnar #include <sys/syscall.h> 6686470930SIngo Molnar #include <sys/ioctl.h> 67a8fa4960SArnaldo Carvalho de Melo #include <poll.h> 6886470930SIngo Molnar #include <sys/prctl.h> 6986470930SIngo Molnar #include <sys/wait.h> 7086470930SIngo Molnar #include <sys/uio.h> 7131d68e7bSArnaldo Carvalho de Melo #include <sys/utsname.h> 7286470930SIngo Molnar #include <sys/mman.h> 7386470930SIngo Molnar 74531d2410SArnaldo Carvalho de Melo #include <linux/stringify.h> 75b9c4b0f4SArnaldo Carvalho de Melo #include <linux/time64.h> 7686470930SIngo Molnar #include <linux/types.h> 7786470930SIngo Molnar 783d689ed6SArnaldo Carvalho de Melo #include "sane_ctype.h" 793d689ed6SArnaldo Carvalho de Melo 8011859e82SArnaldo Carvalho de Melo static volatile int done; 81b135e5eeSJiri Olsa static volatile int resize; 8211859e82SArnaldo Carvalho de Melo 83933cbb1cSNamhyung Kim #define HEADER_LINE_NR 5 84933cbb1cSNamhyung Kim 851758af10SArnaldo Carvalho de Melo static void perf_top__update_print_entries(struct perf_top *top) 863b6ed988SArnaldo Carvalho de Melo { 87933cbb1cSNamhyung Kim top->print_entries = top->winsize.ws_row - HEADER_LINE_NR; 883b6ed988SArnaldo Carvalho de Melo } 893b6ed988SArnaldo Carvalho de Melo 90244a1086SJiri Olsa static void winch_sig(int sig __maybe_unused) 913b6ed988SArnaldo Carvalho de Melo { 92b135e5eeSJiri Olsa resize = 1; 93b135e5eeSJiri Olsa } 941758af10SArnaldo Carvalho de Melo 95b135e5eeSJiri Olsa static void perf_top__resize(struct perf_top *top) 96b135e5eeSJiri Olsa { 971758af10SArnaldo Carvalho de Melo get_term_dimensions(&top->winsize); 981758af10SArnaldo Carvalho de Melo perf_top__update_print_entries(top); 993b6ed988SArnaldo Carvalho de Melo } 1003b6ed988SArnaldo Carvalho de Melo 1011758af10SArnaldo Carvalho de Melo static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) 102923c42c1SMike Galbraith { 103a7eec4c6SJiri Olsa struct perf_evsel *evsel = hists_to_evsel(he->hists); 104923c42c1SMike Galbraith struct symbol *sym; 105ce6f4fabSArnaldo Carvalho de Melo struct annotation *notes; 106439d473bSArnaldo Carvalho de Melo struct map *map; 10736532461SArnaldo Carvalho de Melo int err = -1; 108923c42c1SMike Galbraith 109ab81f3fdSArnaldo Carvalho de Melo if (!he || !he->ms.sym) 110b0a9ab62SArnaldo Carvalho de Melo return -1; 111b0a9ab62SArnaldo Carvalho de Melo 112ab81f3fdSArnaldo Carvalho de Melo sym = he->ms.sym; 113ab81f3fdSArnaldo Carvalho de Melo map = he->ms.map; 114b0a9ab62SArnaldo Carvalho de Melo 115b0a9ab62SArnaldo Carvalho de Melo /* 116b0a9ab62SArnaldo Carvalho de Melo * We can't annotate with just /proc/kallsyms 117b0a9ab62SArnaldo Carvalho de Melo */ 118bbb7f846SAdrian Hunter if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && 119bbb7f846SAdrian Hunter !dso__is_kcore(map->dso)) { 120ce6f4fabSArnaldo Carvalho de Melo pr_err("Can't annotate %s: No vmlinux file was found in the " 121ce6f4fabSArnaldo Carvalho de Melo "path\n", sym->name); 122ce6f4fabSArnaldo Carvalho de Melo sleep(1); 123b0a9ab62SArnaldo Carvalho de Melo return -1; 124b269876cSArnaldo Carvalho de Melo } 125b269876cSArnaldo Carvalho de Melo 126ce6f4fabSArnaldo Carvalho de Melo notes = symbol__annotation(sym); 127ce6f4fabSArnaldo Carvalho de Melo pthread_mutex_lock(¬es->lock); 128923c42c1SMike Galbraith 12914c8dde1SArnaldo Carvalho de Melo if (!symbol__hists(sym, top->evlist->nr_entries)) { 130c97cf422SArnaldo Carvalho de Melo pthread_mutex_unlock(¬es->lock); 13136532461SArnaldo Carvalho de Melo pr_err("Not enough memory for annotating '%s' symbol!\n", 13236532461SArnaldo Carvalho de Melo sym->name); 133ce6f4fabSArnaldo Carvalho de Melo sleep(1); 134c97cf422SArnaldo Carvalho de Melo return err; 135923c42c1SMike Galbraith } 13636532461SArnaldo Carvalho de Melo 137380195e2SArnaldo Carvalho de Melo err = symbol__annotate(sym, map, evsel, 0, &top->annotation_opts, NULL); 13836532461SArnaldo Carvalho de Melo if (err == 0) { 1391758af10SArnaldo Carvalho de Melo top->sym_filter_entry = he; 140ee51d851SArnaldo Carvalho de Melo } else { 141ee51d851SArnaldo Carvalho de Melo char msg[BUFSIZ]; 142ee51d851SArnaldo Carvalho de Melo symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); 143ee51d851SArnaldo Carvalho de Melo pr_err("Couldn't annotate %s: %s\n", sym->name, msg); 14436532461SArnaldo Carvalho de Melo } 145c97cf422SArnaldo Carvalho de Melo 146ce6f4fabSArnaldo Carvalho de Melo pthread_mutex_unlock(¬es->lock); 14736532461SArnaldo Carvalho de Melo return err; 148923c42c1SMike Galbraith } 149923c42c1SMike Galbraith 150ab81f3fdSArnaldo Carvalho de Melo static void __zero_source_counters(struct hist_entry *he) 151923c42c1SMike Galbraith { 152ab81f3fdSArnaldo Carvalho de Melo struct symbol *sym = he->ms.sym; 15336532461SArnaldo Carvalho de Melo symbol__annotate_zero_histograms(sym); 154923c42c1SMike Galbraith } 155923c42c1SMike Galbraith 15631d68e7bSArnaldo Carvalho de Melo static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) 15731d68e7bSArnaldo Carvalho de Melo { 15831d68e7bSArnaldo Carvalho de Melo struct utsname uts; 15931d68e7bSArnaldo Carvalho de Melo int err = uname(&uts); 16031d68e7bSArnaldo Carvalho de Melo 16131d68e7bSArnaldo Carvalho de Melo ui__warning("Out of bounds address found:\n\n" 16231d68e7bSArnaldo Carvalho de Melo "Addr: %" PRIx64 "\n" 16331d68e7bSArnaldo Carvalho de Melo "DSO: %s %c\n" 16431d68e7bSArnaldo Carvalho de Melo "Map: %" PRIx64 "-%" PRIx64 "\n" 16531d68e7bSArnaldo Carvalho de Melo "Symbol: %" PRIx64 "-%" PRIx64 " %c %s\n" 16631d68e7bSArnaldo Carvalho de Melo "Arch: %s\n" 16731d68e7bSArnaldo Carvalho de Melo "Kernel: %s\n" 16831d68e7bSArnaldo Carvalho de Melo "Tools: %s\n\n" 16931d68e7bSArnaldo Carvalho de Melo "Not all samples will be on the annotation output.\n\n" 17031d68e7bSArnaldo Carvalho de Melo "Please report to linux-kernel@vger.kernel.org\n", 17131d68e7bSArnaldo Carvalho de Melo ip, map->dso->long_name, dso__symtab_origin(map->dso), 17231d68e7bSArnaldo Carvalho de Melo map->start, map->end, sym->start, sym->end, 17331d68e7bSArnaldo Carvalho de Melo sym->binding == STB_GLOBAL ? 'g' : 17431d68e7bSArnaldo Carvalho de Melo sym->binding == STB_LOCAL ? 'l' : 'w', sym->name, 17531d68e7bSArnaldo Carvalho de Melo err ? "[unknown]" : uts.machine, 17631d68e7bSArnaldo Carvalho de Melo err ? "[unknown]" : uts.release, perf_version_string); 17731d68e7bSArnaldo Carvalho de Melo if (use_browser <= 0) 17831d68e7bSArnaldo Carvalho de Melo sleep(5); 17931d68e7bSArnaldo Carvalho de Melo 18031d68e7bSArnaldo Carvalho de Melo map->erange_warned = true; 18131d68e7bSArnaldo Carvalho de Melo } 18231d68e7bSArnaldo Carvalho de Melo 1831758af10SArnaldo Carvalho de Melo static void perf_top__record_precise_ip(struct perf_top *top, 1841758af10SArnaldo Carvalho de Melo struct hist_entry *he, 185bab89f6aSTaeung Song struct perf_sample *sample, 186e345f3bdSArnaldo Carvalho de Melo struct perf_evsel *evsel, u64 ip) 187923c42c1SMike Galbraith { 188ce6f4fabSArnaldo Carvalho de Melo struct annotation *notes; 189beefb8d0SNamhyung Kim struct symbol *sym = he->ms.sym; 19048c65bdaSNamhyung Kim int err = 0; 191ce6f4fabSArnaldo Carvalho de Melo 192beefb8d0SNamhyung Kim if (sym == NULL || (use_browser == 0 && 193beefb8d0SNamhyung Kim (top->sym_filter_entry == NULL || 194beefb8d0SNamhyung Kim top->sym_filter_entry->ms.sym != sym))) 195923c42c1SMike Galbraith return; 196923c42c1SMike Galbraith 197ce6f4fabSArnaldo Carvalho de Melo notes = symbol__annotation(sym); 198ce6f4fabSArnaldo Carvalho de Melo 199ce6f4fabSArnaldo Carvalho de Melo if (pthread_mutex_trylock(¬es->lock)) 200923c42c1SMike Galbraith return; 201923c42c1SMike Galbraith 202e345f3bdSArnaldo Carvalho de Melo err = hist_entry__inc_addr_samples(he, sample, evsel, ip); 203923c42c1SMike Galbraith 204ce6f4fabSArnaldo Carvalho de Melo pthread_mutex_unlock(¬es->lock); 20531d68e7bSArnaldo Carvalho de Melo 206151ee834SNamhyung Kim if (unlikely(err)) { 2077c50391fSNamhyung Kim /* 2087c50391fSNamhyung Kim * This function is now called with he->hists->lock held. 2097c50391fSNamhyung Kim * Release it before going to sleep. 2107c50391fSNamhyung Kim */ 2117c50391fSNamhyung Kim pthread_mutex_unlock(&he->hists->lock); 2127c50391fSNamhyung Kim 21331d68e7bSArnaldo Carvalho de Melo if (err == -ERANGE && !he->ms.map->erange_warned) 21431d68e7bSArnaldo Carvalho de Melo ui__warn_map_erange(he->ms.map, sym, ip); 215b66d8c0cSArnaldo Carvalho de Melo else if (err == -ENOMEM) { 216b66d8c0cSArnaldo Carvalho de Melo pr_err("Not enough memory for annotating '%s' symbol!\n", 217b66d8c0cSArnaldo Carvalho de Melo sym->name); 218b66d8c0cSArnaldo Carvalho de Melo sleep(1); 219b66d8c0cSArnaldo Carvalho de Melo } 2207c50391fSNamhyung Kim 2217c50391fSNamhyung Kim pthread_mutex_lock(&he->hists->lock); 222923c42c1SMike Galbraith } 223151ee834SNamhyung Kim } 224923c42c1SMike Galbraith 2251758af10SArnaldo Carvalho de Melo static void perf_top__show_details(struct perf_top *top) 226923c42c1SMike Galbraith { 2271758af10SArnaldo Carvalho de Melo struct hist_entry *he = top->sym_filter_entry; 228f681d593SJiri Olsa struct perf_evsel *evsel = hists_to_evsel(he->hists); 229ce6f4fabSArnaldo Carvalho de Melo struct annotation *notes; 230923c42c1SMike Galbraith struct symbol *symbol; 23136532461SArnaldo Carvalho de Melo int more; 232923c42c1SMike Galbraith 233ab81f3fdSArnaldo Carvalho de Melo if (!he) 234923c42c1SMike Galbraith return; 235923c42c1SMike Galbraith 236ab81f3fdSArnaldo Carvalho de Melo symbol = he->ms.sym; 237ce6f4fabSArnaldo Carvalho de Melo notes = symbol__annotation(symbol); 238ce6f4fabSArnaldo Carvalho de Melo 239ce6f4fabSArnaldo Carvalho de Melo pthread_mutex_lock(¬es->lock); 240ce6f4fabSArnaldo Carvalho de Melo 241f681d593SJiri Olsa symbol__calc_percent(symbol, evsel); 242f681d593SJiri Olsa 243ce6f4fabSArnaldo Carvalho de Melo if (notes->src == NULL) 244ce6f4fabSArnaldo Carvalho de Melo goto out_unlock; 245923c42c1SMike Galbraith 2467289f83cSArnaldo Carvalho de Melo printf("Showing %s for %s\n", perf_evsel__name(top->sym_evsel), symbol->name); 247982d410bSArnaldo Carvalho de Melo printf(" Events Pcnt (>=%d%%)\n", top->annotation_opts.min_pcnt); 248923c42c1SMike Galbraith 249982d410bSArnaldo Carvalho de Melo more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel, &top->annotation_opts); 2505d484f99SArnaldo Carvalho de Melo 2515d484f99SArnaldo Carvalho de Melo if (top->evlist->enabled) { 2521758af10SArnaldo Carvalho de Melo if (top->zero) 2531758af10SArnaldo Carvalho de Melo symbol__annotate_zero_histogram(symbol, top->sym_evsel->idx); 25436532461SArnaldo Carvalho de Melo else 2551758af10SArnaldo Carvalho de Melo symbol__annotate_decay_histogram(symbol, top->sym_evsel->idx); 2565d484f99SArnaldo Carvalho de Melo } 25736532461SArnaldo Carvalho de Melo if (more != 0) 258923c42c1SMike Galbraith printf("%d lines not displayed, maybe increase display entries [e]\n", more); 259ce6f4fabSArnaldo Carvalho de Melo out_unlock: 260ce6f4fabSArnaldo Carvalho de Melo pthread_mutex_unlock(¬es->lock); 261923c42c1SMike Galbraith } 26286470930SIngo Molnar 2631758af10SArnaldo Carvalho de Melo static void perf_top__print_sym_table(struct perf_top *top) 26486470930SIngo Molnar { 2658c3e10ebSArnaldo Carvalho de Melo char bf[160]; 2668c3e10ebSArnaldo Carvalho de Melo int printed = 0; 2671758af10SArnaldo Carvalho de Melo const int win_width = top->winsize.ws_col - 1; 268452ce03bSJiri Olsa struct perf_evsel *evsel = top->sym_evsel; 269452ce03bSJiri Olsa struct hists *hists = evsel__hists(evsel); 27086470930SIngo Molnar 27186470930SIngo Molnar puts(CONSOLE_CLEAR); 27286470930SIngo Molnar 2731758af10SArnaldo Carvalho de Melo perf_top__header_snprintf(top, bf, sizeof(bf)); 2748c3e10ebSArnaldo Carvalho de Melo printf("%s\n", bf); 27586470930SIngo Molnar 2761758af10SArnaldo Carvalho de Melo perf_top__reset_sample_counters(top); 27786470930SIngo Molnar 2781a105f74SArnaldo Carvalho de Melo printf("%-*.*s\n", win_width, win_width, graph_dotted_line); 27986470930SIngo Molnar 280a1ff5b05SKan Liang if (!top->record_opts.overwrite && 281a1ff5b05SKan Liang (hists->stats.nr_lost_warned != 282a1ff5b05SKan Liang hists->stats.nr_events[PERF_RECORD_LOST])) { 2834ea062edSArnaldo Carvalho de Melo hists->stats.nr_lost_warned = 2844ea062edSArnaldo Carvalho de Melo hists->stats.nr_events[PERF_RECORD_LOST]; 2857b27509fSArnaldo Carvalho de Melo color_fprintf(stdout, PERF_COLOR_RED, 2867b27509fSArnaldo Carvalho de Melo "WARNING: LOST %d chunks, Check IO/CPU overload", 2874ea062edSArnaldo Carvalho de Melo hists->stats.nr_lost_warned); 288ab81f3fdSArnaldo Carvalho de Melo ++printed; 28993fc64f1SArnaldo Carvalho de Melo } 29093fc64f1SArnaldo Carvalho de Melo 2911758af10SArnaldo Carvalho de Melo if (top->sym_filter_entry) { 2921758af10SArnaldo Carvalho de Melo perf_top__show_details(top); 293923c42c1SMike Galbraith return; 294923c42c1SMike Galbraith } 295923c42c1SMike Galbraith 2965d484f99SArnaldo Carvalho de Melo if (top->evlist->enabled) { 297701937bdSNamhyung Kim if (top->zero) { 2984ea062edSArnaldo Carvalho de Melo hists__delete_entries(hists); 299701937bdSNamhyung Kim } else { 3004ea062edSArnaldo Carvalho de Melo hists__decay_entries(hists, top->hide_user_symbols, 3011758af10SArnaldo Carvalho de Melo top->hide_kernel_symbols); 302701937bdSNamhyung Kim } 3035d484f99SArnaldo Carvalho de Melo } 304701937bdSNamhyung Kim 3054ea062edSArnaldo Carvalho de Melo hists__collapse_resort(hists, NULL); 306452ce03bSJiri Olsa perf_evsel__output_resort(evsel, NULL); 307701937bdSNamhyung Kim 3084ea062edSArnaldo Carvalho de Melo hists__output_recalc_col_len(hists, top->print_entries - printed); 3091a105f74SArnaldo Carvalho de Melo putchar('\n'); 3104ea062edSArnaldo Carvalho de Melo hists__fprintf(hists, false, top->print_entries - printed, win_width, 311e9de7e2fSArnaldo Carvalho de Melo top->min_percent, stdout, !symbol_conf.use_callchain); 31286470930SIngo Molnar } 31386470930SIngo Molnar 314923c42c1SMike Galbraith static void prompt_integer(int *target, const char *msg) 315923c42c1SMike Galbraith { 316923c42c1SMike Galbraith char *buf = malloc(0), *p; 317923c42c1SMike Galbraith size_t dummy = 0; 318923c42c1SMike Galbraith int tmp; 319923c42c1SMike Galbraith 320923c42c1SMike Galbraith fprintf(stdout, "\n%s: ", msg); 321923c42c1SMike Galbraith if (getline(&buf, &dummy, stdin) < 0) 322923c42c1SMike Galbraith return; 323923c42c1SMike Galbraith 324923c42c1SMike Galbraith p = strchr(buf, '\n'); 325923c42c1SMike Galbraith if (p) 326923c42c1SMike Galbraith *p = 0; 327923c42c1SMike Galbraith 328923c42c1SMike Galbraith p = buf; 329923c42c1SMike Galbraith while(*p) { 330923c42c1SMike Galbraith if (!isdigit(*p)) 331923c42c1SMike Galbraith goto out_free; 332923c42c1SMike Galbraith p++; 333923c42c1SMike Galbraith } 334923c42c1SMike Galbraith tmp = strtoul(buf, NULL, 10); 335923c42c1SMike Galbraith *target = tmp; 336923c42c1SMike Galbraith out_free: 337923c42c1SMike Galbraith free(buf); 338923c42c1SMike Galbraith } 339923c42c1SMike Galbraith 340923c42c1SMike Galbraith static void prompt_percent(int *target, const char *msg) 341923c42c1SMike Galbraith { 342923c42c1SMike Galbraith int tmp = 0; 343923c42c1SMike Galbraith 344923c42c1SMike Galbraith prompt_integer(&tmp, msg); 345923c42c1SMike Galbraith if (tmp >= 0 && tmp <= 100) 346923c42c1SMike Galbraith *target = tmp; 347923c42c1SMike Galbraith } 348923c42c1SMike Galbraith 3491758af10SArnaldo Carvalho de Melo static void perf_top__prompt_symbol(struct perf_top *top, const char *msg) 350923c42c1SMike Galbraith { 351923c42c1SMike Galbraith char *buf = malloc(0), *p; 3521758af10SArnaldo Carvalho de Melo struct hist_entry *syme = top->sym_filter_entry, *n, *found = NULL; 3534ea062edSArnaldo Carvalho de Melo struct hists *hists = evsel__hists(top->sym_evsel); 354ab81f3fdSArnaldo Carvalho de Melo struct rb_node *next; 355923c42c1SMike Galbraith size_t dummy = 0; 356923c42c1SMike Galbraith 357923c42c1SMike Galbraith /* zero counters of active symbol */ 358923c42c1SMike Galbraith if (syme) { 359923c42c1SMike Galbraith __zero_source_counters(syme); 3601758af10SArnaldo Carvalho de Melo top->sym_filter_entry = NULL; 361923c42c1SMike Galbraith } 362923c42c1SMike Galbraith 363923c42c1SMike Galbraith fprintf(stdout, "\n%s: ", msg); 364923c42c1SMike Galbraith if (getline(&buf, &dummy, stdin) < 0) 365923c42c1SMike Galbraith goto out_free; 366923c42c1SMike Galbraith 367923c42c1SMike Galbraith p = strchr(buf, '\n'); 368923c42c1SMike Galbraith if (p) 369923c42c1SMike Galbraith *p = 0; 370923c42c1SMike Galbraith 3714ea062edSArnaldo Carvalho de Melo next = rb_first(&hists->entries); 372ab81f3fdSArnaldo Carvalho de Melo while (next) { 373ab81f3fdSArnaldo Carvalho de Melo n = rb_entry(next, struct hist_entry, rb_node); 374ab81f3fdSArnaldo Carvalho de Melo if (n->ms.sym && !strcmp(buf, n->ms.sym->name)) { 375ab81f3fdSArnaldo Carvalho de Melo found = n; 376923c42c1SMike Galbraith break; 377923c42c1SMike Galbraith } 378ab81f3fdSArnaldo Carvalho de Melo next = rb_next(&n->rb_node); 379923c42c1SMike Galbraith } 380923c42c1SMike Galbraith 381923c42c1SMike Galbraith if (!found) { 38266aeb6d5SKirill Smelkov fprintf(stderr, "Sorry, %s is not active.\n", buf); 383923c42c1SMike Galbraith sleep(1); 384923c42c1SMike Galbraith } else 3851758af10SArnaldo Carvalho de Melo perf_top__parse_source(top, found); 386923c42c1SMike Galbraith 387923c42c1SMike Galbraith out_free: 388923c42c1SMike Galbraith free(buf); 389923c42c1SMike Galbraith } 390923c42c1SMike Galbraith 3911758af10SArnaldo Carvalho de Melo static void perf_top__print_mapped_keys(struct perf_top *top) 392923c42c1SMike Galbraith { 393091bd2e9SMike Galbraith char *name = NULL; 394091bd2e9SMike Galbraith 3951758af10SArnaldo Carvalho de Melo if (top->sym_filter_entry) { 3961758af10SArnaldo Carvalho de Melo struct symbol *sym = top->sym_filter_entry->ms.sym; 397091bd2e9SMike Galbraith name = sym->name; 398091bd2e9SMike Galbraith } 399091bd2e9SMike Galbraith 400091bd2e9SMike Galbraith fprintf(stdout, "\nMapped keys:\n"); 4011758af10SArnaldo Carvalho de Melo fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", top->delay_secs); 4021758af10SArnaldo Carvalho de Melo fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", top->print_entries); 403091bd2e9SMike Galbraith 4041758af10SArnaldo Carvalho de Melo if (top->evlist->nr_entries > 1) 4057289f83cSArnaldo Carvalho de Melo fprintf(stdout, "\t[E] active event counter. \t(%s)\n", perf_evsel__name(top->sym_evsel)); 406091bd2e9SMike Galbraith 4071758af10SArnaldo Carvalho de Melo fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", top->count_filter); 408091bd2e9SMike Galbraith 409982d410bSArnaldo Carvalho de Melo fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", top->annotation_opts.min_pcnt); 410091bd2e9SMike Galbraith fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL"); 411091bd2e9SMike Galbraith fprintf(stdout, "\t[S] stop annotation.\n"); 412091bd2e9SMike Galbraith 4138ffcda17SArnaldo Carvalho de Melo fprintf(stdout, 4148fce3743SSihyeon Jang "\t[K] hide kernel symbols. \t(%s)\n", 4151758af10SArnaldo Carvalho de Melo top->hide_kernel_symbols ? "yes" : "no"); 4168ffcda17SArnaldo Carvalho de Melo fprintf(stdout, 4178ffcda17SArnaldo Carvalho de Melo "\t[U] hide user symbols. \t(%s)\n", 4181758af10SArnaldo Carvalho de Melo top->hide_user_symbols ? "yes" : "no"); 4191758af10SArnaldo Carvalho de Melo fprintf(stdout, "\t[z] toggle sample zeroing. \t(%d)\n", top->zero ? 1 : 0); 420091bd2e9SMike Galbraith fprintf(stdout, "\t[qQ] quit.\n"); 421091bd2e9SMike Galbraith } 422091bd2e9SMike Galbraith 4231758af10SArnaldo Carvalho de Melo static int perf_top__key_mapped(struct perf_top *top, int c) 424091bd2e9SMike Galbraith { 425091bd2e9SMike Galbraith switch (c) { 426091bd2e9SMike Galbraith case 'd': 427091bd2e9SMike Galbraith case 'e': 428091bd2e9SMike Galbraith case 'f': 429091bd2e9SMike Galbraith case 'z': 430091bd2e9SMike Galbraith case 'q': 431091bd2e9SMike Galbraith case 'Q': 4328ffcda17SArnaldo Carvalho de Melo case 'K': 4338ffcda17SArnaldo Carvalho de Melo case 'U': 4346cff0e8dSKirill Smelkov case 'F': 4356cff0e8dSKirill Smelkov case 's': 4366cff0e8dSKirill Smelkov case 'S': 437091bd2e9SMike Galbraith return 1; 438091bd2e9SMike Galbraith case 'E': 4391758af10SArnaldo Carvalho de Melo return top->evlist->nr_entries > 1 ? 1 : 0; 44083a0944fSIngo Molnar default: 44183a0944fSIngo Molnar break; 442091bd2e9SMike Galbraith } 443091bd2e9SMike Galbraith 444091bd2e9SMike Galbraith return 0; 445923c42c1SMike Galbraith } 446923c42c1SMike Galbraith 44711859e82SArnaldo Carvalho de Melo static bool perf_top__handle_keypress(struct perf_top *top, int c) 448923c42c1SMike Galbraith { 44911859e82SArnaldo Carvalho de Melo bool ret = true; 45011859e82SArnaldo Carvalho de Melo 4511758af10SArnaldo Carvalho de Melo if (!perf_top__key_mapped(top, c)) { 452091bd2e9SMike Galbraith struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 4533969cc09SJiri Olsa struct termios save; 454091bd2e9SMike Galbraith 4551758af10SArnaldo Carvalho de Melo perf_top__print_mapped_keys(top); 456091bd2e9SMike Galbraith fprintf(stdout, "\nEnter selection, or unmapped key to continue: "); 457091bd2e9SMike Galbraith fflush(stdout); 458091bd2e9SMike Galbraith 4593969cc09SJiri Olsa set_term_quiet_input(&save); 460091bd2e9SMike Galbraith 461091bd2e9SMike Galbraith poll(&stdin_poll, 1, -1); 462091bd2e9SMike Galbraith c = getc(stdin); 463091bd2e9SMike Galbraith 464091bd2e9SMike Galbraith tcsetattr(0, TCSAFLUSH, &save); 4651758af10SArnaldo Carvalho de Melo if (!perf_top__key_mapped(top, c)) 46611859e82SArnaldo Carvalho de Melo return ret; 467091bd2e9SMike Galbraith } 468091bd2e9SMike Galbraith 469923c42c1SMike Galbraith switch (c) { 470923c42c1SMike Galbraith case 'd': 4711758af10SArnaldo Carvalho de Melo prompt_integer(&top->delay_secs, "Enter display delay"); 4721758af10SArnaldo Carvalho de Melo if (top->delay_secs < 1) 4731758af10SArnaldo Carvalho de Melo top->delay_secs = 1; 474923c42c1SMike Galbraith break; 475923c42c1SMike Galbraith case 'e': 4761758af10SArnaldo Carvalho de Melo prompt_integer(&top->print_entries, "Enter display entries (lines)"); 4771758af10SArnaldo Carvalho de Melo if (top->print_entries == 0) { 478b135e5eeSJiri Olsa perf_top__resize(top); 479244a1086SJiri Olsa signal(SIGWINCH, winch_sig); 480509605dbSStephane Eranian } else { 4813b6ed988SArnaldo Carvalho de Melo signal(SIGWINCH, SIG_DFL); 482509605dbSStephane Eranian } 483923c42c1SMike Galbraith break; 484923c42c1SMike Galbraith case 'E': 4851758af10SArnaldo Carvalho de Melo if (top->evlist->nr_entries > 1) { 486ce2d17caSAkihiro Nagai /* Select 0 as the default event: */ 487ce2d17caSAkihiro Nagai int counter = 0; 488ce2d17caSAkihiro Nagai 489923c42c1SMike Galbraith fprintf(stderr, "\nAvailable events:"); 49069aad6f1SArnaldo Carvalho de Melo 491e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(top->evlist, top->sym_evsel) 4927289f83cSArnaldo Carvalho de Melo fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel)); 493923c42c1SMike Galbraith 494ec52d976SArnaldo Carvalho de Melo prompt_integer(&counter, "Enter details event counter"); 495923c42c1SMike Galbraith 4961758af10SArnaldo Carvalho de Melo if (counter >= top->evlist->nr_entries) { 4970c21f736SArnaldo Carvalho de Melo top->sym_evsel = perf_evlist__first(top->evlist); 4987289f83cSArnaldo Carvalho de Melo fprintf(stderr, "Sorry, no such event, using %s.\n", perf_evsel__name(top->sym_evsel)); 499923c42c1SMike Galbraith sleep(1); 50069aad6f1SArnaldo Carvalho de Melo break; 501923c42c1SMike Galbraith } 502e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(top->evlist, top->sym_evsel) 5031758af10SArnaldo Carvalho de Melo if (top->sym_evsel->idx == counter) 50469aad6f1SArnaldo Carvalho de Melo break; 505ec52d976SArnaldo Carvalho de Melo } else 5060c21f736SArnaldo Carvalho de Melo top->sym_evsel = perf_evlist__first(top->evlist); 507923c42c1SMike Galbraith break; 508923c42c1SMike Galbraith case 'f': 5091758af10SArnaldo Carvalho de Melo prompt_integer(&top->count_filter, "Enter display event count filter"); 510923c42c1SMike Galbraith break; 511923c42c1SMike Galbraith case 'F': 512982d410bSArnaldo Carvalho de Melo prompt_percent(&top->annotation_opts.min_pcnt, 5131758af10SArnaldo Carvalho de Melo "Enter details display event filter (percent)"); 514923c42c1SMike Galbraith break; 5158ffcda17SArnaldo Carvalho de Melo case 'K': 5161758af10SArnaldo Carvalho de Melo top->hide_kernel_symbols = !top->hide_kernel_symbols; 5178ffcda17SArnaldo Carvalho de Melo break; 518923c42c1SMike Galbraith case 'q': 519923c42c1SMike Galbraith case 'Q': 520923c42c1SMike Galbraith printf("exiting.\n"); 5211758af10SArnaldo Carvalho de Melo if (top->dump_symtab) 5221758af10SArnaldo Carvalho de Melo perf_session__fprintf_dsos(top->session, stderr); 52311859e82SArnaldo Carvalho de Melo ret = false; 52411859e82SArnaldo Carvalho de Melo break; 525923c42c1SMike Galbraith case 's': 5261758af10SArnaldo Carvalho de Melo perf_top__prompt_symbol(top, "Enter details symbol"); 527923c42c1SMike Galbraith break; 528923c42c1SMike Galbraith case 'S': 5291758af10SArnaldo Carvalho de Melo if (!top->sym_filter_entry) 530923c42c1SMike Galbraith break; 531923c42c1SMike Galbraith else { 5321758af10SArnaldo Carvalho de Melo struct hist_entry *syme = top->sym_filter_entry; 533923c42c1SMike Galbraith 5341758af10SArnaldo Carvalho de Melo top->sym_filter_entry = NULL; 535923c42c1SMike Galbraith __zero_source_counters(syme); 536923c42c1SMike Galbraith } 537923c42c1SMike Galbraith break; 5388ffcda17SArnaldo Carvalho de Melo case 'U': 5391758af10SArnaldo Carvalho de Melo top->hide_user_symbols = !top->hide_user_symbols; 5408ffcda17SArnaldo Carvalho de Melo break; 541923c42c1SMike Galbraith case 'z': 5421758af10SArnaldo Carvalho de Melo top->zero = !top->zero; 543923c42c1SMike Galbraith break; 54483a0944fSIngo Molnar default: 54583a0944fSIngo Molnar break; 546923c42c1SMike Galbraith } 54711859e82SArnaldo Carvalho de Melo 54811859e82SArnaldo Carvalho de Melo return ret; 549923c42c1SMike Galbraith } 550923c42c1SMike Galbraith 551ab81f3fdSArnaldo Carvalho de Melo static void perf_top__sort_new_samples(void *arg) 552ab81f3fdSArnaldo Carvalho de Melo { 553ab81f3fdSArnaldo Carvalho de Melo struct perf_top *t = arg; 554452ce03bSJiri Olsa struct perf_evsel *evsel = t->sym_evsel; 5554ea062edSArnaldo Carvalho de Melo struct hists *hists; 5564ea062edSArnaldo Carvalho de Melo 557ab81f3fdSArnaldo Carvalho de Melo if (t->evlist->selected != NULL) 558ab81f3fdSArnaldo Carvalho de Melo t->sym_evsel = t->evlist->selected; 559ab81f3fdSArnaldo Carvalho de Melo 560452ce03bSJiri Olsa hists = evsel__hists(evsel); 5614ea062edSArnaldo Carvalho de Melo 5625d484f99SArnaldo Carvalho de Melo if (t->evlist->enabled) { 563701937bdSNamhyung Kim if (t->zero) { 5644ea062edSArnaldo Carvalho de Melo hists__delete_entries(hists); 565701937bdSNamhyung Kim } else { 5664ea062edSArnaldo Carvalho de Melo hists__decay_entries(hists, t->hide_user_symbols, 5671758af10SArnaldo Carvalho de Melo t->hide_kernel_symbols); 568ab81f3fdSArnaldo Carvalho de Melo } 5695d484f99SArnaldo Carvalho de Melo } 570ab81f3fdSArnaldo Carvalho de Melo 5714ea062edSArnaldo Carvalho de Melo hists__collapse_resort(hists, NULL); 572452ce03bSJiri Olsa perf_evsel__output_resort(evsel, NULL); 573254de74cSJiri Olsa 574254de74cSJiri Olsa if (t->lost) 575254de74cSJiri Olsa pr_warning("Too slow to read ring buffer (change period (-c/-F) or limit CPUs (-C)\n"); 576254de74cSJiri Olsa 577254de74cSJiri Olsa perf_top__reset_sample_counters(t); 578701937bdSNamhyung Kim } 579701937bdSNamhyung Kim 5801758af10SArnaldo Carvalho de Melo static void *display_thread_tui(void *arg) 581c0443df1SArnaldo Carvalho de Melo { 5820d37aa34SArnaldo Carvalho de Melo struct perf_evsel *pos; 5831758af10SArnaldo Carvalho de Melo struct perf_top *top = arg; 584ab81f3fdSArnaldo Carvalho de Melo const char *help = "For a higher level overview, try: perf top --sort comm,dso"; 5859783adf7SNamhyung Kim struct hist_browser_timer hbt = { 5869783adf7SNamhyung Kim .timer = perf_top__sort_new_samples, 5879783adf7SNamhyung Kim .arg = top, 5889783adf7SNamhyung Kim .refresh = top->delay_secs, 5899783adf7SNamhyung Kim }; 590ab81f3fdSArnaldo Carvalho de Melo 591868a8329SKrister Johansen /* In order to read symbols from other namespaces perf to needs to call 592868a8329SKrister Johansen * setns(2). This isn't permitted if the struct_fs has multiple users. 593868a8329SKrister Johansen * unshare(2) the fs so that we may continue to setns into namespaces 594868a8329SKrister Johansen * that we're observing. 595868a8329SKrister Johansen */ 596868a8329SKrister Johansen unshare(CLONE_FS); 597868a8329SKrister Johansen 5981758af10SArnaldo Carvalho de Melo perf_top__sort_new_samples(top); 5990d37aa34SArnaldo Carvalho de Melo 6000d37aa34SArnaldo Carvalho de Melo /* 6010d37aa34SArnaldo Carvalho de Melo * Initialize the uid_filter_str, in the future the TUI will allow 602adba1634SIngo Molnar * Zooming in/out UIDs. For now just use whatever the user passed 6030d37aa34SArnaldo Carvalho de Melo * via --uid. 6040d37aa34SArnaldo Carvalho de Melo */ 605e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(top->evlist, pos) { 6064ea062edSArnaldo Carvalho de Melo struct hists *hists = evsel__hists(pos); 6074ea062edSArnaldo Carvalho de Melo hists->uid_filter_str = top->record_opts.target.uid_str; 6084ea062edSArnaldo Carvalho de Melo } 6090d37aa34SArnaldo Carvalho de Melo 61013d1e536SNamhyung Kim perf_evlist__tui_browse_hists(top->evlist, help, &hbt, 6115d484f99SArnaldo Carvalho de Melo top->min_percent, 612a1ff5b05SKan Liang &top->session->header.env, 613cd0cccbaSArnaldo Carvalho de Melo !top->record_opts.overwrite, 614cd0cccbaSArnaldo Carvalho de Melo &top->annotation_opts); 615ab81f3fdSArnaldo Carvalho de Melo 61611859e82SArnaldo Carvalho de Melo done = 1; 617c0443df1SArnaldo Carvalho de Melo return NULL; 618c0443df1SArnaldo Carvalho de Melo } 619c0443df1SArnaldo Carvalho de Melo 6204a1a9971SJiri Olsa static void display_sig(int sig __maybe_unused) 6214a1a9971SJiri Olsa { 6224a1a9971SJiri Olsa done = 1; 6234a1a9971SJiri Olsa } 6244a1a9971SJiri Olsa 6254a1a9971SJiri Olsa static void display_setup_sig(void) 6264a1a9971SJiri Olsa { 62709f4d78aSArnaldo Carvalho de Melo signal(SIGSEGV, sighandler_dump_stack); 62809f4d78aSArnaldo Carvalho de Melo signal(SIGFPE, sighandler_dump_stack); 6294a1a9971SJiri Olsa signal(SIGINT, display_sig); 6304a1a9971SJiri Olsa signal(SIGQUIT, display_sig); 6314a1a9971SJiri Olsa signal(SIGTERM, display_sig); 6324a1a9971SJiri Olsa } 6334a1a9971SJiri Olsa 6341758af10SArnaldo Carvalho de Melo static void *display_thread(void *arg) 63586470930SIngo Molnar { 63686470930SIngo Molnar struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 6379398c484SJiri Olsa struct termios save; 6381758af10SArnaldo Carvalho de Melo struct perf_top *top = arg; 639923c42c1SMike Galbraith int delay_msecs, c; 64086470930SIngo Molnar 641868a8329SKrister Johansen /* In order to read symbols from other namespaces perf to needs to call 642868a8329SKrister Johansen * setns(2). This isn't permitted if the struct_fs has multiple users. 643868a8329SKrister Johansen * unshare(2) the fs so that we may continue to setns into namespaces 644868a8329SKrister Johansen * that we're observing. 645868a8329SKrister Johansen */ 646868a8329SKrister Johansen unshare(CLONE_FS); 647868a8329SKrister Johansen 6484a1a9971SJiri Olsa display_setup_sig(); 6493af6e338SArnaldo Carvalho de Melo pthread__unblock_sigwinch(); 650923c42c1SMike Galbraith repeat: 651b9c4b0f4SArnaldo Carvalho de Melo delay_msecs = top->delay_secs * MSEC_PER_SEC; 6529398c484SJiri Olsa set_term_quiet_input(&save); 653923c42c1SMike Galbraith /* trash return*/ 654923c42c1SMike Galbraith getc(stdin); 65586470930SIngo Molnar 65611859e82SArnaldo Carvalho de Melo while (!done) { 6571758af10SArnaldo Carvalho de Melo perf_top__print_sym_table(top); 6583af6e338SArnaldo Carvalho de Melo /* 6593af6e338SArnaldo Carvalho de Melo * Either timeout expired or we got an EINTR due to SIGWINCH, 6603af6e338SArnaldo Carvalho de Melo * refresh screen in both cases. 6613af6e338SArnaldo Carvalho de Melo */ 6623af6e338SArnaldo Carvalho de Melo switch (poll(&stdin_poll, 1, delay_msecs)) { 6633af6e338SArnaldo Carvalho de Melo case 0: 6643af6e338SArnaldo Carvalho de Melo continue; 6653af6e338SArnaldo Carvalho de Melo case -1: 6663af6e338SArnaldo Carvalho de Melo if (errno == EINTR) 6673af6e338SArnaldo Carvalho de Melo continue; 6687b0214b7SArnaldo Carvalho de Melo __fallthrough; 6693af6e338SArnaldo Carvalho de Melo default: 670923c42c1SMike Galbraith c = getc(stdin); 671923c42c1SMike Galbraith tcsetattr(0, TCSAFLUSH, &save); 672923c42c1SMike Galbraith 67311859e82SArnaldo Carvalho de Melo if (perf_top__handle_keypress(top, c)) 674923c42c1SMike Galbraith goto repeat; 67511859e82SArnaldo Carvalho de Melo done = 1; 67611859e82SArnaldo Carvalho de Melo } 67711859e82SArnaldo Carvalho de Melo } 67886470930SIngo Molnar 6794a1a9971SJiri Olsa tcsetattr(0, TCSAFLUSH, &save); 68086470930SIngo Molnar return NULL; 68186470930SIngo Molnar } 68286470930SIngo Molnar 6837c50391fSNamhyung Kim static int hist_iter__top_callback(struct hist_entry_iter *iter, 6847c50391fSNamhyung Kim struct addr_location *al, bool single, 6857c50391fSNamhyung Kim void *arg) 6867c50391fSNamhyung Kim { 6877c50391fSNamhyung Kim struct perf_top *top = arg; 6887c50391fSNamhyung Kim struct hist_entry *he = iter->he; 6897c50391fSNamhyung Kim struct perf_evsel *evsel = iter->evsel; 6907c50391fSNamhyung Kim 6912e0453afSJiri Olsa if (perf_hpp_list.sym && single) 692e345f3bdSArnaldo Carvalho de Melo perf_top__record_precise_ip(top, he, iter->sample, evsel, al->addr); 6937c50391fSNamhyung Kim 694a18b027eSAndi Kleen hist__account_cycles(iter->sample->branch_stack, al, iter->sample, 695a18b027eSAndi Kleen !(top->record_opts.branch_stack & PERF_SAMPLE_BRANCH_ANY)); 6967c50391fSNamhyung Kim return 0; 6977c50391fSNamhyung Kim } 6987c50391fSNamhyung Kim 6991758af10SArnaldo Carvalho de Melo static void perf_event__process_sample(struct perf_tool *tool, 7001758af10SArnaldo Carvalho de Melo const union perf_event *event, 7017b27509fSArnaldo Carvalho de Melo struct perf_evsel *evsel, 7028d50e5b4SArnaldo Carvalho de Melo struct perf_sample *sample, 703743eb868SArnaldo Carvalho de Melo struct machine *machine) 70486470930SIngo Molnar { 7051758af10SArnaldo Carvalho de Melo struct perf_top *top = container_of(tool, struct perf_top, tool); 7061ed091c4SArnaldo Carvalho de Melo struct addr_location al; 70719d4ac3cSArnaldo Carvalho de Melo int err; 7085b2bb75aSArnaldo Carvalho de Melo 70923346f21SArnaldo Carvalho de Melo if (!machine && perf_guest) { 7106b118e92SDavid Ahern static struct intlist *seen; 7116b118e92SDavid Ahern 7126b118e92SDavid Ahern if (!seen) 713ffe0fb76SArnaldo Carvalho de Melo seen = intlist__new(NULL); 7146b118e92SDavid Ahern 715ef89325fSAdrian Hunter if (!intlist__has_entry(seen, sample->pid)) { 716a1645ce1SZhang, Yanmin pr_err("Can't find guest [%d]'s kernel information\n", 717ef89325fSAdrian Hunter sample->pid); 718ef89325fSAdrian Hunter intlist__add(seen, sample->pid); 7196b118e92SDavid Ahern } 720a1645ce1SZhang, Yanmin return; 721a1645ce1SZhang, Yanmin } 722a1645ce1SZhang, Yanmin 7230c095715SJoerg Roedel if (!machine) { 72411859e82SArnaldo Carvalho de Melo pr_err("%u unprocessable samples recorded.\r", 72575be989aSArnaldo Carvalho de Melo top->session->evlist->stats.nr_unprocessable_samples++); 7260c095715SJoerg Roedel return; 7270c095715SJoerg Roedel } 7280c095715SJoerg Roedel 7298115d60cSArnaldo Carvalho de Melo if (event->header.misc & PERF_RECORD_MISC_EXACT_IP) 7301758af10SArnaldo Carvalho de Melo top->exact_samples++; 7311676b8a0SPeter Zijlstra 732bb3eb566SArnaldo Carvalho de Melo if (machine__resolve(machine, &al, sample) < 0) 7331ed091c4SArnaldo Carvalho de Melo return; 73486470930SIngo Molnar 735e77a0742SArnaldo Carvalho de Melo if (!machine->kptr_restrict_warned && 7365f6f5580SArnaldo Carvalho de Melo symbol_conf.kptr_restrict && 7375f6f5580SArnaldo Carvalho de Melo al.cpumode == PERF_RECORD_MISC_KERNEL) { 738b89a5124SArnaldo Carvalho de Melo if (!perf_evlist__exclude_kernel(top->session->evlist)) { 7395f6f5580SArnaldo Carvalho de Melo ui__warning( 7405f6f5580SArnaldo Carvalho de Melo "Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" 7415f6f5580SArnaldo Carvalho de Melo "Check /proc/sys/kernel/kptr_restrict.\n\n" 7425f6f5580SArnaldo Carvalho de Melo "Kernel%s samples will not be resolved.\n", 743e94b861aSArnaldo Carvalho de Melo al.map && map__has_symbols(al.map) ? 7445f6f5580SArnaldo Carvalho de Melo " modules" : ""); 7455f6f5580SArnaldo Carvalho de Melo if (use_browser <= 0) 7465f6f5580SArnaldo Carvalho de Melo sleep(5); 747b89a5124SArnaldo Carvalho de Melo } 748e77a0742SArnaldo Carvalho de Melo machine->kptr_restrict_warned = true; 7495f6f5580SArnaldo Carvalho de Melo } 7505f6f5580SArnaldo Carvalho de Melo 75168766bfaSArnaldo Carvalho de Melo if (al.sym == NULL && al.map != NULL) { 752e4a338d0SArnaldo Carvalho de Melo const char *msg = "Kernel samples will not be resolved.\n"; 75372b8fa17SArnaldo Carvalho de Melo /* 75472b8fa17SArnaldo Carvalho de Melo * As we do lazy loading of symtabs we only will know if the 75572b8fa17SArnaldo Carvalho de Melo * specified vmlinux file is invalid when we actually have a 75672b8fa17SArnaldo Carvalho de Melo * hit in kernel space and then try to load it. So if we get 75772b8fa17SArnaldo Carvalho de Melo * here and there are _no_ symbols in the DSO backing the 75872b8fa17SArnaldo Carvalho de Melo * kernel map, bail out. 75972b8fa17SArnaldo Carvalho de Melo * 76072b8fa17SArnaldo Carvalho de Melo * We may never get here, for instance, if we use -K/ 76172b8fa17SArnaldo Carvalho de Melo * --hide-kernel-symbols, even if the user specifies an 76272b8fa17SArnaldo Carvalho de Melo * invalid --vmlinux ;-) 76372b8fa17SArnaldo Carvalho de Melo */ 764e77a0742SArnaldo Carvalho de Melo if (!machine->kptr_restrict_warned && !top->vmlinux_warned && 765e94b861aSArnaldo Carvalho de Melo __map__is_kernel(al.map) && map__has_symbols(al.map)) { 766e4a338d0SArnaldo Carvalho de Melo if (symbol_conf.vmlinux_name) { 76718425f13SArnaldo Carvalho de Melo char serr[256]; 76818425f13SArnaldo Carvalho de Melo dso__strerror_load(al.map->dso, serr, sizeof(serr)); 76918425f13SArnaldo Carvalho de Melo ui__warning("The %s file can't be used: %s\n%s", 77018425f13SArnaldo Carvalho de Melo symbol_conf.vmlinux_name, serr, msg); 771e4a338d0SArnaldo Carvalho de Melo } else { 772e4a338d0SArnaldo Carvalho de Melo ui__warning("A vmlinux file was not found.\n%s", 773e4a338d0SArnaldo Carvalho de Melo msg); 774e4a338d0SArnaldo Carvalho de Melo } 775e4a338d0SArnaldo Carvalho de Melo 776e4a338d0SArnaldo Carvalho de Melo if (use_browser <= 0) 777e4a338d0SArnaldo Carvalho de Melo sleep(5); 7781758af10SArnaldo Carvalho de Melo top->vmlinux_warned = true; 77972b8fa17SArnaldo Carvalho de Melo } 78072b8fa17SArnaldo Carvalho de Melo } 78172b8fa17SArnaldo Carvalho de Melo 782b55cc4edSArnaldo Carvalho de Melo if (al.sym == NULL || !al.sym->idle) { 7834ea062edSArnaldo Carvalho de Melo struct hists *hists = evsel__hists(evsel); 7847c50391fSNamhyung Kim struct hist_entry_iter iter = { 785063bd936SNamhyung Kim .evsel = evsel, 786063bd936SNamhyung Kim .sample = sample, 7877c50391fSNamhyung Kim .add_entry_cb = hist_iter__top_callback, 7887c50391fSNamhyung Kim }; 78970db7533SArnaldo Carvalho de Melo 7907c50391fSNamhyung Kim if (symbol_conf.cumulate_callchain) 7917c50391fSNamhyung Kim iter.ops = &hist_iter_cumulative; 7927c50391fSNamhyung Kim else 7937c50391fSNamhyung Kim iter.ops = &hist_iter_normal; 79419d4ac3cSArnaldo Carvalho de Melo 7954ea062edSArnaldo Carvalho de Melo pthread_mutex_lock(&hists->lock); 7967c50391fSNamhyung Kim 797063bd936SNamhyung Kim err = hist_entry_iter__add(&iter, &al, top->max_stack, top); 7987c50391fSNamhyung Kim if (err < 0) 799ab81f3fdSArnaldo Carvalho de Melo pr_err("Problem incrementing symbol period, skipping event\n"); 800ab81f3fdSArnaldo Carvalho de Melo 8014ea062edSArnaldo Carvalho de Melo pthread_mutex_unlock(&hists->lock); 8025807806aSArnaldo Carvalho de Melo } 803ab81f3fdSArnaldo Carvalho de Melo 804b91fc39fSArnaldo Carvalho de Melo addr_location__put(&al); 80586470930SIngo Molnar } 80686470930SIngo Molnar 807d24e3c98SJiri Olsa static void 808d24e3c98SJiri Olsa perf_top__process_lost(struct perf_top *top, union perf_event *event, 809d24e3c98SJiri Olsa struct perf_evsel *evsel) 810d24e3c98SJiri Olsa { 811d24e3c98SJiri Olsa struct hists *hists = evsel__hists(evsel); 812d24e3c98SJiri Olsa 813d24e3c98SJiri Olsa top->lost += event->lost.lost; 814d24e3c98SJiri Olsa top->lost_total += event->lost.lost; 815d24e3c98SJiri Olsa hists->stats.total_lost += event->lost.lost; 816d24e3c98SJiri Olsa } 817d24e3c98SJiri Olsa 818d24e3c98SJiri Olsa static void 819d24e3c98SJiri Olsa perf_top__process_lost_samples(struct perf_top *top, 820d24e3c98SJiri Olsa union perf_event *event, 821d24e3c98SJiri Olsa struct perf_evsel *evsel) 822d24e3c98SJiri Olsa { 823d24e3c98SJiri Olsa struct hists *hists = evsel__hists(evsel); 824d24e3c98SJiri Olsa 825d24e3c98SJiri Olsa top->lost += event->lost_samples.lost; 826d24e3c98SJiri Olsa top->lost_total += event->lost_samples.lost; 827d24e3c98SJiri Olsa hists->stats.total_lost_samples += event->lost_samples.lost; 828d24e3c98SJiri Olsa } 829d24e3c98SJiri Olsa 8301758af10SArnaldo Carvalho de Melo static void perf_top__mmap_read_idx(struct perf_top *top, int idx) 83186470930SIngo Molnar { 832ebebbf08SKan Liang struct record_opts *opts = &top->record_opts; 833ebebbf08SKan Liang struct perf_evlist *evlist = top->evlist; 834ebebbf08SKan Liang struct perf_mmap *md; 8358115d60cSArnaldo Carvalho de Melo union perf_event *event; 83686470930SIngo Molnar 837ebebbf08SKan Liang md = opts->overwrite ? &evlist->overwrite_mmap[idx] : &evlist->mmap[idx]; 838b9bae2c8SKan Liang if (perf_mmap__read_init(md) < 0) 839ebebbf08SKan Liang return; 840ebebbf08SKan Liang 8410019dc87SKan Liang while ((event = perf_mmap__read_event(md)) != NULL) { 84216c66bc1SJiri Olsa u64 timestamp = -1ULL; 84316c66bc1SJiri Olsa int ret; 84404391debSArnaldo Carvalho de Melo 84516c66bc1SJiri Olsa ret = perf_evlist__parse_sample_timestamp(evlist, event, ×tamp); 84616c66bc1SJiri Olsa if (ret && ret != -1) 847743eb868SArnaldo Carvalho de Melo break; 848743eb868SArnaldo Carvalho de Melo 84916c66bc1SJiri Olsa pthread_mutex_lock(&top->qe.lock); 85016c66bc1SJiri Olsa ret = ordered_events__queue(top->qe.in, event, timestamp, 0); 85116c66bc1SJiri Olsa pthread_mutex_unlock(&top->qe.lock); 852743eb868SArnaldo Carvalho de Melo 853d6ace3dfSKan Liang perf_mmap__consume(md); 85416c66bc1SJiri Olsa if (ret) 85516c66bc1SJiri Olsa break; 85686470930SIngo Molnar } 857ebebbf08SKan Liang 858ebebbf08SKan Liang perf_mmap__read_done(md); 85986470930SIngo Molnar } 86086470930SIngo Molnar 8611758af10SArnaldo Carvalho de Melo static void perf_top__mmap_read(struct perf_top *top) 8622f01190aSFrederic Weisbecker { 863ebebbf08SKan Liang bool overwrite = top->record_opts.overwrite; 864ebebbf08SKan Liang struct perf_evlist *evlist = top->evlist; 86570db7533SArnaldo Carvalho de Melo int i; 8662f01190aSFrederic Weisbecker 867ebebbf08SKan Liang if (overwrite) 868ebebbf08SKan Liang perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_DATA_PENDING); 869ebebbf08SKan Liang 8701758af10SArnaldo Carvalho de Melo for (i = 0; i < top->evlist->nr_mmaps; i++) 8711758af10SArnaldo Carvalho de Melo perf_top__mmap_read_idx(top, i); 872ebebbf08SKan Liang 873ebebbf08SKan Liang if (overwrite) { 874ebebbf08SKan Liang perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY); 875ebebbf08SKan Liang perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING); 876ebebbf08SKan Liang } 8772f01190aSFrederic Weisbecker } 8782f01190aSFrederic Weisbecker 87963878a53SKan Liang /* 88063878a53SKan Liang * Check per-event overwrite term. 88163878a53SKan Liang * perf top should support consistent term for all events. 88263878a53SKan Liang * - All events don't have per-event term 88363878a53SKan Liang * E.g. "cpu/cpu-cycles/,cpu/instructions/" 88463878a53SKan Liang * Nothing change, return 0. 88563878a53SKan Liang * - All events have same per-event term 88663878a53SKan Liang * E.g. "cpu/cpu-cycles,no-overwrite/,cpu/instructions,no-overwrite/ 88763878a53SKan Liang * Using the per-event setting to replace the opts->overwrite if 88863878a53SKan Liang * they are different, then return 0. 88963878a53SKan Liang * - Events have different per-event term 89063878a53SKan Liang * E.g. "cpu/cpu-cycles,overwrite/,cpu/instructions,no-overwrite/" 89163878a53SKan Liang * Return -1 89263878a53SKan Liang * - Some of the event set per-event term, but some not. 89363878a53SKan Liang * E.g. "cpu/cpu-cycles/,cpu/instructions,no-overwrite/" 89463878a53SKan Liang * Return -1 89563878a53SKan Liang */ 89663878a53SKan Liang static int perf_top__overwrite_check(struct perf_top *top) 89763878a53SKan Liang { 89863878a53SKan Liang struct record_opts *opts = &top->record_opts; 89963878a53SKan Liang struct perf_evlist *evlist = top->evlist; 90063878a53SKan Liang struct perf_evsel_config_term *term; 90163878a53SKan Liang struct list_head *config_terms; 90263878a53SKan Liang struct perf_evsel *evsel; 90363878a53SKan Liang int set, overwrite = -1; 90463878a53SKan Liang 90563878a53SKan Liang evlist__for_each_entry(evlist, evsel) { 90663878a53SKan Liang set = -1; 90763878a53SKan Liang config_terms = &evsel->config_terms; 90863878a53SKan Liang list_for_each_entry(term, config_terms, list) { 90963878a53SKan Liang if (term->type == PERF_EVSEL__CONFIG_TERM_OVERWRITE) 91063878a53SKan Liang set = term->val.overwrite ? 1 : 0; 91163878a53SKan Liang } 91263878a53SKan Liang 91363878a53SKan Liang /* no term for current and previous event (likely) */ 91463878a53SKan Liang if ((overwrite < 0) && (set < 0)) 91563878a53SKan Liang continue; 91663878a53SKan Liang 91763878a53SKan Liang /* has term for both current and previous event, compare */ 91863878a53SKan Liang if ((overwrite >= 0) && (set >= 0) && (overwrite != set)) 91963878a53SKan Liang return -1; 92063878a53SKan Liang 92163878a53SKan Liang /* no term for current event but has term for previous one */ 92263878a53SKan Liang if ((overwrite >= 0) && (set < 0)) 92363878a53SKan Liang return -1; 92463878a53SKan Liang 92563878a53SKan Liang /* has term for current event */ 92663878a53SKan Liang if ((overwrite < 0) && (set >= 0)) { 92763878a53SKan Liang /* if it's first event, set overwrite */ 92863878a53SKan Liang if (evsel == perf_evlist__first(evlist)) 92963878a53SKan Liang overwrite = set; 93063878a53SKan Liang else 93163878a53SKan Liang return -1; 93263878a53SKan Liang } 93363878a53SKan Liang } 93463878a53SKan Liang 93563878a53SKan Liang if ((overwrite >= 0) && (opts->overwrite != overwrite)) 93663878a53SKan Liang opts->overwrite = overwrite; 93763878a53SKan Liang 93863878a53SKan Liang return 0; 93963878a53SKan Liang } 94063878a53SKan Liang 941204721d7SKan Liang static int perf_top_overwrite_fallback(struct perf_top *top, 942204721d7SKan Liang struct perf_evsel *evsel) 943204721d7SKan Liang { 944204721d7SKan Liang struct record_opts *opts = &top->record_opts; 945204721d7SKan Liang struct perf_evlist *evlist = top->evlist; 946204721d7SKan Liang struct perf_evsel *counter; 947204721d7SKan Liang 948204721d7SKan Liang if (!opts->overwrite) 949204721d7SKan Liang return 0; 950204721d7SKan Liang 951204721d7SKan Liang /* only fall back when first event fails */ 952204721d7SKan Liang if (evsel != perf_evlist__first(evlist)) 953204721d7SKan Liang return 0; 954204721d7SKan Liang 955204721d7SKan Liang evlist__for_each_entry(evlist, counter) 956204721d7SKan Liang counter->attr.write_backward = false; 957204721d7SKan Liang opts->overwrite = false; 958853745f5SKan Liang pr_debug2("fall back to non-overwrite mode\n"); 959204721d7SKan Liang return 1; 960204721d7SKan Liang } 961204721d7SKan Liang 96211859e82SArnaldo Carvalho de Melo static int perf_top__start_counters(struct perf_top *top) 96372cb7013SArnaldo Carvalho de Melo { 964d6195a6aSArnaldo Carvalho de Melo char msg[BUFSIZ]; 9656a4bb04cSJiri Olsa struct perf_evsel *counter; 9661758af10SArnaldo Carvalho de Melo struct perf_evlist *evlist = top->evlist; 967b4006796SArnaldo Carvalho de Melo struct record_opts *opts = &top->record_opts; 968727ab04eSArnaldo Carvalho de Melo 96963878a53SKan Liang if (perf_top__overwrite_check(top)) { 97063878a53SKan Liang ui__error("perf top only support consistent per-event " 97163878a53SKan Liang "overwrite setting for all events\n"); 97263878a53SKan Liang goto out_err; 97363878a53SKan Liang } 97463878a53SKan Liang 975e68ae9cfSArnaldo Carvalho de Melo perf_evlist__config(evlist, opts, &callchain_param); 97672cb7013SArnaldo Carvalho de Melo 977e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, counter) { 97872cb7013SArnaldo Carvalho de Melo try_again: 9791758af10SArnaldo Carvalho de Melo if (perf_evsel__open(counter, top->evlist->cpus, 9806a4bb04cSJiri Olsa top->evlist->threads) < 0) { 981204721d7SKan Liang 982204721d7SKan Liang /* 983204721d7SKan Liang * Specially handle overwrite fall back. 984204721d7SKan Liang * Because perf top is the only tool which has 985204721d7SKan Liang * overwrite mode by default, support 986204721d7SKan Liang * both overwrite and non-overwrite mode, and 987204721d7SKan Liang * require consistent mode for all events. 988204721d7SKan Liang * 989204721d7SKan Liang * May move it to generic code with more tools 990204721d7SKan Liang * have similar attribute. 991204721d7SKan Liang */ 992204721d7SKan Liang if (perf_missing_features.write_backward && 993204721d7SKan Liang perf_top_overwrite_fallback(top, counter)) 994204721d7SKan Liang goto try_again; 995204721d7SKan Liang 99656e52e85SArnaldo Carvalho de Melo if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { 997bb963e16SNamhyung Kim if (verbose > 0) 998c0a54341SArnaldo Carvalho de Melo ui__warning("%s\n", msg); 99972cb7013SArnaldo Carvalho de Melo goto try_again; 100072cb7013SArnaldo Carvalho de Melo } 1001c286c419SArnaldo Carvalho de Melo 100256e52e85SArnaldo Carvalho de Melo perf_evsel__open_strerror(counter, &opts->target, 100356e52e85SArnaldo Carvalho de Melo errno, msg, sizeof(msg)); 100456e52e85SArnaldo Carvalho de Melo ui__error("%s\n", msg); 1005c286c419SArnaldo Carvalho de Melo goto out_err; 100672cb7013SArnaldo Carvalho de Melo } 100772cb7013SArnaldo Carvalho de Melo } 100870db7533SArnaldo Carvalho de Melo 1009f74b9d3aSWang Nan if (perf_evlist__mmap(evlist, opts->mmap_pages) < 0) { 10103780f488SNamhyung Kim ui__error("Failed to mmap with %d (%s)\n", 1011c8b5f2c9SArnaldo Carvalho de Melo errno, str_error_r(errno, msg, sizeof(msg))); 1012c286c419SArnaldo Carvalho de Melo goto out_err; 1013c286c419SArnaldo Carvalho de Melo } 1014c286c419SArnaldo Carvalho de Melo 101511859e82SArnaldo Carvalho de Melo return 0; 1016c286c419SArnaldo Carvalho de Melo 1017c286c419SArnaldo Carvalho de Melo out_err: 101811859e82SArnaldo Carvalho de Melo return -1; 101972cb7013SArnaldo Carvalho de Melo } 102072cb7013SArnaldo Carvalho de Melo 1021e3815264SArnaldo Carvalho de Melo static int callchain_param__setup_sample_type(struct callchain_param *callchain) 102219d4ac3cSArnaldo Carvalho de Melo { 10232e0453afSJiri Olsa if (!perf_hpp_list.sym) { 1024e3815264SArnaldo Carvalho de Melo if (callchain->enabled) { 10253780f488SNamhyung Kim ui__error("Selected -g but \"sym\" not present in --sort/-s."); 102619d4ac3cSArnaldo Carvalho de Melo return -EINVAL; 102719d4ac3cSArnaldo Carvalho de Melo } 1028e3815264SArnaldo Carvalho de Melo } else if (callchain->mode != CHAIN_NONE) { 1029e3815264SArnaldo Carvalho de Melo if (callchain_register_param(callchain) < 0) { 10303780f488SNamhyung Kim ui__error("Can't register callchain params.\n"); 103119d4ac3cSArnaldo Carvalho de Melo return -EINVAL; 103219d4ac3cSArnaldo Carvalho de Melo } 103319d4ac3cSArnaldo Carvalho de Melo } 103419d4ac3cSArnaldo Carvalho de Melo 103519d4ac3cSArnaldo Carvalho de Melo return 0; 103619d4ac3cSArnaldo Carvalho de Melo } 103719d4ac3cSArnaldo Carvalho de Melo 103816c66bc1SJiri Olsa static struct ordered_events *rotate_queues(struct perf_top *top) 103916c66bc1SJiri Olsa { 104016c66bc1SJiri Olsa struct ordered_events *in = top->qe.in; 104116c66bc1SJiri Olsa 104216c66bc1SJiri Olsa if (top->qe.in == &top->qe.data[1]) 104316c66bc1SJiri Olsa top->qe.in = &top->qe.data[0]; 104416c66bc1SJiri Olsa else 104516c66bc1SJiri Olsa top->qe.in = &top->qe.data[1]; 104616c66bc1SJiri Olsa 104716c66bc1SJiri Olsa return in; 104816c66bc1SJiri Olsa } 104916c66bc1SJiri Olsa 105016c66bc1SJiri Olsa static void *process_thread(void *arg) 105116c66bc1SJiri Olsa { 105216c66bc1SJiri Olsa struct perf_top *top = arg; 105316c66bc1SJiri Olsa 105416c66bc1SJiri Olsa while (!done) { 105516c66bc1SJiri Olsa struct ordered_events *out, *in = top->qe.in; 105616c66bc1SJiri Olsa 105716c66bc1SJiri Olsa if (!in->nr_events) { 105816c66bc1SJiri Olsa usleep(100); 105916c66bc1SJiri Olsa continue; 106016c66bc1SJiri Olsa } 106116c66bc1SJiri Olsa 106216c66bc1SJiri Olsa pthread_mutex_lock(&top->qe.lock); 106316c66bc1SJiri Olsa out = rotate_queues(top); 106416c66bc1SJiri Olsa pthread_mutex_unlock(&top->qe.lock); 106516c66bc1SJiri Olsa 106616c66bc1SJiri Olsa if (ordered_events__flush(out, OE_FLUSH__TOP)) 106716c66bc1SJiri Olsa pr_err("failed to process events\n"); 106816c66bc1SJiri Olsa } 106916c66bc1SJiri Olsa 107016c66bc1SJiri Olsa return NULL; 107116c66bc1SJiri Olsa } 107216c66bc1SJiri Olsa 107316c66bc1SJiri Olsa static int deliver_event(struct ordered_events *qe, 107416c66bc1SJiri Olsa struct ordered_event *qevent) 107516c66bc1SJiri Olsa { 107616c66bc1SJiri Olsa struct perf_top *top = qe->data; 107716c66bc1SJiri Olsa struct perf_evlist *evlist = top->evlist; 107816c66bc1SJiri Olsa struct perf_session *session = top->session; 107916c66bc1SJiri Olsa union perf_event *event = qevent->event; 108016c66bc1SJiri Olsa struct perf_sample sample; 108116c66bc1SJiri Olsa struct perf_evsel *evsel; 108216c66bc1SJiri Olsa struct machine *machine; 108316c66bc1SJiri Olsa int ret = -1; 108416c66bc1SJiri Olsa 108516c66bc1SJiri Olsa ret = perf_evlist__parse_sample(evlist, event, &sample); 108616c66bc1SJiri Olsa if (ret) { 108716c66bc1SJiri Olsa pr_err("Can't parse sample, err = %d\n", ret); 108816c66bc1SJiri Olsa goto next_event; 108916c66bc1SJiri Olsa } 109016c66bc1SJiri Olsa 109116c66bc1SJiri Olsa evsel = perf_evlist__id2evsel(session->evlist, sample.id); 109216c66bc1SJiri Olsa assert(evsel != NULL); 109316c66bc1SJiri Olsa 109416c66bc1SJiri Olsa if (event->header.type == PERF_RECORD_SAMPLE) 109516c66bc1SJiri Olsa ++top->samples; 109616c66bc1SJiri Olsa 109716c66bc1SJiri Olsa switch (sample.cpumode) { 109816c66bc1SJiri Olsa case PERF_RECORD_MISC_USER: 109916c66bc1SJiri Olsa ++top->us_samples; 110016c66bc1SJiri Olsa if (top->hide_user_symbols) 110116c66bc1SJiri Olsa goto next_event; 110216c66bc1SJiri Olsa machine = &session->machines.host; 110316c66bc1SJiri Olsa break; 110416c66bc1SJiri Olsa case PERF_RECORD_MISC_KERNEL: 110516c66bc1SJiri Olsa ++top->kernel_samples; 110616c66bc1SJiri Olsa if (top->hide_kernel_symbols) 110716c66bc1SJiri Olsa goto next_event; 110816c66bc1SJiri Olsa machine = &session->machines.host; 110916c66bc1SJiri Olsa break; 111016c66bc1SJiri Olsa case PERF_RECORD_MISC_GUEST_KERNEL: 111116c66bc1SJiri Olsa ++top->guest_kernel_samples; 111216c66bc1SJiri Olsa machine = perf_session__find_machine(session, 111316c66bc1SJiri Olsa sample.pid); 111416c66bc1SJiri Olsa break; 111516c66bc1SJiri Olsa case PERF_RECORD_MISC_GUEST_USER: 111616c66bc1SJiri Olsa ++top->guest_us_samples; 111716c66bc1SJiri Olsa /* 111816c66bc1SJiri Olsa * TODO: we don't process guest user from host side 111916c66bc1SJiri Olsa * except simple counting. 112016c66bc1SJiri Olsa */ 112116c66bc1SJiri Olsa goto next_event; 112216c66bc1SJiri Olsa default: 112316c66bc1SJiri Olsa if (event->header.type == PERF_RECORD_SAMPLE) 112416c66bc1SJiri Olsa goto next_event; 112516c66bc1SJiri Olsa machine = &session->machines.host; 112616c66bc1SJiri Olsa break; 112716c66bc1SJiri Olsa } 112816c66bc1SJiri Olsa 112916c66bc1SJiri Olsa if (event->header.type == PERF_RECORD_SAMPLE) { 113016c66bc1SJiri Olsa perf_event__process_sample(&top->tool, event, evsel, 113116c66bc1SJiri Olsa &sample, machine); 113216c66bc1SJiri Olsa } else if (event->header.type == PERF_RECORD_LOST) { 113316c66bc1SJiri Olsa perf_top__process_lost(top, event, evsel); 113416c66bc1SJiri Olsa } else if (event->header.type == PERF_RECORD_LOST_SAMPLES) { 113516c66bc1SJiri Olsa perf_top__process_lost_samples(top, event, evsel); 113616c66bc1SJiri Olsa } else if (event->header.type < PERF_RECORD_MAX) { 113716c66bc1SJiri Olsa hists__inc_nr_events(evsel__hists(evsel), event->header.type); 113816c66bc1SJiri Olsa machine__process_event(machine, event, &sample); 113916c66bc1SJiri Olsa } else 114016c66bc1SJiri Olsa ++session->evlist->stats.nr_unknown_events; 114116c66bc1SJiri Olsa 114216c66bc1SJiri Olsa ret = 0; 114316c66bc1SJiri Olsa next_event: 114416c66bc1SJiri Olsa return ret; 114516c66bc1SJiri Olsa } 114616c66bc1SJiri Olsa 114716c66bc1SJiri Olsa static void init_process_thread(struct perf_top *top) 114816c66bc1SJiri Olsa { 114916c66bc1SJiri Olsa ordered_events__init(&top->qe.data[0], deliver_event, top); 115016c66bc1SJiri Olsa ordered_events__init(&top->qe.data[1], deliver_event, top); 115116c66bc1SJiri Olsa ordered_events__set_copy_on_queue(&top->qe.data[0], true); 115216c66bc1SJiri Olsa ordered_events__set_copy_on_queue(&top->qe.data[1], true); 115316c66bc1SJiri Olsa top->qe.in = &top->qe.data[0]; 115416c66bc1SJiri Olsa pthread_mutex_init(&top->qe.lock, NULL); 115516c66bc1SJiri Olsa } 115616c66bc1SJiri Olsa 11571758af10SArnaldo Carvalho de Melo static int __cmd_top(struct perf_top *top) 1158716c69feSIngo Molnar { 11595d8bb1ecSMathieu Poirier char msg[512]; 11605d8bb1ecSMathieu Poirier struct perf_evsel *pos; 11615d8bb1ecSMathieu Poirier struct perf_evsel_config_term *err_term; 11625d8bb1ecSMathieu Poirier struct perf_evlist *evlist = top->evlist; 1163b4006796SArnaldo Carvalho de Melo struct record_opts *opts = &top->record_opts; 116416c66bc1SJiri Olsa pthread_t thread, thread_process; 116519d4ac3cSArnaldo Carvalho de Melo int ret; 1166f5fc1412SJiri Olsa 11676a4d98d7SJiri Olsa top->session = perf_session__new(NULL, false, NULL); 11681758af10SArnaldo Carvalho de Melo if (top->session == NULL) 116952e02834STaeung Song return -1; 1170716c69feSIngo Molnar 1171f178fd2dSArnaldo Carvalho de Melo if (!top->annotation_opts.objdump_path) { 1172f178fd2dSArnaldo Carvalho de Melo ret = perf_env__lookup_objdump(&top->session->header.env, 1173f178fd2dSArnaldo Carvalho de Melo &top->annotation_opts.objdump_path); 11740d3942dbSSukadev Bhattiprolu if (ret) 11750d3942dbSSukadev Bhattiprolu goto out_delete; 11760d3942dbSSukadev Bhattiprolu } 11770d3942dbSSukadev Bhattiprolu 1178e3815264SArnaldo Carvalho de Melo ret = callchain_param__setup_sample_type(&callchain_param); 117919d4ac3cSArnaldo Carvalho de Melo if (ret) 118019d4ac3cSArnaldo Carvalho de Melo goto out_delete; 118119d4ac3cSArnaldo Carvalho de Melo 11829d8b172fSMasami Hiramatsu if (perf_session__register_idle_thread(top->session) < 0) 1183c53d138dSNamhyung Kim goto out_delete; 1184c53d138dSNamhyung Kim 11850c6b4994SKan Liang if (top->nr_threads_synthesize > 1) 1186340b47f5SKan Liang perf_set_multithreaded(); 1187340b47f5SKan Liang 118816c66bc1SJiri Olsa init_process_thread(top); 118916c66bc1SJiri Olsa 1190a33fbd56SArnaldo Carvalho de Melo machine__synthesize_threads(&top->session->machines.host, &opts->target, 1191340b47f5SKan Liang top->evlist->threads, false, 11920c6b4994SKan Liang top->nr_threads_synthesize); 1193340b47f5SKan Liang 11940c6b4994SKan Liang if (top->nr_threads_synthesize > 1) 1195340b47f5SKan Liang perf_set_singlethreaded(); 11962e7ea3abSKan Liang 119735a634f7SJiri Olsa if (perf_hpp_list.socket) { 11982e7ea3abSKan Liang ret = perf_env__read_cpu_topology_map(&perf_env); 11992e7ea3abSKan Liang if (ret < 0) 12002e7ea3abSKan Liang goto out_err_cpu_topo; 12012e7ea3abSKan Liang } 12022e7ea3abSKan Liang 120311859e82SArnaldo Carvalho de Melo ret = perf_top__start_counters(top); 120411859e82SArnaldo Carvalho de Melo if (ret) 120511859e82SArnaldo Carvalho de Melo goto out_delete; 120611859e82SArnaldo Carvalho de Melo 12075d8bb1ecSMathieu Poirier ret = perf_evlist__apply_drv_configs(evlist, &pos, &err_term); 12085d8bb1ecSMathieu Poirier if (ret) { 120962d94b00SArnaldo Carvalho de Melo pr_err("failed to set config \"%s\" on event %s with %d (%s)\n", 12105d8bb1ecSMathieu Poirier err_term->val.drv_cfg, perf_evsel__name(pos), errno, 12115d8bb1ecSMathieu Poirier str_error_r(errno, msg, sizeof(msg))); 12125d8bb1ecSMathieu Poirier goto out_delete; 12135d8bb1ecSMathieu Poirier } 12145d8bb1ecSMathieu Poirier 12151758af10SArnaldo Carvalho de Melo top->session->evlist = top->evlist; 12167b56cce2SArnaldo Carvalho de Melo perf_session__set_id_hdr_size(top->session); 121786470930SIngo Molnar 12182376c67aSArnaldo Carvalho de Melo /* 12192376c67aSArnaldo Carvalho de Melo * When perf is starting the traced process, all the events (apart from 12202376c67aSArnaldo Carvalho de Melo * group members) have enable_on_exec=1 set, so don't spoil it by 12212376c67aSArnaldo Carvalho de Melo * prematurely enabling them. 12222376c67aSArnaldo Carvalho de Melo * 12232376c67aSArnaldo Carvalho de Melo * XXX 'top' still doesn't start workloads like record, trace, but should, 12242376c67aSArnaldo Carvalho de Melo * so leave the check here. 12252376c67aSArnaldo Carvalho de Melo */ 1226602ad878SArnaldo Carvalho de Melo if (!target__none(&opts->target)) 12272376c67aSArnaldo Carvalho de Melo perf_evlist__enable(top->evlist); 12282376c67aSArnaldo Carvalho de Melo 122911859e82SArnaldo Carvalho de Melo ret = -1; 123016c66bc1SJiri Olsa if (pthread_create(&thread_process, NULL, process_thread, top)) { 123116c66bc1SJiri Olsa ui__error("Could not create process thread.\n"); 123216c66bc1SJiri Olsa goto out_delete; 123316c66bc1SJiri Olsa } 123416c66bc1SJiri Olsa 1235c0443df1SArnaldo Carvalho de Melo if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui : 12361758af10SArnaldo Carvalho de Melo display_thread), top)) { 12373780f488SNamhyung Kim ui__error("Could not create display thread.\n"); 123816c66bc1SJiri Olsa goto out_join_thread; 123986470930SIngo Molnar } 124086470930SIngo Molnar 12411758af10SArnaldo Carvalho de Melo if (top->realtime_prio) { 124286470930SIngo Molnar struct sched_param param; 124386470930SIngo Molnar 12441758af10SArnaldo Carvalho de Melo param.sched_priority = top->realtime_prio; 124586470930SIngo Molnar if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { 12463780f488SNamhyung Kim ui__error("Could not set realtime priority.\n"); 1247ae256fa2SJiri Olsa goto out_join; 124886470930SIngo Molnar } 124986470930SIngo Molnar } 125086470930SIngo Molnar 1251ff27a06aSDavid Miller /* Wait for a minimal set of events before starting the snapshot */ 1252ff27a06aSDavid Miller perf_evlist__poll(top->evlist, 100); 1253ff27a06aSDavid Miller 1254ff27a06aSDavid Miller perf_top__mmap_read(top); 1255ff27a06aSDavid Miller 125611859e82SArnaldo Carvalho de Melo while (!done) { 12571758af10SArnaldo Carvalho de Melo u64 hits = top->samples; 125886470930SIngo Molnar 12591758af10SArnaldo Carvalho de Melo perf_top__mmap_read(top); 126086470930SIngo Molnar 1261ebebbf08SKan Liang if (opts->overwrite || (hits == top->samples)) 1262f66a889dSArnaldo Carvalho de Melo ret = perf_evlist__poll(top->evlist, 100); 1263b135e5eeSJiri Olsa 1264b135e5eeSJiri Olsa if (resize) { 1265b135e5eeSJiri Olsa perf_top__resize(top); 1266b135e5eeSJiri Olsa resize = 0; 1267b135e5eeSJiri Olsa } 126886470930SIngo Molnar } 126986470930SIngo Molnar 127011859e82SArnaldo Carvalho de Melo ret = 0; 1271ae256fa2SJiri Olsa out_join: 1272ae256fa2SJiri Olsa pthread_join(thread, NULL); 127316c66bc1SJiri Olsa out_join_thread: 127416c66bc1SJiri Olsa pthread_join(thread_process, NULL); 127519d4ac3cSArnaldo Carvalho de Melo out_delete: 12761758af10SArnaldo Carvalho de Melo perf_session__delete(top->session); 12771758af10SArnaldo Carvalho de Melo top->session = NULL; 127819d4ac3cSArnaldo Carvalho de Melo 127911859e82SArnaldo Carvalho de Melo return ret; 12802e7ea3abSKan Liang 12812e7ea3abSKan Liang out_err_cpu_topo: { 12822e7ea3abSKan Liang char errbuf[BUFSIZ]; 1283c8b5f2c9SArnaldo Carvalho de Melo const char *err = str_error_r(-ret, errbuf, sizeof(errbuf)); 12842e7ea3abSKan Liang 12852e7ea3abSKan Liang ui__error("Could not read the CPU topology map: %s\n", err); 12862e7ea3abSKan Liang goto out_delete; 12872e7ea3abSKan Liang } 128819d4ac3cSArnaldo Carvalho de Melo } 128919d4ac3cSArnaldo Carvalho de Melo 129019d4ac3cSArnaldo Carvalho de Melo static int 1291ae779a63SJiri Olsa callchain_opt(const struct option *opt, const char *arg, int unset) 1292ae779a63SJiri Olsa { 1293ae779a63SJiri Olsa symbol_conf.use_callchain = true; 1294ae779a63SJiri Olsa return record_callchain_opt(opt, arg, unset); 1295ae779a63SJiri Olsa } 1296ae779a63SJiri Olsa 1297ae779a63SJiri Olsa static int 12981758af10SArnaldo Carvalho de Melo parse_callchain_opt(const struct option *opt, const char *arg, int unset) 129919d4ac3cSArnaldo Carvalho de Melo { 13002ddd5c04SArnaldo Carvalho de Melo struct callchain_param *callchain = opt->value; 1301a2c10d39SNamhyung Kim 13022ddd5c04SArnaldo Carvalho de Melo callchain->enabled = !unset; 13032ddd5c04SArnaldo Carvalho de Melo callchain->record_mode = CALLCHAIN_FP; 1304a2c10d39SNamhyung Kim 1305a2c10d39SNamhyung Kim /* 1306a2c10d39SNamhyung Kim * --no-call-graph 1307a2c10d39SNamhyung Kim */ 1308a2c10d39SNamhyung Kim if (unset) { 1309a2c10d39SNamhyung Kim symbol_conf.use_callchain = false; 13102ddd5c04SArnaldo Carvalho de Melo callchain->record_mode = CALLCHAIN_NONE; 1311a2c10d39SNamhyung Kim return 0; 1312a2c10d39SNamhyung Kim } 1313a2c10d39SNamhyung Kim 1314a2c10d39SNamhyung Kim return parse_callchain_top_opt(arg); 131586470930SIngo Molnar } 131686470930SIngo Molnar 1317b8cbb349SWang Nan static int perf_top_config(const char *var, const char *value, void *cb __maybe_unused) 1318eb853e80SJiri Olsa { 1319a3a4a3b3SYisheng Xie if (!strcmp(var, "top.call-graph")) { 1320a3a4a3b3SYisheng Xie var = "call-graph.record-mode"; 1321a3a4a3b3SYisheng Xie return perf_default_config(var, value, cb); 1322a3a4a3b3SYisheng Xie } 1323104ac991SNamhyung Kim if (!strcmp(var, "top.children")) { 1324104ac991SNamhyung Kim symbol_conf.cumulate_callchain = perf_config_bool(var, value); 1325104ac991SNamhyung Kim return 0; 1326104ac991SNamhyung Kim } 1327eb853e80SJiri Olsa 1328b8cbb349SWang Nan return 0; 1329eb853e80SJiri Olsa } 1330eb853e80SJiri Olsa 1331fa5df943SNamhyung Kim static int 1332fa5df943SNamhyung Kim parse_percent_limit(const struct option *opt, const char *arg, 1333fa5df943SNamhyung Kim int unset __maybe_unused) 1334fa5df943SNamhyung Kim { 1335fa5df943SNamhyung Kim struct perf_top *top = opt->value; 1336fa5df943SNamhyung Kim 1337fa5df943SNamhyung Kim top->min_percent = strtof(arg, NULL); 1338fa5df943SNamhyung Kim return 0; 1339fa5df943SNamhyung Kim } 1340fa5df943SNamhyung Kim 134176a26549SNamhyung Kim const char top_callchain_help[] = CALLCHAIN_RECORD_HELP CALLCHAIN_REPORT_HELP 134276a26549SNamhyung Kim "\n\t\t\t\tDefault: fp,graph,0.5,caller,function"; 1343a2c10d39SNamhyung Kim 1344b0ad8ea6SArnaldo Carvalho de Melo int cmd_top(int argc, const char **argv) 13451758af10SArnaldo Carvalho de Melo { 134616ad2ffbSNamhyung Kim char errbuf[BUFSIZ]; 13471758af10SArnaldo Carvalho de Melo struct perf_top top = { 13481758af10SArnaldo Carvalho de Melo .count_filter = 5, 13491758af10SArnaldo Carvalho de Melo .delay_secs = 2, 13502376c67aSArnaldo Carvalho de Melo .record_opts = { 13512376c67aSArnaldo Carvalho de Melo .mmap_pages = UINT_MAX, 13522376c67aSArnaldo Carvalho de Melo .user_freq = UINT_MAX, 13532376c67aSArnaldo Carvalho de Melo .user_interval = ULLONG_MAX, 1354447a6013SArnaldo Carvalho de Melo .freq = 4000, /* 4 KHz */ 1355d1cb9fceSNamhyung Kim .target = { 1356d1cb9fceSNamhyung Kim .uses_mmap = true, 1357d1cb9fceSNamhyung Kim }, 1358218d6111SArnaldo Carvalho de Melo /* 1359218d6111SArnaldo Carvalho de Melo * FIXME: This will lose PERF_RECORD_MMAP and other metadata 1360218d6111SArnaldo Carvalho de Melo * when we pause, fix that and reenable. Probably using a 1361218d6111SArnaldo Carvalho de Melo * separate evlist with a dummy event, i.e. a non-overwrite 1362218d6111SArnaldo Carvalho de Melo * ring buffer just for metadata events, while PERF_RECORD_SAMPLE 1363218d6111SArnaldo Carvalho de Melo * stays in overwrite mode. -acme 1364218d6111SArnaldo Carvalho de Melo * */ 1365218d6111SArnaldo Carvalho de Melo .overwrite = 0, 136616c66bc1SJiri Olsa .sample_time = true, 13672376c67aSArnaldo Carvalho de Melo }, 1368029c75e5SArnaldo Carvalho de Melo .max_stack = sysctl__max_stack(), 1369982d410bSArnaldo Carvalho de Melo .annotation_opts = annotation__default_options, 13700c6b4994SKan Liang .nr_threads_synthesize = UINT_MAX, 13711758af10SArnaldo Carvalho de Melo }; 1372b4006796SArnaldo Carvalho de Melo struct record_opts *opts = &top.record_opts; 1373602ad878SArnaldo Carvalho de Melo struct target *target = &opts->target; 13741758af10SArnaldo Carvalho de Melo const struct option options[] = { 13758c3e10ebSArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &top.evlist, "event", 137686470930SIngo Molnar "event selector. use 'perf list' to list available events", 1377f120f9d5SJiri Olsa parse_events_option), 13782376c67aSArnaldo Carvalho de Melo OPT_U64('c', "count", &opts->user_interval, "event period to sample"), 13792376c67aSArnaldo Carvalho de Melo OPT_STRING('p', "pid", &target->pid, "pid", 1380d6d901c2SZhang, Yanmin "profile events on existing process id"), 13812376c67aSArnaldo Carvalho de Melo OPT_STRING('t', "tid", &target->tid, "tid", 1382d6d901c2SZhang, Yanmin "profile events on existing thread id"), 13832376c67aSArnaldo Carvalho de Melo OPT_BOOLEAN('a', "all-cpus", &target->system_wide, 138486470930SIngo Molnar "system-wide collection from all CPUs"), 13852376c67aSArnaldo Carvalho de Melo OPT_STRING('C', "cpu", &target->cpu_list, "cpu", 1386c45c6ea2SStephane Eranian "list of cpus to monitor"), 1387b32d133aSArnaldo Carvalho de Melo OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 1388b32d133aSArnaldo Carvalho de Melo "file", "vmlinux pathname"), 1389fc2be696SWilly Tarreau OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux, 1390fc2be696SWilly Tarreau "don't load vmlinux even if found"), 13911b3aae90SArnaldo Carvalho de Melo OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, 13921b3aae90SArnaldo Carvalho de Melo "file", "kallsyms pathname"), 13938c3e10ebSArnaldo Carvalho de Melo OPT_BOOLEAN('K', "hide_kernel_symbols", &top.hide_kernel_symbols, 13948ffcda17SArnaldo Carvalho de Melo "hide kernel symbols"), 1395994a1f78SJiri Olsa OPT_CALLBACK('m', "mmap-pages", &opts->mmap_pages, "pages", 1396994a1f78SJiri Olsa "number of mmap data pages", 1397994a1f78SJiri Olsa perf_evlist__parse_mmap_pages), 13981758af10SArnaldo Carvalho de Melo OPT_INTEGER('r', "realtime", &top.realtime_prio, 139986470930SIngo Molnar "collect data with this RT SCHED_FIFO priority"), 14008c3e10ebSArnaldo Carvalho de Melo OPT_INTEGER('d', "delay", &top.delay_secs, 140186470930SIngo Molnar "number of seconds to delay between refreshes"), 14021758af10SArnaldo Carvalho de Melo OPT_BOOLEAN('D', "dump-symtab", &top.dump_symtab, 140386470930SIngo Molnar "dump the symbol table used for profiling"), 14048c3e10ebSArnaldo Carvalho de Melo OPT_INTEGER('f', "count-filter", &top.count_filter, 140586470930SIngo Molnar "only display functions with more events than this"), 1406bf80669eSDavid Ahern OPT_BOOLEAN(0, "group", &opts->group, 140786470930SIngo Molnar "put the counters into a counter group"), 14082376c67aSArnaldo Carvalho de Melo OPT_BOOLEAN('i', "no-inherit", &opts->no_inherit, 14092376c67aSArnaldo Carvalho de Melo "child tasks do not inherit counters"), 14101758af10SArnaldo Carvalho de Melo OPT_STRING(0, "sym-annotate", &top.sym_filter, "symbol name", 14116cff0e8dSKirill Smelkov "symbol to annotate"), 14122376c67aSArnaldo Carvalho de Melo OPT_BOOLEAN('z', "zero", &top.zero, "zero history across updates"), 14137831bf23SArnaldo Carvalho de Melo OPT_CALLBACK('F', "freq", &top.record_opts, "freq or 'max'", 14147831bf23SArnaldo Carvalho de Melo "profile at this frequency", 14157831bf23SArnaldo Carvalho de Melo record__parse_freq), 14168c3e10ebSArnaldo Carvalho de Melo OPT_INTEGER('E', "entries", &top.print_entries, 141786470930SIngo Molnar "display this many functions"), 14188c3e10ebSArnaldo Carvalho de Melo OPT_BOOLEAN('U', "hide_user_symbols", &top.hide_user_symbols, 14198ffcda17SArnaldo Carvalho de Melo "hide user symbols"), 14201758af10SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "tui", &top.use_tui, "Use the TUI interface"), 14211758af10SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "stdio", &top.use_stdio, "Use the stdio interface"), 1422c0555642SIan Munsie OPT_INCR('v', "verbose", &verbose, 14233da297a6SIngo Molnar "be more verbose (show counter open errors, etc)"), 1424ab81f3fdSArnaldo Carvalho de Melo OPT_STRING('s', "sort", &sort_order, "key[,key2...]", 1425a2ce067eSNamhyung Kim "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." 1426a2ce067eSNamhyung Kim " Please refer the man page for the complete list."), 14276fe8c26dSNamhyung Kim OPT_STRING(0, "fields", &field_order, "key[,keys...]", 14286fe8c26dSNamhyung Kim "output field(s): overhead, period, sample plus all of sort keys"), 1429ab81f3fdSArnaldo Carvalho de Melo OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, 1430ab81f3fdSArnaldo Carvalho de Melo "Show a column with the number of samples"), 14312ddd5c04SArnaldo Carvalho de Melo OPT_CALLBACK_NOOPT('g', NULL, &callchain_param, 1432a2c10d39SNamhyung Kim NULL, "enables call-graph recording and display", 1433ae779a63SJiri Olsa &callchain_opt), 14342ddd5c04SArnaldo Carvalho de Melo OPT_CALLBACK(0, "call-graph", &callchain_param, 143576a26549SNamhyung Kim "record_mode[,record_size],print_type,threshold[,print_limit],order,sort_key[,branch]", 1436a2c10d39SNamhyung Kim top_callchain_help, &parse_callchain_opt), 14371432ec34SNamhyung Kim OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain, 14381432ec34SNamhyung Kim "Accumulate callchains of children and show total overhead as well"), 14395dbb6e81SWaiman Long OPT_INTEGER(0, "max-stack", &top.max_stack, 14405dbb6e81SWaiman Long "Set the maximum stack depth when parsing the callchain. " 14414cb93446SArnaldo Carvalho de Melo "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)), 1442b21484f1SGreg Price OPT_CALLBACK(0, "ignore-callees", NULL, "regex", 1443b21484f1SGreg Price "ignore callees of these functions in call graphs", 1444b21484f1SGreg Price report_parse_ignore_callees_opt), 1445ab81f3fdSArnaldo Carvalho de Melo OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, 1446ab81f3fdSArnaldo Carvalho de Melo "Show a column with the sum of periods"), 1447ab81f3fdSArnaldo Carvalho de Melo OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", 1448ab81f3fdSArnaldo Carvalho de Melo "only consider symbols in these dsos"), 1449ab81f3fdSArnaldo Carvalho de Melo OPT_STRING(0, "comms", &symbol_conf.comm_list_str, "comm[,comm...]", 1450ab81f3fdSArnaldo Carvalho de Melo "only consider symbols in these comms"), 1451ab81f3fdSArnaldo Carvalho de Melo OPT_STRING(0, "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", 1452ab81f3fdSArnaldo Carvalho de Melo "only consider these symbols"), 14531eddd9e4SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "source", &top.annotation_opts.annotate_src, 145464c6f0c7SArnaldo Carvalho de Melo "Interleave source code with assembly code (default)"), 14551eddd9e4SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "asm-raw", &top.annotation_opts.show_asm_raw, 145664c6f0c7SArnaldo Carvalho de Melo "Display raw encoding of assembly instructions (default)"), 1457763122adSAvi Kivity OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, 1458763122adSAvi Kivity "Enable kernel symbol demangling"), 1459f178fd2dSArnaldo Carvalho de Melo OPT_STRING(0, "objdump", &top.annotation_opts.objdump_path, "path", 14600d3942dbSSukadev Bhattiprolu "objdump binary to use for disassembly and annotations"), 1461a47e843eSArnaldo Carvalho de Melo OPT_STRING('M', "disassembler-style", &top.annotation_opts.disassembler_style, "disassembler style", 146264c6f0c7SArnaldo Carvalho de Melo "Specify disassembler style (e.g. -M intel for intel syntax)"), 14632376c67aSArnaldo Carvalho de Melo OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"), 1464fa5df943SNamhyung Kim OPT_CALLBACK(0, "percent-limit", &top, "percent", 1465fa5df943SNamhyung Kim "Don't show entries under that percent", parse_percent_limit), 146633db4568SNamhyung Kim OPT_CALLBACK(0, "percentage", NULL, "relative|absolute", 146733db4568SNamhyung Kim "How to display percentage of filtered entries", parse_filter_percentage), 1468cf59002fSNamhyung Kim OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str, 1469cf59002fSNamhyung Kim "width[,width...]", 1470cf59002fSNamhyung Kim "don't try to adjust column width, use these fixed values"), 14713fcb10e4SMark Drayton OPT_UINTEGER(0, "proc-map-timeout", &proc_map_timeout, 14729d9cad76SKan Liang "per thread proc mmap processing timeout in ms"), 1473a18b027eSAndi Kleen OPT_CALLBACK_NOOPT('b', "branch-any", &opts->branch_stack, 1474a18b027eSAndi Kleen "branch any", "sample any taken branches", 1475a18b027eSAndi Kleen parse_branch_stack), 1476a18b027eSAndi Kleen OPT_CALLBACK('j', "branch-filter", &opts->branch_stack, 1477a18b027eSAndi Kleen "branch filter mask", "branch stack filter modes", 1478a18b027eSAndi Kleen parse_branch_stack), 1479053a3989SNamhyung Kim OPT_BOOLEAN(0, "raw-trace", &symbol_conf.raw_trace, 1480053a3989SNamhyung Kim "Show raw trace event output (do not use print fmt or plugins)"), 1481c92fcfdeSNamhyung Kim OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy, 1482c92fcfdeSNamhyung Kim "Show entries in a hierarchy"), 14834e303fbeSArnaldo Carvalho de Melo OPT_BOOLEAN(0, "overwrite", &top.record_opts.overwrite, 1484218d6111SArnaldo Carvalho de Melo "Use a backward ring buffer, default: no"), 1485868a8329SKrister Johansen OPT_BOOLEAN(0, "force", &symbol_conf.force, "don't complain, do it"), 14860c6b4994SKan Liang OPT_UINTEGER(0, "num-thread-synthesize", &top.nr_threads_synthesize, 14870c6b4994SKan Liang "number of thread to run event synthesize"), 148886470930SIngo Molnar OPT_END() 148986470930SIngo Molnar }; 1490be772842SArnaldo Carvalho de Melo const char * const top_usage[] = { 1491be772842SArnaldo Carvalho de Melo "perf top [<options>]", 1492be772842SArnaldo Carvalho de Melo NULL 1493be772842SArnaldo Carvalho de Melo }; 1494a635fc51SArnaldo Carvalho de Melo int status = hists__init(); 1495a635fc51SArnaldo Carvalho de Melo 1496a635fc51SArnaldo Carvalho de Melo if (status < 0) 1497a635fc51SArnaldo Carvalho de Melo return status; 149886470930SIngo Molnar 1499982d410bSArnaldo Carvalho de Melo top.annotation_opts.min_pcnt = 5; 1500982d410bSArnaldo Carvalho de Melo top.annotation_opts.context = 4; 1501982d410bSArnaldo Carvalho de Melo 1502334fe7a3SNamhyung Kim top.evlist = perf_evlist__new(); 15038c3e10ebSArnaldo Carvalho de Melo if (top.evlist == NULL) 1504361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 1505361c99a6SArnaldo Carvalho de Melo 1506ecc4c561SArnaldo Carvalho de Melo status = perf_config(perf_top_config, &top); 1507ecc4c561SArnaldo Carvalho de Melo if (status) 1508ecc4c561SArnaldo Carvalho de Melo return status; 1509eb853e80SJiri Olsa 151086470930SIngo Molnar argc = parse_options(argc, argv, options, top_usage, 0); 151186470930SIngo Molnar if (argc) 151286470930SIngo Molnar usage_with_options(top_usage, options); 151386470930SIngo Molnar 151454f8f403SNamhyung Kim if (!top.evlist->nr_entries && 151554f8f403SNamhyung Kim perf_evlist__add_default(top.evlist) < 0) { 151654f8f403SNamhyung Kim pr_err("Not enough memory for event selector list\n"); 151754f8f403SNamhyung Kim goto out_delete_evlist; 151854f8f403SNamhyung Kim } 151954f8f403SNamhyung Kim 1520c92fcfdeSNamhyung Kim if (symbol_conf.report_hierarchy) { 1521c92fcfdeSNamhyung Kim /* disable incompatible options */ 1522c92fcfdeSNamhyung Kim symbol_conf.event_group = false; 1523c92fcfdeSNamhyung Kim symbol_conf.cumulate_callchain = false; 1524c92fcfdeSNamhyung Kim 1525c92fcfdeSNamhyung Kim if (field_order) { 1526c92fcfdeSNamhyung Kim pr_err("Error: --hierarchy and --fields options cannot be used together\n"); 1527c92fcfdeSNamhyung Kim parse_options_usage(top_usage, options, "fields", 0); 1528c92fcfdeSNamhyung Kim parse_options_usage(NULL, options, "hierarchy", 0); 1529c92fcfdeSNamhyung Kim goto out_delete_evlist; 1530c92fcfdeSNamhyung Kim } 1531c92fcfdeSNamhyung Kim } 1532c92fcfdeSNamhyung Kim 1533590ac60dSJin Yao if (opts->branch_stack && callchain_param.enabled) 1534590ac60dSJin Yao symbol_conf.show_branchflag_count = true; 1535590ac60dSJin Yao 1536512ae1bdSNamhyung Kim sort__mode = SORT_MODE__TOP; 15373a5714f8SNamhyung Kim /* display thread wants entries to be collapsed in a different tree */ 153852225036SJiri Olsa perf_hpp_list.need_collapse = 1; 15393a5714f8SNamhyung Kim 15403ee60c3bSArnaldo Carvalho de Melo if (top.use_stdio) 15413ee60c3bSArnaldo Carvalho de Melo use_browser = 0; 15423ee60c3bSArnaldo Carvalho de Melo else if (top.use_tui) 15433ee60c3bSArnaldo Carvalho de Melo use_browser = 1; 15443ee60c3bSArnaldo Carvalho de Melo 15453ee60c3bSArnaldo Carvalho de Melo setup_browser(false); 15463ee60c3bSArnaldo Carvalho de Melo 154740184c46SNamhyung Kim if (setup_sorting(top.evlist) < 0) { 15486fe8c26dSNamhyung Kim if (sort_order) 15496fe8c26dSNamhyung Kim parse_options_usage(top_usage, options, "s", 1); 15506fe8c26dSNamhyung Kim if (field_order) 15516fe8c26dSNamhyung Kim parse_options_usage(sort_order ? NULL : top_usage, 15526fe8c26dSNamhyung Kim options, "fields", 0); 15536fe8c26dSNamhyung Kim goto out_delete_evlist; 15546fe8c26dSNamhyung Kim } 155522af969eSNamhyung Kim 1556602ad878SArnaldo Carvalho de Melo status = target__validate(target); 155716ad2ffbSNamhyung Kim if (status) { 1558602ad878SArnaldo Carvalho de Melo target__strerror(target, status, errbuf, BUFSIZ); 1559ea432a8bSIngo Molnar ui__warning("%s\n", errbuf); 156016ad2ffbSNamhyung Kim } 15614bd0f2d2SNamhyung Kim 1562602ad878SArnaldo Carvalho de Melo status = target__parse_uid(target); 156316ad2ffbSNamhyung Kim if (status) { 156416ad2ffbSNamhyung Kim int saved_errno = errno; 156516ad2ffbSNamhyung Kim 1566602ad878SArnaldo Carvalho de Melo target__strerror(target, status, errbuf, BUFSIZ); 1567ea432a8bSIngo Molnar ui__error("%s\n", errbuf); 156816ad2ffbSNamhyung Kim 156916ad2ffbSNamhyung Kim status = -saved_errno; 15700d37aa34SArnaldo Carvalho de Melo goto out_delete_evlist; 157116ad2ffbSNamhyung Kim } 15720d37aa34SArnaldo Carvalho de Melo 1573602ad878SArnaldo Carvalho de Melo if (target__none(target)) 15742376c67aSArnaldo Carvalho de Melo target->system_wide = true; 157510b47d54SArnaldo Carvalho de Melo 1576f8a5c0b2SArnaldo Carvalho de Melo if (perf_evlist__create_maps(top.evlist, target) < 0) { 1577f8a5c0b2SArnaldo Carvalho de Melo ui__error("Couldn't create thread/CPU maps: %s\n", 1578c8b5f2c9SArnaldo Carvalho de Melo errno == ENOENT ? "No such process" : str_error_r(errno, errbuf, sizeof(errbuf))); 1579f8a5c0b2SArnaldo Carvalho de Melo goto out_delete_evlist; 1580f8a5c0b2SArnaldo Carvalho de Melo } 15817e2ed097SArnaldo Carvalho de Melo 15828c3e10ebSArnaldo Carvalho de Melo if (top.delay_secs < 1) 15838c3e10ebSArnaldo Carvalho de Melo top.delay_secs = 1; 158486470930SIngo Molnar 1585b4006796SArnaldo Carvalho de Melo if (record_opts__config(opts)) { 15862376c67aSArnaldo Carvalho de Melo status = -EINVAL; 158703ad9747SArnaldo Carvalho de Melo goto out_delete_evlist; 158869aad6f1SArnaldo Carvalho de Melo } 158969aad6f1SArnaldo Carvalho de Melo 15900c21f736SArnaldo Carvalho de Melo top.sym_evsel = perf_evlist__first(top.evlist); 1591cc841580SArnaldo Carvalho de Melo 1592e3815264SArnaldo Carvalho de Melo if (!callchain_param.enabled) { 15931432ec34SNamhyung Kim symbol_conf.cumulate_callchain = false; 15941432ec34SNamhyung Kim perf_hpp__cancel_cumulate(); 15951432ec34SNamhyung Kim } 15961432ec34SNamhyung Kim 1597792aeafaSNamhyung Kim if (symbol_conf.cumulate_callchain && !callchain_param.order_set) 1598792aeafaSNamhyung Kim callchain_param.order = ORDER_CALLER; 1599792aeafaSNamhyung Kim 1600b01141f4SArnaldo Carvalho de Melo status = symbol__annotation_init(); 1601b01141f4SArnaldo Carvalho de Melo if (status < 0) 1602b01141f4SArnaldo Carvalho de Melo goto out_delete_evlist; 160369aad6f1SArnaldo Carvalho de Melo 16047f0b6fdeSArnaldo Carvalho de Melo annotation_config__init(); 16057f0b6fdeSArnaldo Carvalho de Melo 160669aad6f1SArnaldo Carvalho de Melo symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); 16070a7e6d1bSNamhyung Kim if (symbol__init(NULL) < 0) 160869aad6f1SArnaldo Carvalho de Melo return -1; 160969aad6f1SArnaldo Carvalho de Melo 161008e71542SNamhyung Kim sort__setup_elide(stdout); 1611ab81f3fdSArnaldo Carvalho de Melo 16121758af10SArnaldo Carvalho de Melo get_term_dimensions(&top.winsize); 16138c3e10ebSArnaldo Carvalho de Melo if (top.print_entries == 0) { 16141758af10SArnaldo Carvalho de Melo perf_top__update_print_entries(&top); 1615244a1086SJiri Olsa signal(SIGWINCH, winch_sig); 16163b6ed988SArnaldo Carvalho de Melo } 16173b6ed988SArnaldo Carvalho de Melo 16181758af10SArnaldo Carvalho de Melo status = __cmd_top(&top); 1619806fb630SArnaldo Carvalho de Melo 16200d37aa34SArnaldo Carvalho de Melo out_delete_evlist: 16218c3e10ebSArnaldo Carvalho de Melo perf_evlist__delete(top.evlist); 162269aad6f1SArnaldo Carvalho de Melo 162369aad6f1SArnaldo Carvalho de Melo return status; 162486470930SIngo Molnar } 1625