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> 886470930SIngo Molnar * 986470930SIngo Molnar * Improvements and fixes by: 1086470930SIngo Molnar * 1186470930SIngo Molnar * Arjan van de Ven <arjan@linux.intel.com> 1286470930SIngo Molnar * Yanmin Zhang <yanmin.zhang@intel.com> 1386470930SIngo Molnar * Wu Fengguang <fengguang.wu@intel.com> 1486470930SIngo Molnar * Mike Galbraith <efault@gmx.de> 1586470930SIngo Molnar * Paul Mackerras <paulus@samba.org> 1686470930SIngo Molnar * 1786470930SIngo Molnar * Released under the GPL v2. (and only v2, not any later version) 1886470930SIngo Molnar */ 1986470930SIngo Molnar #include "builtin.h" 2086470930SIngo Molnar 2186470930SIngo Molnar #include "perf.h" 2286470930SIngo Molnar 2336532461SArnaldo Carvalho de Melo #include "util/annotate.h" 24c0443df1SArnaldo Carvalho de Melo #include "util/cache.h" 2586470930SIngo Molnar #include "util/color.h" 26361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h" 2769aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h" 28b3165f41SArnaldo Carvalho de Melo #include "util/session.h" 29b3165f41SArnaldo Carvalho de Melo #include "util/symbol.h" 30439d473bSArnaldo Carvalho de Melo #include "util/thread.h" 31fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 328c3e10ebSArnaldo Carvalho de Melo #include "util/top.h" 3386470930SIngo Molnar #include "util/util.h" 3443cbcd8aSArnaldo Carvalho de Melo #include <linux/rbtree.h> 3586470930SIngo Molnar #include "util/parse-options.h" 3686470930SIngo Molnar #include "util/parse-events.h" 37a12b51c4SPaul Mackerras #include "util/cpumap.h" 3869aad6f1SArnaldo Carvalho de Melo #include "util/xyarray.h" 3986470930SIngo Molnar 408f28827aSFrederic Weisbecker #include "util/debug.h" 418f28827aSFrederic Weisbecker 4286470930SIngo Molnar #include <assert.h> 4386470930SIngo Molnar #include <fcntl.h> 4486470930SIngo Molnar 4586470930SIngo Molnar #include <stdio.h> 46923c42c1SMike Galbraith #include <termios.h> 47923c42c1SMike Galbraith #include <unistd.h> 489486aa38SArnaldo Carvalho de Melo #include <inttypes.h> 4986470930SIngo Molnar 5086470930SIngo Molnar #include <errno.h> 5186470930SIngo Molnar #include <time.h> 5286470930SIngo Molnar #include <sched.h> 5386470930SIngo Molnar 5486470930SIngo Molnar #include <sys/syscall.h> 5586470930SIngo Molnar #include <sys/ioctl.h> 5686470930SIngo Molnar #include <sys/poll.h> 5786470930SIngo Molnar #include <sys/prctl.h> 5886470930SIngo Molnar #include <sys/wait.h> 5986470930SIngo Molnar #include <sys/uio.h> 6086470930SIngo Molnar #include <sys/mman.h> 6186470930SIngo Molnar 6286470930SIngo Molnar #include <linux/unistd.h> 6386470930SIngo Molnar #include <linux/types.h> 6486470930SIngo Molnar 6569aad6f1SArnaldo Carvalho de Melo #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 6686470930SIngo Molnar 678c3e10ebSArnaldo Carvalho de Melo static struct perf_top top = { 688c3e10ebSArnaldo Carvalho de Melo .count_filter = 5, 698c3e10ebSArnaldo Carvalho de Melo .delay_secs = 2, 708c3e10ebSArnaldo Carvalho de Melo .display_weighted = -1, 718c3e10ebSArnaldo Carvalho de Melo .target_pid = -1, 728c3e10ebSArnaldo Carvalho de Melo .target_tid = -1, 738c3e10ebSArnaldo Carvalho de Melo .active_symbols = LIST_HEAD_INIT(top.active_symbols), 748c3e10ebSArnaldo Carvalho de Melo .active_symbols_lock = PTHREAD_MUTEX_INITIALIZER, 755807806aSArnaldo Carvalho de Melo .active_symbols_cond = PTHREAD_COND_INITIALIZER, 768c3e10ebSArnaldo Carvalho de Melo .freq = 1000, /* 1 KHz */ 778c3e10ebSArnaldo Carvalho de Melo }; 78361c99a6SArnaldo Carvalho de Melo 79c0555642SIan Munsie static bool system_wide = false; 8086470930SIngo Molnar 81c0443df1SArnaldo Carvalho de Melo static bool use_tui, use_stdio; 82c0443df1SArnaldo Carvalho de Melo 837e4ff9e3SMike Galbraith static int default_interval = 0; 8486470930SIngo Molnar 85c0555642SIan Munsie static bool inherit = false; 861967936dSArnaldo Carvalho de Melo static int realtime_prio = 0; 87c0555642SIan Munsie static bool group = false; 8886470930SIngo Molnar static unsigned int page_size; 8970db7533SArnaldo Carvalho de Melo static unsigned int mmap_pages = 128; 9086470930SIngo Molnar 91c0555642SIan Munsie static bool dump_symtab = false; 9286470930SIngo Molnar 9313cc5079SArnaldo Carvalho de Melo static struct winsize winsize; 948ffcda17SArnaldo Carvalho de Melo 95edb7c60eSArnaldo Carvalho de Melo static const char *sym_filter = NULL; 966cff0e8dSKirill Smelkov struct sym_entry *sym_filter_entry_sched = NULL; 97923c42c1SMike Galbraith static int sym_pcnt_filter = 5; 9886470930SIngo Molnar 99923c42c1SMike Galbraith /* 100923c42c1SMike Galbraith * Source functions 101923c42c1SMike Galbraith */ 102923c42c1SMike Galbraith 103895f0edcSArnaldo Carvalho de Melo void get_term_dimensions(struct winsize *ws) 1043b6ed988SArnaldo Carvalho de Melo { 10513cc5079SArnaldo Carvalho de Melo char *s = getenv("LINES"); 1063b6ed988SArnaldo Carvalho de Melo 10713cc5079SArnaldo Carvalho de Melo if (s != NULL) { 10813cc5079SArnaldo Carvalho de Melo ws->ws_row = atoi(s); 10913cc5079SArnaldo Carvalho de Melo s = getenv("COLUMNS"); 11013cc5079SArnaldo Carvalho de Melo if (s != NULL) { 11113cc5079SArnaldo Carvalho de Melo ws->ws_col = atoi(s); 11213cc5079SArnaldo Carvalho de Melo if (ws->ws_row && ws->ws_col) 11313cc5079SArnaldo Carvalho de Melo return; 11413cc5079SArnaldo Carvalho de Melo } 11513cc5079SArnaldo Carvalho de Melo } 1163b6ed988SArnaldo Carvalho de Melo #ifdef TIOCGWINSZ 11713cc5079SArnaldo Carvalho de Melo if (ioctl(1, TIOCGWINSZ, ws) == 0 && 11813cc5079SArnaldo Carvalho de Melo ws->ws_row && ws->ws_col) 11913cc5079SArnaldo Carvalho de Melo return; 1203b6ed988SArnaldo Carvalho de Melo #endif 12113cc5079SArnaldo Carvalho de Melo ws->ws_row = 25; 12213cc5079SArnaldo Carvalho de Melo ws->ws_col = 80; 1233b6ed988SArnaldo Carvalho de Melo } 1243b6ed988SArnaldo Carvalho de Melo 12513cc5079SArnaldo Carvalho de Melo static void update_print_entries(struct winsize *ws) 1263b6ed988SArnaldo Carvalho de Melo { 1278c3e10ebSArnaldo Carvalho de Melo top.print_entries = ws->ws_row; 12813cc5079SArnaldo Carvalho de Melo 1298c3e10ebSArnaldo Carvalho de Melo if (top.print_entries > 9) 1308c3e10ebSArnaldo Carvalho de Melo top.print_entries -= 9; 1313b6ed988SArnaldo Carvalho de Melo } 1323b6ed988SArnaldo Carvalho de Melo 1333b6ed988SArnaldo Carvalho de Melo static void sig_winch_handler(int sig __used) 1343b6ed988SArnaldo Carvalho de Melo { 13513cc5079SArnaldo Carvalho de Melo get_term_dimensions(&winsize); 13613cc5079SArnaldo Carvalho de Melo update_print_entries(&winsize); 1373b6ed988SArnaldo Carvalho de Melo } 1383b6ed988SArnaldo Carvalho de Melo 139b0a9ab62SArnaldo Carvalho de Melo static int parse_source(struct sym_entry *syme) 140923c42c1SMike Galbraith { 141923c42c1SMike Galbraith struct symbol *sym; 142ce6f4fabSArnaldo Carvalho de Melo struct annotation *notes; 143439d473bSArnaldo Carvalho de Melo struct map *map; 14436532461SArnaldo Carvalho de Melo int err = -1; 145923c42c1SMike Galbraith 146923c42c1SMike Galbraith if (!syme) 147b0a9ab62SArnaldo Carvalho de Melo return -1; 148b0a9ab62SArnaldo Carvalho de Melo 149b0a9ab62SArnaldo Carvalho de Melo sym = sym_entry__symbol(syme); 150b0a9ab62SArnaldo Carvalho de Melo map = syme->map; 151b0a9ab62SArnaldo Carvalho de Melo 152b0a9ab62SArnaldo Carvalho de Melo /* 153b0a9ab62SArnaldo Carvalho de Melo * We can't annotate with just /proc/kallsyms 154b0a9ab62SArnaldo Carvalho de Melo */ 155878b439dSArnaldo Carvalho de Melo if (map->dso->symtab_type == SYMTAB__KALLSYMS) { 156ce6f4fabSArnaldo Carvalho de Melo pr_err("Can't annotate %s: No vmlinux file was found in the " 157ce6f4fabSArnaldo Carvalho de Melo "path\n", sym->name); 158ce6f4fabSArnaldo Carvalho de Melo sleep(1); 159b0a9ab62SArnaldo Carvalho de Melo return -1; 160b269876cSArnaldo Carvalho de Melo } 161b269876cSArnaldo Carvalho de Melo 162ce6f4fabSArnaldo Carvalho de Melo notes = symbol__annotation(sym); 163ce6f4fabSArnaldo Carvalho de Melo if (notes->src != NULL) { 164ce6f4fabSArnaldo Carvalho de Melo pthread_mutex_lock(¬es->lock); 165923c42c1SMike Galbraith goto out_assign; 166923c42c1SMike Galbraith } 167923c42c1SMike Galbraith 168ce6f4fabSArnaldo Carvalho de Melo pthread_mutex_lock(¬es->lock); 169923c42c1SMike Galbraith 17036532461SArnaldo Carvalho de Melo if (symbol__alloc_hist(sym, top.evlist->nr_entries) < 0) { 171c97cf422SArnaldo Carvalho de Melo pthread_mutex_unlock(¬es->lock); 17236532461SArnaldo Carvalho de Melo pr_err("Not enough memory for annotating '%s' symbol!\n", 17336532461SArnaldo Carvalho de Melo sym->name); 174ce6f4fabSArnaldo Carvalho de Melo sleep(1); 175c97cf422SArnaldo Carvalho de Melo return err; 176923c42c1SMike Galbraith } 17736532461SArnaldo Carvalho de Melo 178ce6f4fabSArnaldo Carvalho de Melo err = symbol__annotate(sym, syme->map, 0); 17936532461SArnaldo Carvalho de Melo if (err == 0) { 180923c42c1SMike Galbraith out_assign: 181c97cf422SArnaldo Carvalho de Melo top.sym_filter_entry = syme; 18236532461SArnaldo Carvalho de Melo } 183c97cf422SArnaldo Carvalho de Melo 184ce6f4fabSArnaldo Carvalho de Melo pthread_mutex_unlock(¬es->lock); 18536532461SArnaldo Carvalho de Melo return err; 186923c42c1SMike Galbraith } 187923c42c1SMike Galbraith 188923c42c1SMike Galbraith static void __zero_source_counters(struct sym_entry *syme) 189923c42c1SMike Galbraith { 19036532461SArnaldo Carvalho de Melo struct symbol *sym = sym_entry__symbol(syme); 19136532461SArnaldo Carvalho de Melo symbol__annotate_zero_histograms(sym); 192923c42c1SMike Galbraith } 193923c42c1SMike Galbraith 194923c42c1SMike Galbraith static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip) 195923c42c1SMike Galbraith { 196ce6f4fabSArnaldo Carvalho de Melo struct annotation *notes; 197ce6f4fabSArnaldo Carvalho de Melo struct symbol *sym; 198ce6f4fabSArnaldo Carvalho de Melo 199c97cf422SArnaldo Carvalho de Melo if (syme != top.sym_filter_entry) 200923c42c1SMike Galbraith return; 201923c42c1SMike Galbraith 202ce6f4fabSArnaldo Carvalho de Melo sym = sym_entry__symbol(syme); 203ce6f4fabSArnaldo Carvalho de Melo notes = symbol__annotation(sym); 204ce6f4fabSArnaldo Carvalho de Melo 205ce6f4fabSArnaldo Carvalho de Melo if (pthread_mutex_trylock(¬es->lock)) 206923c42c1SMike Galbraith return; 207923c42c1SMike Galbraith 20836532461SArnaldo Carvalho de Melo ip = syme->map->map_ip(syme->map, ip); 209ce6f4fabSArnaldo Carvalho de Melo symbol__inc_addr_samples(sym, syme->map, counter, ip); 210923c42c1SMike Galbraith 211ce6f4fabSArnaldo Carvalho de Melo pthread_mutex_unlock(¬es->lock); 212923c42c1SMike Galbraith } 213923c42c1SMike Galbraith 214923c42c1SMike Galbraith static void show_details(struct sym_entry *syme) 215923c42c1SMike Galbraith { 216ce6f4fabSArnaldo Carvalho de Melo struct annotation *notes; 217923c42c1SMike Galbraith struct symbol *symbol; 21836532461SArnaldo Carvalho de Melo int more; 219923c42c1SMike Galbraith 220923c42c1SMike Galbraith if (!syme) 221923c42c1SMike Galbraith return; 222923c42c1SMike Galbraith 22336532461SArnaldo Carvalho de Melo symbol = sym_entry__symbol(syme); 224ce6f4fabSArnaldo Carvalho de Melo notes = symbol__annotation(symbol); 225ce6f4fabSArnaldo Carvalho de Melo 226ce6f4fabSArnaldo Carvalho de Melo pthread_mutex_lock(¬es->lock); 227ce6f4fabSArnaldo Carvalho de Melo 228ce6f4fabSArnaldo Carvalho de Melo if (notes->src == NULL) 229ce6f4fabSArnaldo Carvalho de Melo goto out_unlock; 230923c42c1SMike Galbraith 2318c3e10ebSArnaldo Carvalho de Melo printf("Showing %s for %s\n", event_name(top.sym_evsel), symbol->name); 232923c42c1SMike Galbraith printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); 233923c42c1SMike Galbraith 234ce6f4fabSArnaldo Carvalho de Melo more = symbol__annotate_printf(symbol, syme->map, top.sym_evsel->idx, 235d5e3d747SArnaldo Carvalho de Melo 0, sym_pcnt_filter, top.print_entries, 4); 23636532461SArnaldo Carvalho de Melo if (top.zero) 23736532461SArnaldo Carvalho de Melo symbol__annotate_zero_histogram(symbol, top.sym_evsel->idx); 23836532461SArnaldo Carvalho de Melo else 239ce6f4fabSArnaldo Carvalho de Melo symbol__annotate_decay_histogram(symbol, top.sym_evsel->idx); 24036532461SArnaldo Carvalho de Melo if (more != 0) 241923c42c1SMike Galbraith printf("%d lines not displayed, maybe increase display entries [e]\n", more); 242ce6f4fabSArnaldo Carvalho de Melo out_unlock: 243ce6f4fabSArnaldo Carvalho de Melo pthread_mutex_unlock(¬es->lock); 244923c42c1SMike Galbraith } 24586470930SIngo Molnar 24686470930SIngo Molnar static const char CONSOLE_CLEAR[] = "[H[2J"; 24786470930SIngo Molnar 24886470930SIngo Molnar static void __list_insert_active_sym(struct sym_entry *syme) 24986470930SIngo Molnar { 2508c3e10ebSArnaldo Carvalho de Melo list_add(&syme->node, &top.active_symbols); 25186470930SIngo Molnar } 25286470930SIngo Molnar 25393fc64f1SArnaldo Carvalho de Melo static void print_sym_table(struct perf_session *session) 25486470930SIngo Molnar { 2558c3e10ebSArnaldo Carvalho de Melo char bf[160]; 2568c3e10ebSArnaldo Carvalho de Melo int printed = 0; 25786470930SIngo Molnar struct rb_node *nd; 2588c3e10ebSArnaldo Carvalho de Melo struct sym_entry *syme; 2598c3e10ebSArnaldo Carvalho de Melo struct rb_root tmp = RB_ROOT; 26013cc5079SArnaldo Carvalho de Melo const int win_width = winsize.ws_col - 1; 2618c3e10ebSArnaldo Carvalho de Melo int sym_width, dso_width, dso_short_width; 2628c3e10ebSArnaldo Carvalho de Melo float sum_ksamples = perf_top__decay_samples(&top, &tmp); 26386470930SIngo Molnar 26486470930SIngo Molnar puts(CONSOLE_CLEAR); 26586470930SIngo Molnar 2668c3e10ebSArnaldo Carvalho de Melo perf_top__header_snprintf(&top, bf, sizeof(bf)); 2678c3e10ebSArnaldo Carvalho de Melo printf("%s\n", bf); 26886470930SIngo Molnar 2698c3e10ebSArnaldo Carvalho de Melo perf_top__reset_sample_counters(&top); 27086470930SIngo Molnar 2711a105f74SArnaldo Carvalho de Melo printf("%-*.*s\n", win_width, win_width, graph_dotted_line); 27286470930SIngo Molnar 27393fc64f1SArnaldo Carvalho de Melo if (session->hists.stats.total_lost != 0) { 27493fc64f1SArnaldo Carvalho de Melo color_fprintf(stdout, PERF_COLOR_RED, "WARNING:"); 27593fc64f1SArnaldo Carvalho de Melo printf(" LOST %" PRIu64 " events, Check IO/CPU overload\n", 27693fc64f1SArnaldo Carvalho de Melo session->hists.stats.total_lost); 27793fc64f1SArnaldo Carvalho de Melo } 27893fc64f1SArnaldo Carvalho de Melo 279c97cf422SArnaldo Carvalho de Melo if (top.sym_filter_entry) { 280c97cf422SArnaldo Carvalho de Melo show_details(top.sym_filter_entry); 281923c42c1SMike Galbraith return; 282923c42c1SMike Galbraith } 283923c42c1SMike Galbraith 2848c3e10ebSArnaldo Carvalho de Melo perf_top__find_widths(&top, &tmp, &dso_width, &dso_short_width, 2858c3e10ebSArnaldo Carvalho de Melo &sym_width); 28613cc5079SArnaldo Carvalho de Melo 287b63be8d7SArnaldo Carvalho de Melo if (sym_width + dso_width > winsize.ws_col - 29) { 288b63be8d7SArnaldo Carvalho de Melo dso_width = dso_short_width; 289b63be8d7SArnaldo Carvalho de Melo if (sym_width + dso_width > winsize.ws_col - 29) 290b63be8d7SArnaldo Carvalho de Melo sym_width = winsize.ws_col - dso_width - 29; 291b63be8d7SArnaldo Carvalho de Melo } 2921a105f74SArnaldo Carvalho de Melo putchar('\n'); 2938c3e10ebSArnaldo Carvalho de Melo if (top.evlist->nr_entries == 1) 29486470930SIngo Molnar printf(" samples pcnt"); 29586470930SIngo Molnar else 29686470930SIngo Molnar printf(" weight samples pcnt"); 29786470930SIngo Molnar 2987ced156bSArnaldo Carvalho de Melo if (verbose) 2997ced156bSArnaldo Carvalho de Melo printf(" RIP "); 3007cc017edSArnaldo Carvalho de Melo printf(" %-*.*s DSO\n", sym_width, sym_width, "function"); 3017ced156bSArnaldo Carvalho de Melo printf(" %s _______ _____", 3028c3e10ebSArnaldo Carvalho de Melo top.evlist->nr_entries == 1 ? " " : "______"); 3037ced156bSArnaldo Carvalho de Melo if (verbose) 3047ced156bSArnaldo Carvalho de Melo printf(" ________________"); 3051a105f74SArnaldo Carvalho de Melo printf(" %-*.*s", sym_width, sym_width, graph_line); 3061a105f74SArnaldo Carvalho de Melo printf(" %-*.*s", dso_width, dso_width, graph_line); 3071a105f74SArnaldo Carvalho de Melo puts("\n"); 30886470930SIngo Molnar 30986470930SIngo Molnar for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) { 31083a0944fSIngo Molnar struct symbol *sym; 31186470930SIngo Molnar double pcnt; 31286470930SIngo Molnar 31383a0944fSIngo Molnar syme = rb_entry(nd, struct sym_entry, rb_node); 31451a472deSArnaldo Carvalho de Melo sym = sym_entry__symbol(syme); 3158c3e10ebSArnaldo Carvalho de Melo if (++printed > top.print_entries || 3168c3e10ebSArnaldo Carvalho de Melo (int)syme->snap_count < top.count_filter) 31786470930SIngo Molnar continue; 31886470930SIngo Molnar 31986470930SIngo Molnar pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / 32086470930SIngo Molnar sum_ksamples)); 32186470930SIngo Molnar 3228c3e10ebSArnaldo Carvalho de Melo if (top.evlist->nr_entries == 1 || !top.display_weighted) 3235b2bb75aSArnaldo Carvalho de Melo printf("%20.2f ", syme->weight); 32486470930SIngo Molnar else 3255b2bb75aSArnaldo Carvalho de Melo printf("%9.1f %10ld ", syme->weight, syme->snap_count); 32686470930SIngo Molnar 3271e11fd82SFrederic Weisbecker percent_color_fprintf(stdout, "%4.1f%%", pcnt); 3287ced156bSArnaldo Carvalho de Melo if (verbose) 3299486aa38SArnaldo Carvalho de Melo printf(" %016" PRIx64, sym->start); 33013cc5079SArnaldo Carvalho de Melo printf(" %-*.*s", sym_width, sym_width, sym->name); 3317cc017edSArnaldo Carvalho de Melo printf(" %-*.*s\n", dso_width, dso_width, 33213cc5079SArnaldo Carvalho de Melo dso_width >= syme->map->dso->long_name_len ? 33313cc5079SArnaldo Carvalho de Melo syme->map->dso->long_name : 33413cc5079SArnaldo Carvalho de Melo syme->map->dso->short_name); 33586470930SIngo Molnar } 33686470930SIngo Molnar } 33786470930SIngo Molnar 338923c42c1SMike Galbraith static void prompt_integer(int *target, const char *msg) 339923c42c1SMike Galbraith { 340923c42c1SMike Galbraith char *buf = malloc(0), *p; 341923c42c1SMike Galbraith size_t dummy = 0; 342923c42c1SMike Galbraith int tmp; 343923c42c1SMike Galbraith 344923c42c1SMike Galbraith fprintf(stdout, "\n%s: ", msg); 345923c42c1SMike Galbraith if (getline(&buf, &dummy, stdin) < 0) 346923c42c1SMike Galbraith return; 347923c42c1SMike Galbraith 348923c42c1SMike Galbraith p = strchr(buf, '\n'); 349923c42c1SMike Galbraith if (p) 350923c42c1SMike Galbraith *p = 0; 351923c42c1SMike Galbraith 352923c42c1SMike Galbraith p = buf; 353923c42c1SMike Galbraith while(*p) { 354923c42c1SMike Galbraith if (!isdigit(*p)) 355923c42c1SMike Galbraith goto out_free; 356923c42c1SMike Galbraith p++; 357923c42c1SMike Galbraith } 358923c42c1SMike Galbraith tmp = strtoul(buf, NULL, 10); 359923c42c1SMike Galbraith *target = tmp; 360923c42c1SMike Galbraith out_free: 361923c42c1SMike Galbraith free(buf); 362923c42c1SMike Galbraith } 363923c42c1SMike Galbraith 364923c42c1SMike Galbraith static void prompt_percent(int *target, const char *msg) 365923c42c1SMike Galbraith { 366923c42c1SMike Galbraith int tmp = 0; 367923c42c1SMike Galbraith 368923c42c1SMike Galbraith prompt_integer(&tmp, msg); 369923c42c1SMike Galbraith if (tmp >= 0 && tmp <= 100) 370923c42c1SMike Galbraith *target = tmp; 371923c42c1SMike Galbraith } 372923c42c1SMike Galbraith 373923c42c1SMike Galbraith static void prompt_symbol(struct sym_entry **target, const char *msg) 374923c42c1SMike Galbraith { 375923c42c1SMike Galbraith char *buf = malloc(0), *p; 376923c42c1SMike Galbraith struct sym_entry *syme = *target, *n, *found = NULL; 377923c42c1SMike Galbraith size_t dummy = 0; 378923c42c1SMike Galbraith 379923c42c1SMike Galbraith /* zero counters of active symbol */ 380923c42c1SMike Galbraith if (syme) { 381923c42c1SMike Galbraith __zero_source_counters(syme); 382923c42c1SMike Galbraith *target = NULL; 383923c42c1SMike Galbraith } 384923c42c1SMike Galbraith 385923c42c1SMike Galbraith fprintf(stdout, "\n%s: ", msg); 386923c42c1SMike Galbraith if (getline(&buf, &dummy, stdin) < 0) 387923c42c1SMike Galbraith goto out_free; 388923c42c1SMike Galbraith 389923c42c1SMike Galbraith p = strchr(buf, '\n'); 390923c42c1SMike Galbraith if (p) 391923c42c1SMike Galbraith *p = 0; 392923c42c1SMike Galbraith 3938c3e10ebSArnaldo Carvalho de Melo pthread_mutex_lock(&top.active_symbols_lock); 3948c3e10ebSArnaldo Carvalho de Melo syme = list_entry(top.active_symbols.next, struct sym_entry, node); 3958c3e10ebSArnaldo Carvalho de Melo pthread_mutex_unlock(&top.active_symbols_lock); 396923c42c1SMike Galbraith 3978c3e10ebSArnaldo Carvalho de Melo list_for_each_entry_safe_from(syme, n, &top.active_symbols, node) { 39851a472deSArnaldo Carvalho de Melo struct symbol *sym = sym_entry__symbol(syme); 399923c42c1SMike Galbraith 400923c42c1SMike Galbraith if (!strcmp(buf, sym->name)) { 401923c42c1SMike Galbraith found = syme; 402923c42c1SMike Galbraith break; 403923c42c1SMike Galbraith } 404923c42c1SMike Galbraith } 405923c42c1SMike Galbraith 406923c42c1SMike Galbraith if (!found) { 40766aeb6d5SKirill Smelkov fprintf(stderr, "Sorry, %s is not active.\n", buf); 408923c42c1SMike Galbraith sleep(1); 409923c42c1SMike Galbraith return; 410923c42c1SMike Galbraith } else 411923c42c1SMike Galbraith parse_source(found); 412923c42c1SMike Galbraith 413923c42c1SMike Galbraith out_free: 414923c42c1SMike Galbraith free(buf); 415923c42c1SMike Galbraith } 416923c42c1SMike Galbraith 417091bd2e9SMike Galbraith static void print_mapped_keys(void) 418923c42c1SMike Galbraith { 419091bd2e9SMike Galbraith char *name = NULL; 420091bd2e9SMike Galbraith 421c97cf422SArnaldo Carvalho de Melo if (top.sym_filter_entry) { 422c97cf422SArnaldo Carvalho de Melo struct symbol *sym = sym_entry__symbol(top.sym_filter_entry); 423091bd2e9SMike Galbraith name = sym->name; 424091bd2e9SMike Galbraith } 425091bd2e9SMike Galbraith 426091bd2e9SMike Galbraith fprintf(stdout, "\nMapped keys:\n"); 4278c3e10ebSArnaldo Carvalho de Melo fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", top.delay_secs); 4288c3e10ebSArnaldo Carvalho de Melo fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", top.print_entries); 429091bd2e9SMike Galbraith 4308c3e10ebSArnaldo Carvalho de Melo if (top.evlist->nr_entries > 1) 4318c3e10ebSArnaldo Carvalho de Melo fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(top.sym_evsel)); 432091bd2e9SMike Galbraith 4338c3e10ebSArnaldo Carvalho de Melo fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", top.count_filter); 434091bd2e9SMike Galbraith 435091bd2e9SMike Galbraith fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter); 436091bd2e9SMike Galbraith fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL"); 437091bd2e9SMike Galbraith fprintf(stdout, "\t[S] stop annotation.\n"); 438091bd2e9SMike Galbraith 4398c3e10ebSArnaldo Carvalho de Melo if (top.evlist->nr_entries > 1) 4408c3e10ebSArnaldo Carvalho de Melo fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", top.display_weighted ? 1 : 0); 441091bd2e9SMike Galbraith 4428ffcda17SArnaldo Carvalho de Melo fprintf(stdout, 4438ffcda17SArnaldo Carvalho de Melo "\t[K] hide kernel_symbols symbols. \t(%s)\n", 4448c3e10ebSArnaldo Carvalho de Melo top.hide_kernel_symbols ? "yes" : "no"); 4458ffcda17SArnaldo Carvalho de Melo fprintf(stdout, 4468ffcda17SArnaldo Carvalho de Melo "\t[U] hide user symbols. \t(%s)\n", 4478c3e10ebSArnaldo Carvalho de Melo top.hide_user_symbols ? "yes" : "no"); 4488c3e10ebSArnaldo Carvalho de Melo fprintf(stdout, "\t[z] toggle sample zeroing. \t(%d)\n", top.zero ? 1 : 0); 449091bd2e9SMike Galbraith fprintf(stdout, "\t[qQ] quit.\n"); 450091bd2e9SMike Galbraith } 451091bd2e9SMike Galbraith 452091bd2e9SMike Galbraith static int key_mapped(int c) 453091bd2e9SMike Galbraith { 454091bd2e9SMike Galbraith switch (c) { 455091bd2e9SMike Galbraith case 'd': 456091bd2e9SMike Galbraith case 'e': 457091bd2e9SMike Galbraith case 'f': 458091bd2e9SMike Galbraith case 'z': 459091bd2e9SMike Galbraith case 'q': 460091bd2e9SMike Galbraith case 'Q': 4618ffcda17SArnaldo Carvalho de Melo case 'K': 4628ffcda17SArnaldo Carvalho de Melo case 'U': 4636cff0e8dSKirill Smelkov case 'F': 4646cff0e8dSKirill Smelkov case 's': 4656cff0e8dSKirill Smelkov case 'S': 466091bd2e9SMike Galbraith return 1; 467091bd2e9SMike Galbraith case 'E': 468091bd2e9SMike Galbraith case 'w': 4698c3e10ebSArnaldo Carvalho de Melo return top.evlist->nr_entries > 1 ? 1 : 0; 47083a0944fSIngo Molnar default: 47183a0944fSIngo Molnar break; 472091bd2e9SMike Galbraith } 473091bd2e9SMike Galbraith 474091bd2e9SMike Galbraith return 0; 475923c42c1SMike Galbraith } 476923c42c1SMike Galbraith 477a1645ce1SZhang, Yanmin static void handle_keypress(struct perf_session *session, int c) 478923c42c1SMike Galbraith { 479091bd2e9SMike Galbraith if (!key_mapped(c)) { 480091bd2e9SMike Galbraith struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 481091bd2e9SMike Galbraith struct termios tc, save; 482091bd2e9SMike Galbraith 483091bd2e9SMike Galbraith print_mapped_keys(); 484091bd2e9SMike Galbraith fprintf(stdout, "\nEnter selection, or unmapped key to continue: "); 485091bd2e9SMike Galbraith fflush(stdout); 486091bd2e9SMike Galbraith 487091bd2e9SMike Galbraith tcgetattr(0, &save); 488091bd2e9SMike Galbraith tc = save; 489091bd2e9SMike Galbraith tc.c_lflag &= ~(ICANON | ECHO); 490091bd2e9SMike Galbraith tc.c_cc[VMIN] = 0; 491091bd2e9SMike Galbraith tc.c_cc[VTIME] = 0; 492091bd2e9SMike Galbraith tcsetattr(0, TCSANOW, &tc); 493091bd2e9SMike Galbraith 494091bd2e9SMike Galbraith poll(&stdin_poll, 1, -1); 495091bd2e9SMike Galbraith c = getc(stdin); 496091bd2e9SMike Galbraith 497091bd2e9SMike Galbraith tcsetattr(0, TCSAFLUSH, &save); 498091bd2e9SMike Galbraith if (!key_mapped(c)) 499091bd2e9SMike Galbraith return; 500091bd2e9SMike Galbraith } 501091bd2e9SMike Galbraith 502923c42c1SMike Galbraith switch (c) { 503923c42c1SMike Galbraith case 'd': 5048c3e10ebSArnaldo Carvalho de Melo prompt_integer(&top.delay_secs, "Enter display delay"); 5058c3e10ebSArnaldo Carvalho de Melo if (top.delay_secs < 1) 5068c3e10ebSArnaldo Carvalho de Melo top.delay_secs = 1; 507923c42c1SMike Galbraith break; 508923c42c1SMike Galbraith case 'e': 5098c3e10ebSArnaldo Carvalho de Melo prompt_integer(&top.print_entries, "Enter display entries (lines)"); 5108c3e10ebSArnaldo Carvalho de Melo if (top.print_entries == 0) { 51113cc5079SArnaldo Carvalho de Melo sig_winch_handler(SIGWINCH); 5123b6ed988SArnaldo Carvalho de Melo signal(SIGWINCH, sig_winch_handler); 5133b6ed988SArnaldo Carvalho de Melo } else 5143b6ed988SArnaldo Carvalho de Melo signal(SIGWINCH, SIG_DFL); 515923c42c1SMike Galbraith break; 516923c42c1SMike Galbraith case 'E': 5178c3e10ebSArnaldo Carvalho de Melo if (top.evlist->nr_entries > 1) { 518ce2d17caSAkihiro Nagai /* Select 0 as the default event: */ 519ce2d17caSAkihiro Nagai int counter = 0; 520ce2d17caSAkihiro Nagai 521923c42c1SMike Galbraith fprintf(stderr, "\nAvailable events:"); 52269aad6f1SArnaldo Carvalho de Melo 5238c3e10ebSArnaldo Carvalho de Melo list_for_each_entry(top.sym_evsel, &top.evlist->entries, node) 5248c3e10ebSArnaldo Carvalho de Melo fprintf(stderr, "\n\t%d %s", top.sym_evsel->idx, event_name(top.sym_evsel)); 525923c42c1SMike Galbraith 526ec52d976SArnaldo Carvalho de Melo prompt_integer(&counter, "Enter details event counter"); 527923c42c1SMike Galbraith 528ec52d976SArnaldo Carvalho de Melo if (counter >= top.evlist->nr_entries) { 5298c3e10ebSArnaldo Carvalho de Melo top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node); 5308c3e10ebSArnaldo Carvalho de Melo fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(top.sym_evsel)); 531923c42c1SMike Galbraith sleep(1); 53269aad6f1SArnaldo Carvalho de Melo break; 533923c42c1SMike Galbraith } 5348c3e10ebSArnaldo Carvalho de Melo list_for_each_entry(top.sym_evsel, &top.evlist->entries, node) 535ec52d976SArnaldo Carvalho de Melo if (top.sym_evsel->idx == counter) 53669aad6f1SArnaldo Carvalho de Melo break; 537ec52d976SArnaldo Carvalho de Melo } else 538ec52d976SArnaldo Carvalho de Melo top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node); 539923c42c1SMike Galbraith break; 540923c42c1SMike Galbraith case 'f': 5418c3e10ebSArnaldo Carvalho de Melo prompt_integer(&top.count_filter, "Enter display event count filter"); 542923c42c1SMike Galbraith break; 543923c42c1SMike Galbraith case 'F': 544923c42c1SMike Galbraith prompt_percent(&sym_pcnt_filter, "Enter details display event filter (percent)"); 545923c42c1SMike Galbraith break; 5468ffcda17SArnaldo Carvalho de Melo case 'K': 5478c3e10ebSArnaldo Carvalho de Melo top.hide_kernel_symbols = !top.hide_kernel_symbols; 5488ffcda17SArnaldo Carvalho de Melo break; 549923c42c1SMike Galbraith case 'q': 550923c42c1SMike Galbraith case 'Q': 551923c42c1SMike Galbraith printf("exiting.\n"); 552c338aee8SArnaldo Carvalho de Melo if (dump_symtab) 553cbf69680SArnaldo Carvalho de Melo perf_session__fprintf_dsos(session, stderr); 554923c42c1SMike Galbraith exit(0); 555923c42c1SMike Galbraith case 's': 556c97cf422SArnaldo Carvalho de Melo prompt_symbol(&top.sym_filter_entry, "Enter details symbol"); 557923c42c1SMike Galbraith break; 558923c42c1SMike Galbraith case 'S': 559c97cf422SArnaldo Carvalho de Melo if (!top.sym_filter_entry) 560923c42c1SMike Galbraith break; 561923c42c1SMike Galbraith else { 562c97cf422SArnaldo Carvalho de Melo struct sym_entry *syme = top.sym_filter_entry; 563923c42c1SMike Galbraith 564c97cf422SArnaldo Carvalho de Melo top.sym_filter_entry = NULL; 565923c42c1SMike Galbraith __zero_source_counters(syme); 566923c42c1SMike Galbraith } 567923c42c1SMike Galbraith break; 5688ffcda17SArnaldo Carvalho de Melo case 'U': 5698c3e10ebSArnaldo Carvalho de Melo top.hide_user_symbols = !top.hide_user_symbols; 5708ffcda17SArnaldo Carvalho de Melo break; 57146ab9764SMike Galbraith case 'w': 5728c3e10ebSArnaldo Carvalho de Melo top.display_weighted = ~top.display_weighted; 57346ab9764SMike Galbraith break; 574923c42c1SMike Galbraith case 'z': 5758c3e10ebSArnaldo Carvalho de Melo top.zero = !top.zero; 576923c42c1SMike Galbraith break; 57783a0944fSIngo Molnar default: 57883a0944fSIngo Molnar break; 579923c42c1SMike Galbraith } 580923c42c1SMike Galbraith } 581923c42c1SMike Galbraith 582c0443df1SArnaldo Carvalho de Melo static void *display_thread_tui(void *arg __used) 583c0443df1SArnaldo Carvalho de Melo { 5845807806aSArnaldo Carvalho de Melo int err = 0; 5855807806aSArnaldo Carvalho de Melo pthread_mutex_lock(&top.active_symbols_lock); 5865807806aSArnaldo Carvalho de Melo while (list_empty(&top.active_symbols)) { 5875807806aSArnaldo Carvalho de Melo err = pthread_cond_wait(&top.active_symbols_cond, 5885807806aSArnaldo Carvalho de Melo &top.active_symbols_lock); 5895807806aSArnaldo Carvalho de Melo if (err) 5905807806aSArnaldo Carvalho de Melo break; 5915807806aSArnaldo Carvalho de Melo } 5925807806aSArnaldo Carvalho de Melo pthread_mutex_unlock(&top.active_symbols_lock); 5935807806aSArnaldo Carvalho de Melo if (!err) 594c0443df1SArnaldo Carvalho de Melo perf_top__tui_browser(&top); 595c0443df1SArnaldo Carvalho de Melo exit_browser(0); 596c0443df1SArnaldo Carvalho de Melo exit(0); 597c0443df1SArnaldo Carvalho de Melo return NULL; 598c0443df1SArnaldo Carvalho de Melo } 599c0443df1SArnaldo Carvalho de Melo 600f37a291cSIngo Molnar static void *display_thread(void *arg __used) 60186470930SIngo Molnar { 60286470930SIngo Molnar struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 603923c42c1SMike Galbraith struct termios tc, save; 604923c42c1SMike Galbraith int delay_msecs, c; 605a1645ce1SZhang, Yanmin struct perf_session *session = (struct perf_session *) arg; 60686470930SIngo Molnar 607923c42c1SMike Galbraith tcgetattr(0, &save); 608923c42c1SMike Galbraith tc = save; 609923c42c1SMike Galbraith tc.c_lflag &= ~(ICANON | ECHO); 610923c42c1SMike Galbraith tc.c_cc[VMIN] = 0; 611923c42c1SMike Galbraith tc.c_cc[VTIME] = 0; 612091bd2e9SMike Galbraith 613923c42c1SMike Galbraith repeat: 6148c3e10ebSArnaldo Carvalho de Melo delay_msecs = top.delay_secs * 1000; 615923c42c1SMike Galbraith tcsetattr(0, TCSANOW, &tc); 616923c42c1SMike Galbraith /* trash return*/ 617923c42c1SMike Galbraith getc(stdin); 61886470930SIngo Molnar 61986470930SIngo Molnar do { 62093fc64f1SArnaldo Carvalho de Melo print_sym_table(session); 62186470930SIngo Molnar } while (!poll(&stdin_poll, 1, delay_msecs) == 1); 62286470930SIngo Molnar 623923c42c1SMike Galbraith c = getc(stdin); 624923c42c1SMike Galbraith tcsetattr(0, TCSAFLUSH, &save); 625923c42c1SMike Galbraith 626a1645ce1SZhang, Yanmin handle_keypress(session, c); 627923c42c1SMike Galbraith goto repeat; 62886470930SIngo Molnar 62986470930SIngo Molnar return NULL; 63086470930SIngo Molnar } 63186470930SIngo Molnar 6322ab52083SAnton Blanchard /* Tag samples to be skipped. */ 633f37a291cSIngo Molnar static const char *skip_symbols[] = { 6342ab52083SAnton Blanchard "default_idle", 635b0e8572fSArnaldo Carvalho de Melo "native_safe_halt", 6362ab52083SAnton Blanchard "cpu_idle", 6372ab52083SAnton Blanchard "enter_idle", 6382ab52083SAnton Blanchard "exit_idle", 6392ab52083SAnton Blanchard "mwait_idle", 64059b90056SArnaldo Carvalho de Melo "mwait_idle_with_hints", 6418357275bSArnaldo Carvalho de Melo "poll_idle", 6423a3393efSAnton Blanchard "ppc64_runlatch_off", 6433a3393efSAnton Blanchard "pseries_dedicated_idle_sleep", 6442ab52083SAnton Blanchard NULL 6452ab52083SAnton Blanchard }; 6462ab52083SAnton Blanchard 647439d473bSArnaldo Carvalho de Melo static int symbol_filter(struct map *map, struct symbol *sym) 64886470930SIngo Molnar { 64986470930SIngo Molnar struct sym_entry *syme; 65086470930SIngo Molnar const char *name = sym->name; 6512ab52083SAnton Blanchard int i; 65286470930SIngo Molnar 6533a3393efSAnton Blanchard /* 6543a3393efSAnton Blanchard * ppc64 uses function descriptors and appends a '.' to the 6553a3393efSAnton Blanchard * start of every instruction address. Remove it. 6563a3393efSAnton Blanchard */ 6573a3393efSAnton Blanchard if (name[0] == '.') 6583a3393efSAnton Blanchard name++; 6593a3393efSAnton Blanchard 66086470930SIngo Molnar if (!strcmp(name, "_text") || 66186470930SIngo Molnar !strcmp(name, "_etext") || 66286470930SIngo Molnar !strcmp(name, "_sinittext") || 66386470930SIngo Molnar !strncmp("init_module", name, 11) || 66486470930SIngo Molnar !strncmp("cleanup_module", name, 14) || 66586470930SIngo Molnar strstr(name, "_text_start") || 66686470930SIngo Molnar strstr(name, "_text_end")) 66786470930SIngo Molnar return 1; 66886470930SIngo Molnar 66900a192b3SArnaldo Carvalho de Melo syme = symbol__priv(sym); 670439d473bSArnaldo Carvalho de Melo syme->map = map; 671ce6f4fabSArnaldo Carvalho de Melo symbol__annotate_init(map, sym); 6726cff0e8dSKirill Smelkov 673c97cf422SArnaldo Carvalho de Melo if (!top.sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) { 6746cff0e8dSKirill Smelkov /* schedule initial sym_filter_entry setup */ 6756cff0e8dSKirill Smelkov sym_filter_entry_sched = syme; 6766cff0e8dSKirill Smelkov sym_filter = NULL; 6776cff0e8dSKirill Smelkov } 678923c42c1SMike Galbraith 6792ab52083SAnton Blanchard for (i = 0; skip_symbols[i]; i++) { 6802ab52083SAnton Blanchard if (!strcmp(skip_symbols[i], name)) { 681171b3be9SArnaldo Carvalho de Melo sym->ignore = true; 6822ab52083SAnton Blanchard break; 6832ab52083SAnton Blanchard } 6842ab52083SAnton Blanchard } 68586470930SIngo Molnar 68686470930SIngo Molnar return 0; 68786470930SIngo Molnar } 68886470930SIngo Molnar 6898115d60cSArnaldo Carvalho de Melo static void perf_event__process_sample(const union perf_event *event, 6908d50e5b4SArnaldo Carvalho de Melo struct perf_sample *sample, 69170db7533SArnaldo Carvalho de Melo struct perf_session *session) 69286470930SIngo Molnar { 6938115d60cSArnaldo Carvalho de Melo u64 ip = event->ip.ip; 6945b2bb75aSArnaldo Carvalho de Melo struct sym_entry *syme; 6951ed091c4SArnaldo Carvalho de Melo struct addr_location al; 69623346f21SArnaldo Carvalho de Melo struct machine *machine; 6978115d60cSArnaldo Carvalho de Melo u8 origin = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 69886470930SIngo Molnar 6998c3e10ebSArnaldo Carvalho de Melo ++top.samples; 70024bfef0fSArnaldo Carvalho de Melo 7018ffcda17SArnaldo Carvalho de Melo switch (origin) { 7021ed091c4SArnaldo Carvalho de Melo case PERF_RECORD_MISC_USER: 7038c3e10ebSArnaldo Carvalho de Melo ++top.us_samples; 7048c3e10ebSArnaldo Carvalho de Melo if (top.hide_user_symbols) 7058ffcda17SArnaldo Carvalho de Melo return; 70623346f21SArnaldo Carvalho de Melo machine = perf_session__find_host_machine(session); 7075b2bb75aSArnaldo Carvalho de Melo break; 7085b2bb75aSArnaldo Carvalho de Melo case PERF_RECORD_MISC_KERNEL: 7098c3e10ebSArnaldo Carvalho de Melo ++top.kernel_samples; 7108c3e10ebSArnaldo Carvalho de Melo if (top.hide_kernel_symbols) 7118ffcda17SArnaldo Carvalho de Melo return; 71223346f21SArnaldo Carvalho de Melo machine = perf_session__find_host_machine(session); 7135b2bb75aSArnaldo Carvalho de Melo break; 714a1645ce1SZhang, Yanmin case PERF_RECORD_MISC_GUEST_KERNEL: 7158c3e10ebSArnaldo Carvalho de Melo ++top.guest_kernel_samples; 7168115d60cSArnaldo Carvalho de Melo machine = perf_session__find_machine(session, event->ip.pid); 717a1645ce1SZhang, Yanmin break; 718a1645ce1SZhang, Yanmin case PERF_RECORD_MISC_GUEST_USER: 7198c3e10ebSArnaldo Carvalho de Melo ++top.guest_us_samples; 720a1645ce1SZhang, Yanmin /* 721a1645ce1SZhang, Yanmin * TODO: we don't process guest user from host side 722a1645ce1SZhang, Yanmin * except simple counting. 723a1645ce1SZhang, Yanmin */ 724a1645ce1SZhang, Yanmin return; 7255b2bb75aSArnaldo Carvalho de Melo default: 7265b2bb75aSArnaldo Carvalho de Melo return; 7275b2bb75aSArnaldo Carvalho de Melo } 7285b2bb75aSArnaldo Carvalho de Melo 72923346f21SArnaldo Carvalho de Melo if (!machine && perf_guest) { 730a1645ce1SZhang, Yanmin pr_err("Can't find guest [%d]'s kernel information\n", 7318115d60cSArnaldo Carvalho de Melo event->ip.pid); 732a1645ce1SZhang, Yanmin return; 733a1645ce1SZhang, Yanmin } 734a1645ce1SZhang, Yanmin 7358115d60cSArnaldo Carvalho de Melo if (event->header.misc & PERF_RECORD_MISC_EXACT_IP) 7368c3e10ebSArnaldo Carvalho de Melo top.exact_samples++; 7371676b8a0SPeter Zijlstra 7388115d60cSArnaldo Carvalho de Melo if (perf_event__preprocess_sample(event, session, &al, sample, 73941a37e20SArnaldo Carvalho de Melo symbol_filter) < 0 || 74072b8fa17SArnaldo Carvalho de Melo al.filtered) 7411ed091c4SArnaldo Carvalho de Melo return; 74286470930SIngo Molnar 74372b8fa17SArnaldo Carvalho de Melo if (al.sym == NULL) { 74472b8fa17SArnaldo Carvalho de Melo /* 74572b8fa17SArnaldo Carvalho de Melo * As we do lazy loading of symtabs we only will know if the 74672b8fa17SArnaldo Carvalho de Melo * specified vmlinux file is invalid when we actually have a 74772b8fa17SArnaldo Carvalho de Melo * hit in kernel space and then try to load it. So if we get 74872b8fa17SArnaldo Carvalho de Melo * here and there are _no_ symbols in the DSO backing the 74972b8fa17SArnaldo Carvalho de Melo * kernel map, bail out. 75072b8fa17SArnaldo Carvalho de Melo * 75172b8fa17SArnaldo Carvalho de Melo * We may never get here, for instance, if we use -K/ 75272b8fa17SArnaldo Carvalho de Melo * --hide-kernel-symbols, even if the user specifies an 75372b8fa17SArnaldo Carvalho de Melo * invalid --vmlinux ;-) 75472b8fa17SArnaldo Carvalho de Melo */ 75523346f21SArnaldo Carvalho de Melo if (al.map == machine->vmlinux_maps[MAP__FUNCTION] && 75672b8fa17SArnaldo Carvalho de Melo RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { 757374cfe56SArnaldo Carvalho de Melo ui__warning("The %s file can't be used\n", 75872b8fa17SArnaldo Carvalho de Melo symbol_conf.vmlinux_name); 759374cfe56SArnaldo Carvalho de Melo exit_browser(0); 76072b8fa17SArnaldo Carvalho de Melo exit(1); 76172b8fa17SArnaldo Carvalho de Melo } 76272b8fa17SArnaldo Carvalho de Melo 76372b8fa17SArnaldo Carvalho de Melo return; 76472b8fa17SArnaldo Carvalho de Melo } 76572b8fa17SArnaldo Carvalho de Melo 7666cff0e8dSKirill Smelkov /* let's see, whether we need to install initial sym_filter_entry */ 7676cff0e8dSKirill Smelkov if (sym_filter_entry_sched) { 768c97cf422SArnaldo Carvalho de Melo top.sym_filter_entry = sym_filter_entry_sched; 7696cff0e8dSKirill Smelkov sym_filter_entry_sched = NULL; 770c97cf422SArnaldo Carvalho de Melo if (parse_source(top.sym_filter_entry) < 0) { 771c97cf422SArnaldo Carvalho de Melo struct symbol *sym = sym_entry__symbol(top.sym_filter_entry); 772b0a9ab62SArnaldo Carvalho de Melo 773b0a9ab62SArnaldo Carvalho de Melo pr_err("Can't annotate %s", sym->name); 774878b439dSArnaldo Carvalho de Melo if (top.sym_filter_entry->map->dso->symtab_type == SYMTAB__KALLSYMS) { 775b0a9ab62SArnaldo Carvalho de Melo pr_err(": No vmlinux file was found in the path:\n"); 7765ad90e4eSArnaldo Carvalho de Melo machine__fprintf_vmlinux_path(machine, stderr); 777b0a9ab62SArnaldo Carvalho de Melo } else 778b0a9ab62SArnaldo Carvalho de Melo pr_err(".\n"); 779b0a9ab62SArnaldo Carvalho de Melo exit(1); 780b0a9ab62SArnaldo Carvalho de Melo } 7816cff0e8dSKirill Smelkov } 7826cff0e8dSKirill Smelkov 7831ed091c4SArnaldo Carvalho de Melo syme = symbol__priv(al.sym); 784171b3be9SArnaldo Carvalho de Melo if (!al.sym->ignore) { 78570db7533SArnaldo Carvalho de Melo struct perf_evsel *evsel; 78670db7533SArnaldo Carvalho de Melo 7878c3e10ebSArnaldo Carvalho de Melo evsel = perf_evlist__id2evsel(top.evlist, sample->id); 78870db7533SArnaldo Carvalho de Melo assert(evsel != NULL); 78970db7533SArnaldo Carvalho de Melo syme->count[evsel->idx]++; 79069aad6f1SArnaldo Carvalho de Melo record_precise_ip(syme, evsel->idx, ip); 7918c3e10ebSArnaldo Carvalho de Melo pthread_mutex_lock(&top.active_symbols_lock); 7925807806aSArnaldo Carvalho de Melo if (list_empty(&syme->node) || !syme->node.next) { 7935807806aSArnaldo Carvalho de Melo static bool first = true; 79486470930SIngo Molnar __list_insert_active_sym(syme); 7955807806aSArnaldo Carvalho de Melo if (first) { 7965807806aSArnaldo Carvalho de Melo pthread_cond_broadcast(&top.active_symbols_cond); 7975807806aSArnaldo Carvalho de Melo first = false; 7985807806aSArnaldo Carvalho de Melo } 7995807806aSArnaldo Carvalho de Melo } 8008c3e10ebSArnaldo Carvalho de Melo pthread_mutex_unlock(&top.active_symbols_lock); 80186470930SIngo Molnar } 80286470930SIngo Molnar } 80386470930SIngo Molnar 804*aece948fSArnaldo Carvalho de Melo static void perf_session__mmap_read_idx(struct perf_session *self, int idx) 80586470930SIngo Molnar { 8068d50e5b4SArnaldo Carvalho de Melo struct perf_sample sample; 8078115d60cSArnaldo Carvalho de Melo union perf_event *event; 80886470930SIngo Molnar 809*aece948fSArnaldo Carvalho de Melo while ((event = perf_evlist__mmap_read(top.evlist, idx)) != NULL) { 810d0dd74e8SArnaldo Carvalho de Melo perf_session__parse_sample(self, event, &sample); 81104391debSArnaldo Carvalho de Melo 8125b2bb75aSArnaldo Carvalho de Melo if (event->header.type == PERF_RECORD_SAMPLE) 8138115d60cSArnaldo Carvalho de Melo perf_event__process_sample(event, &sample, self); 8145b2bb75aSArnaldo Carvalho de Melo else 8158115d60cSArnaldo Carvalho de Melo perf_event__process(event, &sample, self); 81686470930SIngo Molnar } 81786470930SIngo Molnar } 81886470930SIngo Molnar 819d8f66248SArnaldo Carvalho de Melo static void perf_session__mmap_read(struct perf_session *self) 8202f01190aSFrederic Weisbecker { 82170db7533SArnaldo Carvalho de Melo int i; 8222f01190aSFrederic Weisbecker 823*aece948fSArnaldo Carvalho de Melo for (i = 0; i < top.evlist->nr_mmaps; i++) 824*aece948fSArnaldo Carvalho de Melo perf_session__mmap_read_idx(self, i); 8252f01190aSFrederic Weisbecker } 8262f01190aSFrederic Weisbecker 82772cb7013SArnaldo Carvalho de Melo static void start_counters(struct perf_evlist *evlist) 82872cb7013SArnaldo Carvalho de Melo { 82972cb7013SArnaldo Carvalho de Melo struct perf_evsel *counter; 83072cb7013SArnaldo Carvalho de Melo 83172cb7013SArnaldo Carvalho de Melo list_for_each_entry(counter, &evlist->entries, node) { 83272cb7013SArnaldo Carvalho de Melo struct perf_event_attr *attr = &counter->attr; 83372cb7013SArnaldo Carvalho de Melo 83472cb7013SArnaldo Carvalho de Melo attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; 83572cb7013SArnaldo Carvalho de Melo 8368c3e10ebSArnaldo Carvalho de Melo if (top.freq) { 83772cb7013SArnaldo Carvalho de Melo attr->sample_type |= PERF_SAMPLE_PERIOD; 83872cb7013SArnaldo Carvalho de Melo attr->freq = 1; 8398c3e10ebSArnaldo Carvalho de Melo attr->sample_freq = top.freq; 84072cb7013SArnaldo Carvalho de Melo } 84172cb7013SArnaldo Carvalho de Melo 84270db7533SArnaldo Carvalho de Melo if (evlist->nr_entries > 1) { 84370db7533SArnaldo Carvalho de Melo attr->sample_type |= PERF_SAMPLE_ID; 84470db7533SArnaldo Carvalho de Melo attr->read_format |= PERF_FORMAT_ID; 84570db7533SArnaldo Carvalho de Melo } 84670db7533SArnaldo Carvalho de Melo 84772cb7013SArnaldo Carvalho de Melo attr->mmap = 1; 8485d2cd909SArnaldo Carvalho de Melo attr->inherit = inherit; 84972cb7013SArnaldo Carvalho de Melo try_again: 8508c3e10ebSArnaldo Carvalho de Melo if (perf_evsel__open(counter, top.evlist->cpus, 8515d2cd909SArnaldo Carvalho de Melo top.evlist->threads, group) < 0) { 85272cb7013SArnaldo Carvalho de Melo int err = errno; 85372cb7013SArnaldo Carvalho de Melo 854c286c419SArnaldo Carvalho de Melo if (err == EPERM || err == EACCES) { 855c286c419SArnaldo Carvalho de Melo ui__warning_paranoid(); 856c286c419SArnaldo Carvalho de Melo goto out_err; 857c286c419SArnaldo Carvalho de Melo } 85872cb7013SArnaldo Carvalho de Melo /* 85972cb7013SArnaldo Carvalho de Melo * If it's cycles then fall back to hrtimer 86072cb7013SArnaldo Carvalho de Melo * based cpu-clock-tick sw counter, which 86172cb7013SArnaldo Carvalho de Melo * is always available even if no PMU support: 86272cb7013SArnaldo Carvalho de Melo */ 86372cb7013SArnaldo Carvalho de Melo if (attr->type == PERF_TYPE_HARDWARE && 86472cb7013SArnaldo Carvalho de Melo attr->config == PERF_COUNT_HW_CPU_CYCLES) { 86572cb7013SArnaldo Carvalho de Melo if (verbose) 866c286c419SArnaldo Carvalho de Melo ui__warning("Cycles event not supported,\n" 867c286c419SArnaldo Carvalho de Melo "trying to fall back to cpu-clock-ticks\n"); 86872cb7013SArnaldo Carvalho de Melo 86972cb7013SArnaldo Carvalho de Melo attr->type = PERF_TYPE_SOFTWARE; 87072cb7013SArnaldo Carvalho de Melo attr->config = PERF_COUNT_SW_CPU_CLOCK; 87172cb7013SArnaldo Carvalho de Melo goto try_again; 87272cb7013SArnaldo Carvalho de Melo } 873c286c419SArnaldo Carvalho de Melo 874ca6a4258SDavid Ahern if (err == ENOENT) { 875ca6a4258SDavid Ahern ui__warning("The %s event is not supported.\n", 876ca6a4258SDavid Ahern event_name(counter)); 877ca6a4258SDavid Ahern goto out_err; 878ca6a4258SDavid Ahern } 879ca6a4258SDavid Ahern 880c286c419SArnaldo Carvalho de Melo ui__warning("The sys_perf_event_open() syscall " 881c286c419SArnaldo Carvalho de Melo "returned with %d (%s). /bin/dmesg " 882c286c419SArnaldo Carvalho de Melo "may provide additional information.\n" 883c286c419SArnaldo Carvalho de Melo "No CONFIG_PERF_EVENTS=y kernel support " 884c286c419SArnaldo Carvalho de Melo "configured?\n", err, strerror(err)); 885c286c419SArnaldo Carvalho de Melo goto out_err; 88672cb7013SArnaldo Carvalho de Melo } 88772cb7013SArnaldo Carvalho de Melo } 88870db7533SArnaldo Carvalho de Melo 889c286c419SArnaldo Carvalho de Melo if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) { 890c286c419SArnaldo Carvalho de Melo ui__warning("Failed to mmap with %d (%s)\n", 891c286c419SArnaldo Carvalho de Melo errno, strerror(errno)); 892c286c419SArnaldo Carvalho de Melo goto out_err; 893c286c419SArnaldo Carvalho de Melo } 894c286c419SArnaldo Carvalho de Melo 895c286c419SArnaldo Carvalho de Melo return; 896c286c419SArnaldo Carvalho de Melo 897c286c419SArnaldo Carvalho de Melo out_err: 898c286c419SArnaldo Carvalho de Melo exit_browser(0); 899c286c419SArnaldo Carvalho de Melo exit(0); 90072cb7013SArnaldo Carvalho de Melo } 90172cb7013SArnaldo Carvalho de Melo 902716c69feSIngo Molnar static int __cmd_top(void) 903716c69feSIngo Molnar { 904716c69feSIngo Molnar pthread_t thread; 905fb7d0b3cSKyle McMartin int ret __used; 906d8f66248SArnaldo Carvalho de Melo /* 907b3165f41SArnaldo Carvalho de Melo * FIXME: perf_session__new should allow passing a O_MMAP, so that all this 908b3165f41SArnaldo Carvalho de Melo * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. 909d8f66248SArnaldo Carvalho de Melo */ 91021ef97f0SIan Munsie struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false, NULL); 911b3165f41SArnaldo Carvalho de Melo if (session == NULL) 912b3165f41SArnaldo Carvalho de Melo return -ENOMEM; 913716c69feSIngo Molnar 9148c3e10ebSArnaldo Carvalho de Melo if (top.target_tid != -1) 9157c940c18SArnaldo Carvalho de Melo perf_event__synthesize_thread_map(top.evlist->threads, 9167c940c18SArnaldo Carvalho de Melo perf_event__process, session); 9175b2bb75aSArnaldo Carvalho de Melo else 9188115d60cSArnaldo Carvalho de Melo perf_event__synthesize_threads(perf_event__process, session); 9195b2bb75aSArnaldo Carvalho de Melo 9208c3e10ebSArnaldo Carvalho de Melo start_counters(top.evlist); 921a91e5431SArnaldo Carvalho de Melo session->evlist = top.evlist; 922a91e5431SArnaldo Carvalho de Melo perf_session__update_sample_type(session); 92386470930SIngo Molnar 9242f01190aSFrederic Weisbecker /* Wait for a minimal set of events before starting the snapshot */ 9258c3e10ebSArnaldo Carvalho de Melo poll(top.evlist->pollfd, top.evlist->nr_fds, 100); 9262f01190aSFrederic Weisbecker 927d8f66248SArnaldo Carvalho de Melo perf_session__mmap_read(session); 9282f01190aSFrederic Weisbecker 929c0443df1SArnaldo Carvalho de Melo if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui : 930c0443df1SArnaldo Carvalho de Melo display_thread), session)) { 93186470930SIngo Molnar printf("Could not create display thread.\n"); 93286470930SIngo Molnar exit(-1); 93386470930SIngo Molnar } 93486470930SIngo Molnar 93586470930SIngo Molnar if (realtime_prio) { 93686470930SIngo Molnar struct sched_param param; 93786470930SIngo Molnar 93886470930SIngo Molnar param.sched_priority = realtime_prio; 93986470930SIngo Molnar if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { 94086470930SIngo Molnar printf("Could not set realtime priority.\n"); 94186470930SIngo Molnar exit(-1); 94286470930SIngo Molnar } 94386470930SIngo Molnar } 94486470930SIngo Molnar 94586470930SIngo Molnar while (1) { 9468c3e10ebSArnaldo Carvalho de Melo u64 hits = top.samples; 94786470930SIngo Molnar 948d8f66248SArnaldo Carvalho de Melo perf_session__mmap_read(session); 94986470930SIngo Molnar 9508c3e10ebSArnaldo Carvalho de Melo if (hits == top.samples) 9518c3e10ebSArnaldo Carvalho de Melo ret = poll(top.evlist->pollfd, top.evlist->nr_fds, 100); 95286470930SIngo Molnar } 95386470930SIngo Molnar 95486470930SIngo Molnar return 0; 95586470930SIngo Molnar } 95686470930SIngo Molnar 95786470930SIngo Molnar static const char * const top_usage[] = { 95886470930SIngo Molnar "perf top [<options>]", 95986470930SIngo Molnar NULL 96086470930SIngo Molnar }; 96186470930SIngo Molnar 96286470930SIngo Molnar static const struct option options[] = { 9638c3e10ebSArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &top.evlist, "event", 96486470930SIngo Molnar "event selector. use 'perf list' to list available events", 96586470930SIngo Molnar parse_events), 96686470930SIngo Molnar OPT_INTEGER('c', "count", &default_interval, 96786470930SIngo Molnar "event period to sample"), 9688c3e10ebSArnaldo Carvalho de Melo OPT_INTEGER('p', "pid", &top.target_pid, 969d6d901c2SZhang, Yanmin "profile events on existing process id"), 9708c3e10ebSArnaldo Carvalho de Melo OPT_INTEGER('t', "tid", &top.target_tid, 971d6d901c2SZhang, Yanmin "profile events on existing thread id"), 97286470930SIngo Molnar OPT_BOOLEAN('a', "all-cpus", &system_wide, 97386470930SIngo Molnar "system-wide collection from all CPUs"), 9748c3e10ebSArnaldo Carvalho de Melo OPT_STRING('C', "cpu", &top.cpu_list, "cpu", 975c45c6ea2SStephane Eranian "list of cpus to monitor"), 976b32d133aSArnaldo Carvalho de Melo OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 977b32d133aSArnaldo Carvalho de Melo "file", "vmlinux pathname"), 9788c3e10ebSArnaldo Carvalho de Melo OPT_BOOLEAN('K', "hide_kernel_symbols", &top.hide_kernel_symbols, 9798ffcda17SArnaldo Carvalho de Melo "hide kernel symbols"), 9801967936dSArnaldo Carvalho de Melo OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"), 98186470930SIngo Molnar OPT_INTEGER('r', "realtime", &realtime_prio, 98286470930SIngo Molnar "collect data with this RT SCHED_FIFO priority"), 9838c3e10ebSArnaldo Carvalho de Melo OPT_INTEGER('d', "delay", &top.delay_secs, 98486470930SIngo Molnar "number of seconds to delay between refreshes"), 98586470930SIngo Molnar OPT_BOOLEAN('D', "dump-symtab", &dump_symtab, 98686470930SIngo Molnar "dump the symbol table used for profiling"), 9878c3e10ebSArnaldo Carvalho de Melo OPT_INTEGER('f', "count-filter", &top.count_filter, 98886470930SIngo Molnar "only display functions with more events than this"), 98986470930SIngo Molnar OPT_BOOLEAN('g', "group", &group, 99086470930SIngo Molnar "put the counters into a counter group"), 9910fdc7e67SMike Galbraith OPT_BOOLEAN('i', "inherit", &inherit, 9920fdc7e67SMike Galbraith "child tasks inherit counters"), 993923c42c1SMike Galbraith OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name", 9946cff0e8dSKirill Smelkov "symbol to annotate"), 9958c3e10ebSArnaldo Carvalho de Melo OPT_BOOLEAN('z', "zero", &top.zero, 99686470930SIngo Molnar "zero history across updates"), 9978c3e10ebSArnaldo Carvalho de Melo OPT_INTEGER('F', "freq", &top.freq, 99886470930SIngo Molnar "profile at this frequency"), 9998c3e10ebSArnaldo Carvalho de Melo OPT_INTEGER('E', "entries", &top.print_entries, 100086470930SIngo Molnar "display this many functions"), 10018c3e10ebSArnaldo Carvalho de Melo OPT_BOOLEAN('U', "hide_user_symbols", &top.hide_user_symbols, 10028ffcda17SArnaldo Carvalho de Melo "hide user symbols"), 1003c0443df1SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "tui", &use_tui, "Use the TUI interface"), 1004c0443df1SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "stdio", &use_stdio, "Use the stdio interface"), 1005c0555642SIan Munsie OPT_INCR('v', "verbose", &verbose, 10063da297a6SIngo Molnar "be more verbose (show counter open errors, etc)"), 100786470930SIngo Molnar OPT_END() 100886470930SIngo Molnar }; 100986470930SIngo Molnar 1010f37a291cSIngo Molnar int cmd_top(int argc, const char **argv, const char *prefix __used) 101186470930SIngo Molnar { 101269aad6f1SArnaldo Carvalho de Melo struct perf_evsel *pos; 101369aad6f1SArnaldo Carvalho de Melo int status = -ENOMEM; 101486470930SIngo Molnar 10158c3e10ebSArnaldo Carvalho de Melo top.evlist = perf_evlist__new(NULL, NULL); 10168c3e10ebSArnaldo Carvalho de Melo if (top.evlist == NULL) 1017361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 1018361c99a6SArnaldo Carvalho de Melo 101986470930SIngo Molnar page_size = sysconf(_SC_PAGE_SIZE); 102086470930SIngo Molnar 102186470930SIngo Molnar argc = parse_options(argc, argv, options, top_usage, 0); 102286470930SIngo Molnar if (argc) 102386470930SIngo Molnar usage_with_options(top_usage, options); 102486470930SIngo Molnar 1025c0443df1SArnaldo Carvalho de Melo /* 1026c0443df1SArnaldo Carvalho de Melo * XXX For now start disabled, only using TUI if explicitely asked for. 1027c0443df1SArnaldo Carvalho de Melo * Change that when handle_keys equivalent gets written, live annotation 1028c0443df1SArnaldo Carvalho de Melo * done, etc. 1029c0443df1SArnaldo Carvalho de Melo */ 1030c0443df1SArnaldo Carvalho de Melo use_browser = 0; 1031c0443df1SArnaldo Carvalho de Melo 1032c0443df1SArnaldo Carvalho de Melo if (use_stdio) 1033c0443df1SArnaldo Carvalho de Melo use_browser = 0; 1034c0443df1SArnaldo Carvalho de Melo else if (use_tui) 1035c0443df1SArnaldo Carvalho de Melo use_browser = 1; 1036c0443df1SArnaldo Carvalho de Melo 1037c0443df1SArnaldo Carvalho de Melo setup_browser(false); 1038c0443df1SArnaldo Carvalho de Melo 103986470930SIngo Molnar /* CPU and PID are mutually exclusive */ 10408c3e10ebSArnaldo Carvalho de Melo if (top.target_tid > 0 && top.cpu_list) { 104186470930SIngo Molnar printf("WARNING: PID switch overriding CPU\n"); 104286470930SIngo Molnar sleep(1); 10438c3e10ebSArnaldo Carvalho de Melo top.cpu_list = NULL; 104486470930SIngo Molnar } 104586470930SIngo Molnar 10468c3e10ebSArnaldo Carvalho de Melo if (top.target_pid != -1) 10478c3e10ebSArnaldo Carvalho de Melo top.target_tid = top.target_pid; 10487e2ed097SArnaldo Carvalho de Melo 10498c3e10ebSArnaldo Carvalho de Melo if (perf_evlist__create_maps(top.evlist, top.target_pid, 10508c3e10ebSArnaldo Carvalho de Melo top.target_tid, top.cpu_list) < 0) 10517e2ed097SArnaldo Carvalho de Melo usage_with_options(top_usage, options); 10527e2ed097SArnaldo Carvalho de Melo 10538c3e10ebSArnaldo Carvalho de Melo if (!top.evlist->nr_entries && 10548c3e10ebSArnaldo Carvalho de Melo perf_evlist__add_default(top.evlist) < 0) { 105569aad6f1SArnaldo Carvalho de Melo pr_err("Not enough memory for event selector list\n"); 105669aad6f1SArnaldo Carvalho de Melo return -ENOMEM; 105769aad6f1SArnaldo Carvalho de Melo } 10585a8e5a30SArnaldo Carvalho de Melo 10598c3e10ebSArnaldo Carvalho de Melo if (top.delay_secs < 1) 10608c3e10ebSArnaldo Carvalho de Melo top.delay_secs = 1; 106186470930SIngo Molnar 10627e4ff9e3SMike Galbraith /* 10637e4ff9e3SMike Galbraith * User specified count overrides default frequency. 10647e4ff9e3SMike Galbraith */ 10657e4ff9e3SMike Galbraith if (default_interval) 10668c3e10ebSArnaldo Carvalho de Melo top.freq = 0; 10678c3e10ebSArnaldo Carvalho de Melo else if (top.freq) { 10688c3e10ebSArnaldo Carvalho de Melo default_interval = top.freq; 10697e4ff9e3SMike Galbraith } else { 10707e4ff9e3SMike Galbraith fprintf(stderr, "frequency and count are zero, aborting\n"); 10717e4ff9e3SMike Galbraith exit(EXIT_FAILURE); 10727e4ff9e3SMike Galbraith } 10737e4ff9e3SMike Galbraith 10748c3e10ebSArnaldo Carvalho de Melo list_for_each_entry(pos, &top.evlist->entries, node) { 10758c3e10ebSArnaldo Carvalho de Melo if (perf_evsel__alloc_fd(pos, top.evlist->cpus->nr, 10768c3e10ebSArnaldo Carvalho de Melo top.evlist->threads->nr) < 0) 107769aad6f1SArnaldo Carvalho de Melo goto out_free_fd; 107869aad6f1SArnaldo Carvalho de Melo /* 107969aad6f1SArnaldo Carvalho de Melo * Fill in the ones not specifically initialized via -c: 108069aad6f1SArnaldo Carvalho de Melo */ 108169aad6f1SArnaldo Carvalho de Melo if (pos->attr.sample_period) 108269aad6f1SArnaldo Carvalho de Melo continue; 108369aad6f1SArnaldo Carvalho de Melo 108469aad6f1SArnaldo Carvalho de Melo pos->attr.sample_period = default_interval; 108569aad6f1SArnaldo Carvalho de Melo } 108669aad6f1SArnaldo Carvalho de Melo 10878c3e10ebSArnaldo Carvalho de Melo if (perf_evlist__alloc_pollfd(top.evlist) < 0 || 10888c3e10ebSArnaldo Carvalho de Melo perf_evlist__alloc_mmap(top.evlist) < 0) 10895c581041SArnaldo Carvalho de Melo goto out_free_fd; 10905c581041SArnaldo Carvalho de Melo 10918c3e10ebSArnaldo Carvalho de Melo top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node); 1092cc841580SArnaldo Carvalho de Melo 109336532461SArnaldo Carvalho de Melo symbol_conf.priv_size = (sizeof(struct sym_entry) + sizeof(struct annotation) + 10948c3e10ebSArnaldo Carvalho de Melo (top.evlist->nr_entries + 1) * sizeof(unsigned long)); 109569aad6f1SArnaldo Carvalho de Melo 109669aad6f1SArnaldo Carvalho de Melo symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); 109769aad6f1SArnaldo Carvalho de Melo if (symbol__init() < 0) 109869aad6f1SArnaldo Carvalho de Melo return -1; 109969aad6f1SArnaldo Carvalho de Melo 110013cc5079SArnaldo Carvalho de Melo get_term_dimensions(&winsize); 11018c3e10ebSArnaldo Carvalho de Melo if (top.print_entries == 0) { 110213cc5079SArnaldo Carvalho de Melo update_print_entries(&winsize); 11033b6ed988SArnaldo Carvalho de Melo signal(SIGWINCH, sig_winch_handler); 11043b6ed988SArnaldo Carvalho de Melo } 11053b6ed988SArnaldo Carvalho de Melo 110669aad6f1SArnaldo Carvalho de Melo status = __cmd_top(); 110769aad6f1SArnaldo Carvalho de Melo out_free_fd: 11088c3e10ebSArnaldo Carvalho de Melo perf_evlist__delete(top.evlist); 110969aad6f1SArnaldo Carvalho de Melo 111069aad6f1SArnaldo Carvalho de Melo return status; 111186470930SIngo Molnar } 1112