Blame view

tools/perf/builtin-top.c 31.1 KB
078006012   Ingo Molnar   perf_counter tool...
1
  /*
bf9e18763   Ingo Molnar   perf_counter tool...
2
3
4
5
6
7
   * builtin-top.c
   *
   * Builtin top command: Display a continuously updated profile of
   * any workload, CPU or specific PID.
   *
   * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
8
   *		 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
bf9e18763   Ingo Molnar   perf_counter tool...
9
10
11
12
13
14
15
16
17
18
   *
   * Improvements and fixes by:
   *
   *   Arjan van de Ven <arjan@linux.intel.com>
   *   Yanmin Zhang <yanmin.zhang@intel.com>
   *   Wu Fengguang <fengguang.wu@intel.com>
   *   Mike Galbraith <efault@gmx.de>
   *   Paul Mackerras <paulus@samba.org>
   *
   * Released under the GPL v2. (and only v2, not any later version)
078006012   Ingo Molnar   perf_counter tool...
19
   */
bf9e18763   Ingo Molnar   perf_counter tool...
20
  #include "builtin.h"
078006012   Ingo Molnar   perf_counter tool...
21

1a482f38c   Peter Zijlstra   perf_counter: Fix...
22
  #include "perf.h"
bf9e18763   Ingo Molnar   perf_counter tool...
23

36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
24
  #include "util/annotate.h"
c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
25
  #include "util/cache.h"
8fc0321f1   Ingo Molnar   perf_counter tool...
26
  #include "util/color.h"
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
27
  #include "util/evlist.h"
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
28
  #include "util/evsel.h"
b3165f414   Arnaldo Carvalho de Melo   perf session: Mov...
29
30
  #include "util/session.h"
  #include "util/symbol.h"
439d473b4   Arnaldo Carvalho de Melo   perf tools: Rewri...
31
  #include "util/thread.h"
fd78260b5   Arnaldo Carvalho de Melo   perf threads: Mov...
32
  #include "util/thread_map.h"
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
33
  #include "util/top.h"
148be2c15   Ingo Molnar   perf_counter tool...
34
  #include "util/util.h"
43cbcd8ac   Arnaldo Carvalho de Melo   perf_counter tool...
35
  #include <linux/rbtree.h>
b456bae0f   Ingo Molnar   perf top: Convert...
36
37
  #include "util/parse-options.h"
  #include "util/parse-events.h"
a12b51c47   Paul Mackerras   perf tools: Fix s...
38
  #include "util/cpumap.h"
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
39
  #include "util/xyarray.h"
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
40
  #include "util/sort.h"
078006012   Ingo Molnar   perf_counter tool...
41

8f28827a1   Frederic Weisbecker   perf tools: Libra...
42
  #include "util/debug.h"
078006012   Ingo Molnar   perf_counter tool...
43
44
  #include <assert.h>
  #include <fcntl.h>
0e9b20b8a   Ingo Molnar   perf record: Conv...
45

078006012   Ingo Molnar   perf_counter tool...
46
  #include <stdio.h>
923c42c19   Mike Galbraith   perf_counter tool...
47
48
  #include <termios.h>
  #include <unistd.h>
9486aa387   Arnaldo Carvalho de Melo   perf tools: Fix 6...
49
  #include <inttypes.h>
0e9b20b8a   Ingo Molnar   perf record: Conv...
50

078006012   Ingo Molnar   perf_counter tool...
51
  #include <errno.h>
078006012   Ingo Molnar   perf_counter tool...
52
53
  #include <time.h>
  #include <sched.h>
078006012   Ingo Molnar   perf_counter tool...
54
55
56
57
58
59
60
61
62
63
64
  
  #include <sys/syscall.h>
  #include <sys/ioctl.h>
  #include <sys/poll.h>
  #include <sys/prctl.h>
  #include <sys/wait.h>
  #include <sys/uio.h>
  #include <sys/mman.h>
  
  #include <linux/unistd.h>
  #include <linux/types.h>
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
65
66
67
  static struct perf_top top = {
  	.count_filter		= 5,
  	.delay_secs		= 2,
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
68
69
  	.target_pid		= -1,
  	.target_tid		= -1,
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
70
71
  	.freq			= 1000, /* 1 KHz */
  };
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
72

c05556421   Ian Munsie   perf: Fix endiann...
73
  static bool			system_wide			=  false;
078006012   Ingo Molnar   perf_counter tool...
74

c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
75
  static bool			use_tui, use_stdio;
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
76
77
78
79
  static bool			sort_has_symbols;
  
  static bool			dont_use_callchains;
  static char			callchain_default_opt[]		= "fractal,0.5,callee";
7e4ff9e3e   Mike Galbraith   perf tools: Fix c...
80
  static int			default_interval		=      0;
078006012   Ingo Molnar   perf_counter tool...
81

5f6f55809   Arnaldo Carvalho de Melo   perf top: Handle ...
82
  static bool			kptr_restrict_warned;
e4a338d05   Arnaldo Carvalho de Melo   perf top: Don't s...
83
  static bool			vmlinux_warned;
c05556421   Ian Munsie   perf: Fix endiann...
84
  static bool			inherit				=  false;
1967936d6   Arnaldo Carvalho de Melo   perf options: Che...
85
  static int			realtime_prio			=      0;
c05556421   Ian Munsie   perf: Fix endiann...
86
  static bool			group				=  false;
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
87
  static bool			sample_id_all_avail		=   true;
70db7533c   Arnaldo Carvalho de Melo   perf evlist: Move...
88
  static unsigned int		mmap_pages			=    128;
078006012   Ingo Molnar   perf_counter tool...
89

c05556421   Ian Munsie   perf: Fix endiann...
90
  static bool			dump_symtab                     =  false;
078006012   Ingo Molnar   perf_counter tool...
91

13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
92
  static struct winsize		winsize;
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
93

edb7c60e2   Arnaldo Carvalho de Melo   perf options: Typ...
94
  static const char		*sym_filter			=   NULL;
42e59d7d1   Ingo Molnar   perf tools: Defau...
95
  static int			sym_pcnt_filter			=      5;
078006012   Ingo Molnar   perf_counter tool...
96

923c42c19   Mike Galbraith   perf_counter tool...
97
98
99
  /*
   * Source functions
   */
895f0edc3   Arnaldo Carvalho de Melo   perf top: Export ...
100
  void get_term_dimensions(struct winsize *ws)
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
101
  {
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
102
103
104
105
106
107
108
109
110
111
  	char *s = getenv("LINES");
  
  	if (s != NULL) {
  		ws->ws_row = atoi(s);
  		s = getenv("COLUMNS");
  		if (s != NULL) {
  			ws->ws_col = atoi(s);
  			if (ws->ws_row && ws->ws_col)
  				return;
  		}
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
112
  	}
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
113
114
115
116
  #ifdef TIOCGWINSZ
  	if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
  	    ws->ws_row && ws->ws_col)
  		return;
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
117
  #endif
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
118
119
  	ws->ws_row = 25;
  	ws->ws_col = 80;
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
120
  }
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
121
  static void update_print_entries(struct winsize *ws)
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
122
  {
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
123
  	top.print_entries = ws->ws_row;
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
124

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
125
126
  	if (top.print_entries > 9)
  		top.print_entries -= 9;
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
127
128
129
130
  }
  
  static void sig_winch_handler(int sig __used)
  {
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
131
132
  	get_term_dimensions(&winsize);
  	update_print_entries(&winsize);
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
133
  }
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
134
  static int parse_source(struct hist_entry *he)
923c42c19   Mike Galbraith   perf_counter tool...
135
136
  {
  	struct symbol *sym;
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
137
  	struct annotation *notes;
439d473b4   Arnaldo Carvalho de Melo   perf tools: Rewri...
138
  	struct map *map;
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
139
  	int err = -1;
923c42c19   Mike Galbraith   perf_counter tool...
140

ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
141
  	if (!he || !he->ms.sym)
b0a9ab62a   Arnaldo Carvalho de Melo   perf top: Properl...
142
  		return -1;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
143
144
  	sym = he->ms.sym;
  	map = he->ms.map;
b0a9ab62a   Arnaldo Carvalho de Melo   perf top: Properl...
145
146
147
148
  
  	/*
  	 * We can't annotate with just /proc/kallsyms
  	 */
878b439dc   Arnaldo Carvalho de Melo   perf symbols: Ren...
149
  	if (map->dso->symtab_type == SYMTAB__KALLSYMS) {
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
150
151
152
153
  		pr_err("Can't annotate %s: No vmlinux file was found in the "
  		       "path
  ", sym->name);
  		sleep(1);
b0a9ab62a   Arnaldo Carvalho de Melo   perf top: Properl...
154
  		return -1;
b269876c8   Arnaldo Carvalho de Melo   perf top: Don't a...
155
  	}
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
156
157
158
  	notes = symbol__annotation(sym);
  	if (notes->src != NULL) {
  		pthread_mutex_lock(&notes->lock);
923c42c19   Mike Galbraith   perf_counter tool...
159
160
  		goto out_assign;
  	}
923c42c19   Mike Galbraith   perf_counter tool...
161

ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
162
  	pthread_mutex_lock(&notes->lock);
923c42c19   Mike Galbraith   perf_counter tool...
163

36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
164
  	if (symbol__alloc_hist(sym, top.evlist->nr_entries) < 0) {
c97cf4221   Arnaldo Carvalho de Melo   perf top: Live TU...
165
  		pthread_mutex_unlock(&notes->lock);
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
166
167
168
  		pr_err("Not enough memory for annotating '%s' symbol!
  ",
  		       sym->name);
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
169
  		sleep(1);
c97cf4221   Arnaldo Carvalho de Melo   perf top: Live TU...
170
  		return err;
923c42c19   Mike Galbraith   perf_counter tool...
171
  	}
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
172

ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
173
  	err = symbol__annotate(sym, map, 0);
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
174
  	if (err == 0) {
923c42c19   Mike Galbraith   perf_counter tool...
175
  out_assign:
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
176
  		top.sym_filter_entry = he;
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
177
  	}
c97cf4221   Arnaldo Carvalho de Melo   perf top: Live TU...
178

ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
179
  	pthread_mutex_unlock(&notes->lock);
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
180
  	return err;
923c42c19   Mike Galbraith   perf_counter tool...
181
  }
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
182
  static void __zero_source_counters(struct hist_entry *he)
923c42c19   Mike Galbraith   perf_counter tool...
183
  {
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
184
  	struct symbol *sym = he->ms.sym;
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
185
  	symbol__annotate_zero_histograms(sym);
923c42c19   Mike Galbraith   perf_counter tool...
186
  }
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
187
  static void record_precise_ip(struct hist_entry *he, int counter, u64 ip)
923c42c19   Mike Galbraith   perf_counter tool...
188
  {
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
189
190
  	struct annotation *notes;
  	struct symbol *sym;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
191
  	if (he == NULL || he->ms.sym == NULL ||
f9e3d4b1a   Arnaldo Carvalho de Melo   perf top: Fix liv...
192
193
  	    ((top.sym_filter_entry == NULL ||
  	      top.sym_filter_entry->ms.sym != he->ms.sym) && use_browser != 1))
923c42c19   Mike Galbraith   perf_counter tool...
194
  		return;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
195
  	sym = he->ms.sym;
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
196
197
198
  	notes = symbol__annotation(sym);
  
  	if (pthread_mutex_trylock(&notes->lock))
923c42c19   Mike Galbraith   perf_counter tool...
199
  		return;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
200
201
202
203
204
205
206
207
208
209
210
211
  	if (notes->src == NULL &&
  	    symbol__alloc_hist(sym, top.evlist->nr_entries) < 0) {
  		pthread_mutex_unlock(&notes->lock);
  		pr_err("Not enough memory for annotating '%s' symbol!
  ",
  		       sym->name);
  		sleep(1);
  		return;
  	}
  
  	ip = he->ms.map->map_ip(he->ms.map, ip);
  	symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
c7ad21af2   Arnaldo Carvalho de Melo   perf top: Use a m...
212

ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
213
  	pthread_mutex_unlock(&notes->lock);
923c42c19   Mike Galbraith   perf_counter tool...
214
  }
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
215
  static void show_details(struct hist_entry *he)
923c42c19   Mike Galbraith   perf_counter tool...
216
  {
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
217
  	struct annotation *notes;
923c42c19   Mike Galbraith   perf_counter tool...
218
  	struct symbol *symbol;
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
219
  	int more;
923c42c19   Mike Galbraith   perf_counter tool...
220

ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
221
  	if (!he)
923c42c19   Mike Galbraith   perf_counter tool...
222
  		return;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
223
  	symbol = he->ms.sym;
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
224
225
226
227
228
229
  	notes = symbol__annotation(symbol);
  
  	pthread_mutex_lock(&notes->lock);
  
  	if (notes->src == NULL)
  		goto out_unlock;
923c42c19   Mike Galbraith   perf_counter tool...
230

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
231
232
  	printf("Showing %s for %s
  ", event_name(top.sym_evsel), symbol->name);
923c42c19   Mike Galbraith   perf_counter tool...
233
234
  	printf("  Events  Pcnt (>=%d%%)
  ", sym_pcnt_filter);
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
235
  	more = symbol__annotate_printf(symbol, he->ms.map, top.sym_evsel->idx,
d5e3d7470   Arnaldo Carvalho de Melo   perf annotate: Fi...
236
  				       0, sym_pcnt_filter, top.print_entries, 4);
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
237
238
239
  	if (top.zero)
  		symbol__annotate_zero_histogram(symbol, top.sym_evsel->idx);
  	else
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
240
  		symbol__annotate_decay_histogram(symbol, top.sym_evsel->idx);
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
241
  	if (more != 0)
923c42c19   Mike Galbraith   perf_counter tool...
242
243
  		printf("%d lines not displayed, maybe increase display entries [e]
  ", more);
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
244
245
  out_unlock:
  	pthread_mutex_unlock(&notes->lock);
923c42c19   Mike Galbraith   perf_counter tool...
246
  }
078006012   Ingo Molnar   perf_counter tool...
247

078006012   Ingo Molnar   perf_counter tool...
248
  static const char		CONSOLE_CLEAR[] = "";
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
249
250
251
252
253
  static struct hist_entry *
  	perf_session__add_hist_entry(struct perf_session *session,
  				     struct addr_location *al,
  				     struct perf_sample *sample,
  				     struct perf_evsel *evsel)
de04687f8   Arnaldo Carvalho de Melo   perf_counter tool...
254
  {
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
255
256
257
258
259
260
261
262
263
  	struct hist_entry *he;
  
  	he = __hists__add_entry(&evsel->hists, al, NULL, sample->period);
  	if (he == NULL)
  		return NULL;
  
  	session->hists.stats.total_period += sample->period;
  	hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
  	return he;
de04687f8   Arnaldo Carvalho de Melo   perf_counter tool...
264
  }
078006012   Ingo Molnar   perf_counter tool...
265

dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
266
  static void print_sym_table(void)
078006012   Ingo Molnar   perf_counter tool...
267
  {
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
268
269
  	char bf[160];
  	int printed = 0;
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
270
  	const int win_width = winsize.ws_col - 1;
d94b94305   Mike Galbraith   perf top: Reduce ...
271

0f5486b5c   Frederic Weisbecker   perf_counter: Sle...
272
  	puts(CONSOLE_CLEAR);
078006012   Ingo Molnar   perf_counter tool...
273

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
274
275
276
  	perf_top__header_snprintf(&top, bf, sizeof(bf));
  	printf("%s
  ", bf);
078006012   Ingo Molnar   perf_counter tool...
277

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
278
  	perf_top__reset_sample_counters(&top);
078006012   Ingo Molnar   perf_counter tool...
279

1a105f743   Arnaldo Carvalho de Melo   perf top: Suppres...
280
281
  	printf("%-*.*s
  ", win_width, win_width, graph_dotted_line);
078006012   Ingo Molnar   perf_counter tool...
282

7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
283
284
285
286
287
288
289
  	if (top.sym_evsel->hists.stats.nr_lost_warned !=
  	    top.sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST]) {
  		top.sym_evsel->hists.stats.nr_lost_warned =
  			top.sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST];
  		color_fprintf(stdout, PERF_COLOR_RED,
  			      "WARNING: LOST %d chunks, Check IO/CPU overload",
  			      top.sym_evsel->hists.stats.nr_lost_warned);
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
290
  		++printed;
93fc64f14   Arnaldo Carvalho de Melo   perf top: Switch ...
291
  	}
c97cf4221   Arnaldo Carvalho de Melo   perf top: Live TU...
292
293
  	if (top.sym_filter_entry) {
  		show_details(top.sym_filter_entry);
923c42c19   Mike Galbraith   perf_counter tool...
294
295
  		return;
  	}
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
296
297
  	hists__collapse_resort_threaded(&top.sym_evsel->hists);
  	hists__output_resort_threaded(&top.sym_evsel->hists);
b079d4e97   Arnaldo Carvalho de Melo   perf top: Honour ...
298
299
300
  	hists__decay_entries_threaded(&top.sym_evsel->hists,
  				      top.hide_user_symbols,
  				      top.hide_kernel_symbols);
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
301
  	hists__output_recalc_col_len(&top.sym_evsel->hists, winsize.ws_row - 3);
7cc017edb   Arnaldo Carvalho de Melo   perf top: Always ...
302
303
  	putchar('
  ');
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
304
305
  	hists__fprintf(&top.sym_evsel->hists, NULL, false, false,
  		       winsize.ws_row - 4 - printed, win_width, stdout);
078006012   Ingo Molnar   perf_counter tool...
306
  }
923c42c19   Mike Galbraith   perf_counter tool...
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
  static void prompt_integer(int *target, const char *msg)
  {
  	char *buf = malloc(0), *p;
  	size_t dummy = 0;
  	int tmp;
  
  	fprintf(stdout, "
  %s: ", msg);
  	if (getline(&buf, &dummy, stdin) < 0)
  		return;
  
  	p = strchr(buf, '
  ');
  	if (p)
  		*p = 0;
  
  	p = buf;
  	while(*p) {
  		if (!isdigit(*p))
  			goto out_free;
  		p++;
  	}
  	tmp = strtoul(buf, NULL, 10);
  	*target = tmp;
  out_free:
  	free(buf);
  }
  
  static void prompt_percent(int *target, const char *msg)
  {
  	int tmp = 0;
  
  	prompt_integer(&tmp, msg);
  	if (tmp >= 0 && tmp <= 100)
  		*target = tmp;
  }
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
343
  static void prompt_symbol(struct hist_entry **target, const char *msg)
923c42c19   Mike Galbraith   perf_counter tool...
344
345
  {
  	char *buf = malloc(0), *p;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
346
347
  	struct hist_entry *syme = *target, *n, *found = NULL;
  	struct rb_node *next;
923c42c19   Mike Galbraith   perf_counter tool...
348
349
350
351
  	size_t dummy = 0;
  
  	/* zero counters of active symbol */
  	if (syme) {
923c42c19   Mike Galbraith   perf_counter tool...
352
353
  		__zero_source_counters(syme);
  		*target = NULL;
923c42c19   Mike Galbraith   perf_counter tool...
354
355
356
357
358
359
360
361
362
363
364
  	}
  
  	fprintf(stdout, "
  %s: ", msg);
  	if (getline(&buf, &dummy, stdin) < 0)
  		goto out_free;
  
  	p = strchr(buf, '
  ');
  	if (p)
  		*p = 0;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
365
366
367
368
369
  	next = rb_first(&top.sym_evsel->hists.entries);
  	while (next) {
  		n = rb_entry(next, struct hist_entry, rb_node);
  		if (n->ms.sym && !strcmp(buf, n->ms.sym->name)) {
  			found = n;
923c42c19   Mike Galbraith   perf_counter tool...
370
371
  			break;
  		}
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
372
  		next = rb_next(&n->rb_node);
923c42c19   Mike Galbraith   perf_counter tool...
373
374
375
  	}
  
  	if (!found) {
66aeb6d5c   Kirill Smelkov   perf top: Fix cod...
376
377
  		fprintf(stderr, "Sorry, %s is not active.
  ", buf);
923c42c19   Mike Galbraith   perf_counter tool...
378
379
380
381
382
383
384
385
  		sleep(1);
  		return;
  	} else
  		parse_source(found);
  
  out_free:
  	free(buf);
  }
091bd2e99   Mike Galbraith   perf top: Improve...
386
  static void print_mapped_keys(void)
923c42c19   Mike Galbraith   perf_counter tool...
387
  {
091bd2e99   Mike Galbraith   perf top: Improve...
388
  	char *name = NULL;
c97cf4221   Arnaldo Carvalho de Melo   perf top: Live TU...
389
  	if (top.sym_filter_entry) {
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
390
  		struct symbol *sym = top.sym_filter_entry->ms.sym;
091bd2e99   Mike Galbraith   perf top: Improve...
391
392
393
394
395
396
  		name = sym->name;
  	}
  
  	fprintf(stdout, "
  Mapped keys:
  ");
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
397
398
399
400
  	fprintf(stdout, "\t[d]     display refresh delay.             \t(%d)
  ", top.delay_secs);
  	fprintf(stdout, "\t[e]     display entries (lines).           \t(%d)
  ", top.print_entries);
091bd2e99   Mike Galbraith   perf top: Improve...
401

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
402
403
404
  	if (top.evlist->nr_entries > 1)
  		fprintf(stdout, "\t[E]     active event counter.              \t(%s)
  ", event_name(top.sym_evsel));
091bd2e99   Mike Galbraith   perf top: Improve...
405

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
406
407
  	fprintf(stdout, "\t[f]     profile display filter (count).    \t(%d)
  ", top.count_filter);
091bd2e99   Mike Galbraith   perf top: Improve...
408

6cff0e8db   Kirill Smelkov   perf top: Teach i...
409
410
411
412
413
414
  	fprintf(stdout, "\t[F]     annotate display filter (percent). \t(%d%%)
  ", sym_pcnt_filter);
  	fprintf(stdout, "\t[s]     annotate symbol.                   \t(%s)
  ", name?: "NULL");
  	fprintf(stdout, "\t[S]     stop annotation.
  ");
091bd2e99   Mike Galbraith   perf top: Improve...
415

8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
416
  	fprintf(stdout,
1a72cfa68   Kirill Smelkov   perf top: Fix hel...
417
418
  		"\t[K]     hide kernel_symbols symbols.     \t(%s)
  ",
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
419
  		top.hide_kernel_symbols ? "yes" : "no");
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
420
421
422
  	fprintf(stdout,
  		"\t[U]     hide user symbols.               \t(%s)
  ",
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
423
424
425
  		top.hide_user_symbols ? "yes" : "no");
  	fprintf(stdout, "\t[z]     toggle sample zeroing.             \t(%d)
  ", top.zero ? 1 : 0);
091bd2e99   Mike Galbraith   perf top: Improve...
426
427
428
429
430
431
432
433
434
435
436
437
438
  	fprintf(stdout, "\t[qQ]    quit.
  ");
  }
  
  static int key_mapped(int c)
  {
  	switch (c) {
  		case 'd':
  		case 'e':
  		case 'f':
  		case 'z':
  		case 'q':
  		case 'Q':
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
439
440
  		case 'K':
  		case 'U':
6cff0e8db   Kirill Smelkov   perf top: Teach i...
441
442
443
  		case 'F':
  		case 's':
  		case 'S':
091bd2e99   Mike Galbraith   perf top: Improve...
444
445
  			return 1;
  		case 'E':
b2b7e9eb2   Arnaldo Carvalho de Melo   perf top: Fix the...
446
  			return top.evlist->nr_entries > 1 ? 1 : 0;
83a0944fa   Ingo Molnar   perf: Enable more...
447
448
  		default:
  			break;
091bd2e99   Mike Galbraith   perf top: Improve...
449
450
451
  	}
  
  	return 0;
923c42c19   Mike Galbraith   perf_counter tool...
452
  }
dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
453
  static void handle_keypress(int c)
923c42c19   Mike Galbraith   perf_counter tool...
454
  {
091bd2e99   Mike Galbraith   perf top: Improve...
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
  	if (!key_mapped(c)) {
  		struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
  		struct termios tc, save;
  
  		print_mapped_keys();
  		fprintf(stdout, "
  Enter selection, or unmapped key to continue: ");
  		fflush(stdout);
  
  		tcgetattr(0, &save);
  		tc = save;
  		tc.c_lflag &= ~(ICANON | ECHO);
  		tc.c_cc[VMIN] = 0;
  		tc.c_cc[VTIME] = 0;
  		tcsetattr(0, TCSANOW, &tc);
  
  		poll(&stdin_poll, 1, -1);
  		c = getc(stdin);
  
  		tcsetattr(0, TCSAFLUSH, &save);
  		if (!key_mapped(c))
  			return;
  	}
923c42c19   Mike Galbraith   perf_counter tool...
478
479
  	switch (c) {
  		case 'd':
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
480
481
482
  			prompt_integer(&top.delay_secs, "Enter display delay");
  			if (top.delay_secs < 1)
  				top.delay_secs = 1;
923c42c19   Mike Galbraith   perf_counter tool...
483
484
  			break;
  		case 'e':
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
485
486
  			prompt_integer(&top.print_entries, "Enter display entries (lines)");
  			if (top.print_entries == 0) {
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
487
  				sig_winch_handler(SIGWINCH);
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
488
489
490
  				signal(SIGWINCH, sig_winch_handler);
  			} else
  				signal(SIGWINCH, SIG_DFL);
923c42c19   Mike Galbraith   perf_counter tool...
491
492
  			break;
  		case 'E':
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
493
  			if (top.evlist->nr_entries > 1) {
ce2d17ca7   Akihiro Nagai   perf top: Fix uni...
494
495
  				/* Select 0 as the default event: */
  				int counter = 0;
923c42c19   Mike Galbraith   perf_counter tool...
496
497
  				fprintf(stderr, "
  Available events:");
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
498

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
499
500
501
  				list_for_each_entry(top.sym_evsel, &top.evlist->entries, node)
  					fprintf(stderr, "
  \t%d %s", top.sym_evsel->idx, event_name(top.sym_evsel));
923c42c19   Mike Galbraith   perf_counter tool...
502

ec52d9765   Arnaldo Carvalho de Melo   perf top: Remove ...
503
  				prompt_integer(&counter, "Enter details event counter");
923c42c19   Mike Galbraith   perf_counter tool...
504

ec52d9765   Arnaldo Carvalho de Melo   perf top: Remove ...
505
  				if (counter >= top.evlist->nr_entries) {
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
506
  					top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
507
508
  					fprintf(stderr, "Sorry, no such event, using %s.
  ", event_name(top.sym_evsel));
923c42c19   Mike Galbraith   perf_counter tool...
509
  					sleep(1);
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
510
  					break;
923c42c19   Mike Galbraith   perf_counter tool...
511
  				}
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
512
  				list_for_each_entry(top.sym_evsel, &top.evlist->entries, node)
ec52d9765   Arnaldo Carvalho de Melo   perf top: Remove ...
513
  					if (top.sym_evsel->idx == counter)
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
514
  						break;
ec52d9765   Arnaldo Carvalho de Melo   perf top: Remove ...
515
516
  			} else
  				top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
923c42c19   Mike Galbraith   perf_counter tool...
517
518
  			break;
  		case 'f':
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
519
  			prompt_integer(&top.count_filter, "Enter display event count filter");
923c42c19   Mike Galbraith   perf_counter tool...
520
521
522
523
  			break;
  		case 'F':
  			prompt_percent(&sym_pcnt_filter, "Enter details display event filter (percent)");
  			break;
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
524
  		case 'K':
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
525
  			top.hide_kernel_symbols = !top.hide_kernel_symbols;
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
526
  			break;
923c42c19   Mike Galbraith   perf_counter tool...
527
528
529
530
  		case 'q':
  		case 'Q':
  			printf("exiting.
  ");
c338aee85   Arnaldo Carvalho de Melo   perf symbols: Do ...
531
  			if (dump_symtab)
dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
532
  				perf_session__fprintf_dsos(top.session, stderr);
923c42c19   Mike Galbraith   perf_counter tool...
533
534
  			exit(0);
  		case 's':
c97cf4221   Arnaldo Carvalho de Melo   perf top: Live TU...
535
  			prompt_symbol(&top.sym_filter_entry, "Enter details symbol");
923c42c19   Mike Galbraith   perf_counter tool...
536
537
  			break;
  		case 'S':
c97cf4221   Arnaldo Carvalho de Melo   perf top: Live TU...
538
  			if (!top.sym_filter_entry)
923c42c19   Mike Galbraith   perf_counter tool...
539
540
  				break;
  			else {
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
541
  				struct hist_entry *syme = top.sym_filter_entry;
923c42c19   Mike Galbraith   perf_counter tool...
542

c97cf4221   Arnaldo Carvalho de Melo   perf top: Live TU...
543
  				top.sym_filter_entry = NULL;
923c42c19   Mike Galbraith   perf_counter tool...
544
  				__zero_source_counters(syme);
923c42c19   Mike Galbraith   perf_counter tool...
545
546
  			}
  			break;
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
547
  		case 'U':
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
548
  			top.hide_user_symbols = !top.hide_user_symbols;
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
549
  			break;
923c42c19   Mike Galbraith   perf_counter tool...
550
  		case 'z':
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
551
  			top.zero = !top.zero;
923c42c19   Mike Galbraith   perf_counter tool...
552
  			break;
83a0944fa   Ingo Molnar   perf: Enable more...
553
554
  		default:
  			break;
923c42c19   Mike Galbraith   perf_counter tool...
555
556
  	}
  }
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
557
558
559
560
561
562
563
564
565
566
  static void perf_top__sort_new_samples(void *arg)
  {
  	struct perf_top *t = arg;
  	perf_top__reset_sample_counters(t);
  
  	if (t->evlist->selected != NULL)
  		t->sym_evsel = t->evlist->selected;
  
  	hists__collapse_resort_threaded(&t->sym_evsel->hists);
  	hists__output_resort_threaded(&t->sym_evsel->hists);
b079d4e97   Arnaldo Carvalho de Melo   perf top: Honour ...
567
568
569
  	hists__decay_entries_threaded(&t->sym_evsel->hists,
  				      top.hide_user_symbols,
  				      top.hide_kernel_symbols);
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
570
  }
c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
571
572
  static void *display_thread_tui(void *arg __used)
  {
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
573
574
575
576
577
578
  	const char *help = "For a higher level overview, try: perf top --sort comm,dso";
  
  	perf_top__sort_new_samples(&top);
  	perf_evlist__tui_browse_hists(top.evlist, help,
  				      perf_top__sort_new_samples,
  				      &top, top.delay_secs);
c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
579
580
581
582
  	exit_browser(0);
  	exit(0);
  	return NULL;
  }
f37a291c5   Ingo Molnar   perf_counter tool...
583
  static void *display_thread(void *arg __used)
078006012   Ingo Molnar   perf_counter tool...
584
  {
0f5486b5c   Frederic Weisbecker   perf_counter: Sle...
585
  	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
923c42c19   Mike Galbraith   perf_counter tool...
586
587
588
589
590
591
592
593
  	struct termios tc, save;
  	int delay_msecs, c;
  
  	tcgetattr(0, &save);
  	tc = save;
  	tc.c_lflag &= ~(ICANON | ECHO);
  	tc.c_cc[VMIN] = 0;
  	tc.c_cc[VTIME] = 0;
091bd2e99   Mike Galbraith   perf top: Improve...
594

3af6e3386   Arnaldo Carvalho de Melo   perf ui browser: ...
595
  	pthread__unblock_sigwinch();
923c42c19   Mike Galbraith   perf_counter tool...
596
  repeat:
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
597
  	delay_msecs = top.delay_secs * 1000;
923c42c19   Mike Galbraith   perf_counter tool...
598
599
600
  	tcsetattr(0, TCSANOW, &tc);
  	/* trash return*/
  	getc(stdin);
078006012   Ingo Molnar   perf_counter tool...
601

3af6e3386   Arnaldo Carvalho de Melo   perf ui browser: ...
602
  	while (1) {
dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
603
  		print_sym_table();
3af6e3386   Arnaldo Carvalho de Melo   perf ui browser: ...
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
  		/*
  		 * Either timeout expired or we got an EINTR due to SIGWINCH,
  		 * refresh screen in both cases.
  		 */
  		switch (poll(&stdin_poll, 1, delay_msecs)) {
  		case 0:
  			continue;
  		case -1:
  			if (errno == EINTR)
  				continue;
  			/* Fall trhu */
  		default:
  			goto process_hotkey;
  		}
  	}
  process_hotkey:
923c42c19   Mike Galbraith   perf_counter tool...
620
621
  	c = getc(stdin);
  	tcsetattr(0, TCSAFLUSH, &save);
dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
622
  	handle_keypress(c);
923c42c19   Mike Galbraith   perf_counter tool...
623
  	goto repeat;
078006012   Ingo Molnar   perf_counter tool...
624
625
626
  
  	return NULL;
  }
2ab52083f   Anton Blanchard   perf top: Move sk...
627
  /* Tag samples to be skipped. */
f37a291c5   Ingo Molnar   perf_counter tool...
628
  static const char *skip_symbols[] = {
2ab52083f   Anton Blanchard   perf top: Move sk...
629
  	"default_idle",
b0e8572f3   Arnaldo Carvalho de Melo   perf top: Add nat...
630
  	"native_safe_halt",
2ab52083f   Anton Blanchard   perf top: Move sk...
631
632
633
634
  	"cpu_idle",
  	"enter_idle",
  	"exit_idle",
  	"mwait_idle",
59b900569   Arnaldo Carvalho de Melo   perf top: Add mwa...
635
  	"mwait_idle_with_hints",
8357275bb   Arnaldo Carvalho de Melo   perf top: Add pol...
636
  	"poll_idle",
3a3393ef7   Anton Blanchard   perf top: Add ppc...
637
638
  	"ppc64_runlatch_off",
  	"pseries_dedicated_idle_sleep",
2ab52083f   Anton Blanchard   perf top: Move sk...
639
640
  	NULL
  };
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
641
  static int symbol_filter(struct map *map __used, struct symbol *sym)
078006012   Ingo Molnar   perf_counter tool...
642
  {
de04687f8   Arnaldo Carvalho de Melo   perf_counter tool...
643
  	const char *name = sym->name;
2ab52083f   Anton Blanchard   perf top: Move sk...
644
  	int i;
de04687f8   Arnaldo Carvalho de Melo   perf_counter tool...
645

3a3393ef7   Anton Blanchard   perf top: Add ppc...
646
647
648
649
650
651
  	/*
  	 * ppc64 uses function descriptors and appends a '.' to the
  	 * start of every instruction address. Remove it.
  	 */
  	if (name[0] == '.')
  		name++;
de04687f8   Arnaldo Carvalho de Melo   perf_counter tool...
652
653
654
655
656
657
658
  	if (!strcmp(name, "_text") ||
  	    !strcmp(name, "_etext") ||
  	    !strcmp(name, "_sinittext") ||
  	    !strncmp("init_module", name, 11) ||
  	    !strncmp("cleanup_module", name, 14) ||
  	    strstr(name, "_text_start") ||
  	    strstr(name, "_text_end"))
078006012   Ingo Molnar   perf_counter tool...
659
  		return 1;
078006012   Ingo Molnar   perf_counter tool...
660

2ab52083f   Anton Blanchard   perf top: Move sk...
661
662
  	for (i = 0; skip_symbols[i]; i++) {
  		if (!strcmp(skip_symbols[i], name)) {
171b3be9c   Arnaldo Carvalho de Melo   perf symbol: Move...
663
  			sym->ignore = true;
2ab52083f   Anton Blanchard   perf top: Move sk...
664
665
666
  			break;
  		}
  	}
078006012   Ingo Molnar   perf_counter tool...
667

078006012   Ingo Molnar   perf_counter tool...
668
669
  	return 0;
  }
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
670
  static void perf_event__process_sample(const union perf_event *event,
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
671
  				       struct perf_evsel *evsel,
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
672
673
  				       struct perf_sample *sample,
  				       struct perf_session *session)
078006012   Ingo Molnar   perf_counter tool...
674
  {
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
675
  	struct symbol *parent = NULL;
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
676
  	u64 ip = event->ip.ip;
1ed091c45   Arnaldo Carvalho de Melo   perf tools: Conso...
677
  	struct addr_location al;
23346f21b   Arnaldo Carvalho de Melo   perf tools: Renam...
678
  	struct machine *machine;
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
679
  	int err;
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
680
  	u8 origin = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
681

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
682
  	++top.samples;
24bfef0f9   Arnaldo Carvalho de Melo   perf top: Fix sam...
683

8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
684
  	switch (origin) {
1ed091c45   Arnaldo Carvalho de Melo   perf tools: Conso...
685
  	case PERF_RECORD_MISC_USER:
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
686
687
  		++top.us_samples;
  		if (top.hide_user_symbols)
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
688
  			return;
23346f21b   Arnaldo Carvalho de Melo   perf tools: Renam...
689
  		machine = perf_session__find_host_machine(session);
1ed091c45   Arnaldo Carvalho de Melo   perf tools: Conso...
690
  		break;
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
691
  	case PERF_RECORD_MISC_KERNEL:
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
692
693
  		++top.kernel_samples;
  		if (top.hide_kernel_symbols)
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
694
  			return;
23346f21b   Arnaldo Carvalho de Melo   perf tools: Renam...
695
  		machine = perf_session__find_host_machine(session);
a1645ce12   Zhang, Yanmin   perf: 'perf kvm' ...
696
697
  		break;
  	case PERF_RECORD_MISC_GUEST_KERNEL:
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
698
  		++top.guest_kernel_samples;
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
699
  		machine = perf_session__find_machine(session, event->ip.pid);
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
700
  		break;
a1645ce12   Zhang, Yanmin   perf: 'perf kvm' ...
701
  	case PERF_RECORD_MISC_GUEST_USER:
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
702
  		++top.guest_us_samples;
a1645ce12   Zhang, Yanmin   perf: 'perf kvm' ...
703
704
705
706
707
  		/*
  		 * TODO: we don't process guest user from host side
  		 * except simple counting.
  		 */
  		return;
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
708
709
710
  	default:
  		return;
  	}
23346f21b   Arnaldo Carvalho de Melo   perf tools: Renam...
711
  	if (!machine && perf_guest) {
a1645ce12   Zhang, Yanmin   perf: 'perf kvm' ...
712
713
  		pr_err("Can't find guest [%d]'s kernel information
  ",
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
714
  			event->ip.pid);
a1645ce12   Zhang, Yanmin   perf: 'perf kvm' ...
715
716
  		return;
  	}
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
717
  	if (event->header.misc & PERF_RECORD_MISC_EXACT_IP)
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
718
  		top.exact_samples++;
1676b8a07   Peter Zijlstra   perf-top: Show th...
719

8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
720
721
  	if (perf_event__preprocess_sample(event, session, &al, sample,
  					  symbol_filter) < 0 ||
72b8fa173   Arnaldo Carvalho de Melo   perf top: Exit if...
722
  	    al.filtered)
1ed091c45   Arnaldo Carvalho de Melo   perf tools: Conso...
723
  		return;
078006012   Ingo Molnar   perf_counter tool...
724

5f6f55809   Arnaldo Carvalho de Melo   perf top: Handle ...
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  	if (!kptr_restrict_warned &&
  	    symbol_conf.kptr_restrict &&
  	    al.cpumode == PERF_RECORD_MISC_KERNEL) {
  		ui__warning(
  "Kernel address maps (/proc/{kallsyms,modules}) are restricted.
  
  "
  "Check /proc/sys/kernel/kptr_restrict.
  
  "
  "Kernel%s samples will not be resolved.
  ",
  			  !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ?
  			  " modules" : "");
  		if (use_browser <= 0)
  			sleep(5);
  		kptr_restrict_warned = true;
  	}
72b8fa173   Arnaldo Carvalho de Melo   perf top: Exit if...
743
  	if (al.sym == NULL) {
e4a338d05   Arnaldo Carvalho de Melo   perf top: Don't s...
744
745
  		const char *msg = "Kernel samples will not be resolved.
  ";
72b8fa173   Arnaldo Carvalho de Melo   perf top: Exit if...
746
747
748
749
750
751
752
753
754
755
756
  		/*
  		 * As we do lazy loading of symtabs we only will know if the
  		 * specified vmlinux file is invalid when we actually have a
  		 * hit in kernel space and then try to load it. So if we get
  		 * here and there are _no_ symbols in the DSO backing the
  		 * kernel map, bail out.
  		 *
  		 * We may never get here, for instance, if we use -K/
  		 * --hide-kernel-symbols, even if the user specifies an
  		 * invalid --vmlinux ;-)
  		 */
e4a338d05   Arnaldo Carvalho de Melo   perf top: Don't s...
757
758
  		if (!kptr_restrict_warned && !vmlinux_warned &&
  		    al.map == machine->vmlinux_maps[MAP__FUNCTION] &&
72b8fa173   Arnaldo Carvalho de Melo   perf top: Exit if...
759
  		    RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
e4a338d05   Arnaldo Carvalho de Melo   perf top: Don't s...
760
761
762
763
764
765
766
767
768
769
770
771
772
  			if (symbol_conf.vmlinux_name) {
  				ui__warning("The %s file can't be used.
  %s",
  					    symbol_conf.vmlinux_name, msg);
  			} else {
  				ui__warning("A vmlinux file was not found.
  %s",
  					    msg);
  			}
  
  			if (use_browser <= 0)
  				sleep(5);
  			vmlinux_warned = true;
72b8fa173   Arnaldo Carvalho de Melo   perf top: Exit if...
773
  		}
6cff0e8db   Kirill Smelkov   perf top: Teach i...
774
  	}
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
775
  	if (al.sym == NULL || !al.sym->ignore) {
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
776
  		struct hist_entry *he;
70db7533c   Arnaldo Carvalho de Melo   perf evlist: Move...
777

19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
778
779
780
781
782
783
784
  		if ((sort__has_parent || symbol_conf.use_callchain) &&
  		    sample->callchain) {
  			err = perf_session__resolve_callchain(session, al.thread,
  							      sample->callchain, &parent);
  			if (err)
  				return;
  		}
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
785
786
787
788
789
  		he = perf_session__add_hist_entry(session, &al, sample, evsel);
  		if (he == NULL) {
  			pr_err("Problem incrementing symbol period, skipping event
  ");
  			return;
5807806a9   Arnaldo Carvalho de Melo   perf top tui: Wai...
790
  		}
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
791

19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
792
793
794
795
796
797
798
799
800
  		if (symbol_conf.use_callchain) {
  			err = callchain_append(he->callchain, &session->callchain_cursor,
  					       sample->period);
  			if (err)
  				return;
  		}
  
  		if (sort_has_symbols)
  			record_precise_ip(he, evsel->idx, ip);
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
801
  	}
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
802
803
  
  	return;
078006012   Ingo Molnar   perf_counter tool...
804
  }
aece948f5   Arnaldo Carvalho de Melo   perf evlist: Fix ...
805
  static void perf_session__mmap_read_idx(struct perf_session *self, int idx)
078006012   Ingo Molnar   perf_counter tool...
806
  {
8d50e5b41   Arnaldo Carvalho de Melo   perf tools: Renam...
807
  	struct perf_sample sample;
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
808
  	struct perf_evsel *evsel;
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
809
  	union perf_event *event;
5538becae   Frederic Weisbecker   perf tools: Propa...
810
  	int ret;
078006012   Ingo Molnar   perf_counter tool...
811

aece948f5   Arnaldo Carvalho de Melo   perf evlist: Fix ...
812
  	while ((event = perf_evlist__mmap_read(top.evlist, idx)) != NULL) {
5538becae   Frederic Weisbecker   perf tools: Propa...
813
814
815
816
817
818
  		ret = perf_session__parse_sample(self, event, &sample);
  		if (ret) {
  			pr_err("Can't parse sample, err = %d
  ", ret);
  			continue;
  		}
04391debc   Arnaldo Carvalho de Melo   perf evlist: Stea...
819

7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
820
821
  		evsel = perf_evlist__id2evsel(self->evlist, sample.id);
  		assert(evsel != NULL);
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
822
  		if (event->header.type == PERF_RECORD_SAMPLE)
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
823
824
825
  			perf_event__process_sample(event, evsel, &sample, self);
  		else if (event->header.type < PERF_RECORD_MAX) {
  			hists__inc_nr_events(&evsel->hists, event->header.type);
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
826
  			perf_event__process(event, &sample, self);
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
827
828
  		} else
  			++self->hists.stats.nr_unknown_events;
078006012   Ingo Molnar   perf_counter tool...
829
  	}
078006012   Ingo Molnar   perf_counter tool...
830
  }
d8f66248d   Arnaldo Carvalho de Melo   perf session: Pas...
831
  static void perf_session__mmap_read(struct perf_session *self)
2f01190aa   Frederic Weisbecker   perf top: Wait fo...
832
  {
70db7533c   Arnaldo Carvalho de Melo   perf evlist: Move...
833
  	int i;
aece948f5   Arnaldo Carvalho de Melo   perf evlist: Fix ...
834
835
  	for (i = 0; i < top.evlist->nr_mmaps; i++)
  		perf_session__mmap_read_idx(self, i);
2f01190aa   Frederic Weisbecker   perf top: Wait fo...
836
  }
72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
837
838
  static void start_counters(struct perf_evlist *evlist)
  {
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
839
840
841
  	struct perf_evsel *counter, *first;
  
  	first = list_entry(evlist->entries.next, struct perf_evsel, node);
7e4ff9e3e   Mike Galbraith   perf tools: Fix c...
842

72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
843
844
  	list_for_each_entry(counter, &evlist->entries, node) {
  		struct perf_event_attr *attr = &counter->attr;
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
845
846
847
848
  		struct xyarray *group_fd = NULL;
  
  		if (group && counter != first)
  			group_fd = first->fd;
716c69fec   Ingo Molnar   perf top: Fall ba...
849

72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
850
  		attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
851
  		if (top.freq) {
72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
852
853
  			attr->sample_type |= PERF_SAMPLE_PERIOD;
  			attr->freq	  = 1;
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
854
  			attr->sample_freq = top.freq;
72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
855
  		}
d6d901c23   Zhang, Yanmin   perf events: Chan...
856

70db7533c   Arnaldo Carvalho de Melo   perf evlist: Move...
857
858
859
860
  		if (evlist->nr_entries > 1) {
  			attr->sample_type |= PERF_SAMPLE_ID;
  			attr->read_format |= PERF_FORMAT_ID;
  		}
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
861
862
  		if (symbol_conf.use_callchain)
  			attr->sample_type |= PERF_SAMPLE_CALLCHAIN;
72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
863
  		attr->mmap = 1;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
864
  		attr->comm = 1;
5d2cd9092   Arnaldo Carvalho de Melo   perf evsel: Fix u...
865
  		attr->inherit = inherit;
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
866
867
  retry_sample_id:
  		attr->sample_id_all = sample_id_all_avail ? 1 : 0;
72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
868
  try_again:
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
869
  		if (perf_evsel__open(counter, top.evlist->cpus,
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
870
871
  				     top.evlist->threads, group,
  				     group_fd) < 0) {
d6d901c23   Zhang, Yanmin   perf events: Chan...
872
  			int err = errno;
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
873
  			if (err == EPERM || err == EACCES) {
b8631e6eb   Arnaldo Carvalho de Melo   perf ui: Rename u...
874
  				ui__error_paranoid();
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
875
  				goto out_err;
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
876
877
878
879
880
881
  			} else if (err == EINVAL && sample_id_all_avail) {
  				/*
  				 * Old kernel, no attr->sample_id_type_all field
  				 */
  				sample_id_all_avail = false;
  				goto retry_sample_id;
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
882
  			}
d6d901c23   Zhang, Yanmin   perf events: Chan...
883
884
885
886
887
  			/*
  			 * If it's cycles then fall back to hrtimer
  			 * based cpu-clock-tick sw counter, which
  			 * is always available even if no PMU support:
  			 */
72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
888
889
  			if (attr->type == PERF_TYPE_HARDWARE &&
  			    attr->config == PERF_COUNT_HW_CPU_CYCLES) {
d6d901c23   Zhang, Yanmin   perf events: Chan...
890
  				if (verbose)
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
891
892
893
894
  					ui__warning("Cycles event not supported,
  "
  						    "trying to fall back to cpu-clock-ticks
  ");
d6d901c23   Zhang, Yanmin   perf events: Chan...
895
896
897
898
899
  
  				attr->type = PERF_TYPE_SOFTWARE;
  				attr->config = PERF_COUNT_SW_CPU_CLOCK;
  				goto try_again;
  			}
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
900

ca6a42586   David Ahern   perf tools: Emit ...
901
902
903
904
905
906
  			if (err == ENOENT) {
  				ui__warning("The %s event is not supported.
  ",
  					    event_name(counter));
  				goto out_err;
  			}
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
907
908
909
910
911
912
913
914
  			ui__warning("The sys_perf_event_open() syscall "
  				    "returned with %d (%s).  /bin/dmesg "
  				    "may provide additional information.
  "
  				    "No CONFIG_PERF_EVENTS=y kernel support "
  				    "configured?
  ", err, strerror(err));
  			goto out_err;
d6d901c23   Zhang, Yanmin   perf events: Chan...
915
  		}
716c69fec   Ingo Molnar   perf top: Fall ba...
916
  	}
70db7533c   Arnaldo Carvalho de Melo   perf evlist: Move...
917

c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
918
919
920
921
922
923
924
925
926
927
928
929
  	if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) {
  		ui__warning("Failed to mmap with %d (%s)
  ",
  			    errno, strerror(errno));
  		goto out_err;
  	}
  
  	return;
  
  out_err:
  	exit_browser(0);
  	exit(0);
716c69fec   Ingo Molnar   perf top: Fall ba...
930
  }
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
  static int setup_sample_type(void)
  {
  	if (!sort_has_symbols) {
  		if (symbol_conf.use_callchain) {
  			ui__warning("Selected -g but \"sym\" not present in --sort/-s.");
  			return -EINVAL;
  		}
  	} else if (!dont_use_callchains && callchain_param.mode != CHAIN_NONE) {
  		if (callchain_register_param(&callchain_param) < 0) {
  			ui__warning("Can't register callchain params.
  ");
  			return -EINVAL;
  		}
  	}
  
  	return 0;
  }
716c69fec   Ingo Molnar   perf top: Fall ba...
948
949
950
  static int __cmd_top(void)
  {
  	pthread_t thread;
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
951
  	int ret;
d8f66248d   Arnaldo Carvalho de Melo   perf session: Pas...
952
  	/*
b3165f414   Arnaldo Carvalho de Melo   perf session: Mov...
953
954
  	 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
  	 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
d8f66248d   Arnaldo Carvalho de Melo   perf session: Pas...
955
  	 */
dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
956
957
  	top.session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
  	if (top.session == NULL)
b3165f414   Arnaldo Carvalho de Melo   perf session: Mov...
958
  		return -ENOMEM;
078006012   Ingo Molnar   perf_counter tool...
959

19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
960
961
962
  	ret = setup_sample_type();
  	if (ret)
  		goto out_delete;
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
963
  	if (top.target_tid != -1)
7c940c18c   Arnaldo Carvalho de Melo   Merge remote bran...
964
  		perf_event__synthesize_thread_map(top.evlist->threads,
dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
965
  						  perf_event__process, top.session);
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
966
  	else
dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
967
  		perf_event__synthesize_threads(perf_event__process, top.session);
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
968

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
969
  	start_counters(top.evlist);
dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
970
971
  	top.session->evlist = top.evlist;
  	perf_session__update_sample_type(top.session);
078006012   Ingo Molnar   perf_counter tool...
972

2f01190aa   Frederic Weisbecker   perf top: Wait fo...
973
  	/* Wait for a minimal set of events before starting the snapshot */
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
974
  	poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
2f01190aa   Frederic Weisbecker   perf top: Wait fo...
975

dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
976
  	perf_session__mmap_read(top.session);
2f01190aa   Frederic Weisbecker   perf top: Wait fo...
977

c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
978
  	if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui :
dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
979
  							     display_thread), NULL)) {
078006012   Ingo Molnar   perf_counter tool...
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
  		printf("Could not create display thread.
  ");
  		exit(-1);
  	}
  
  	if (realtime_prio) {
  		struct sched_param param;
  
  		param.sched_priority = realtime_prio;
  		if (sched_setscheduler(0, SCHED_FIFO, &param)) {
  			printf("Could not set realtime priority.
  ");
  			exit(-1);
  		}
  	}
  
  	while (1) {
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
997
  		u64 hits = top.samples;
078006012   Ingo Molnar   perf_counter tool...
998

dcc101d1d   Arnaldo Carvalho de Melo   perf top: Improve...
999
  		perf_session__mmap_read(top.session);
078006012   Ingo Molnar   perf_counter tool...
1000

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1001
1002
  		if (hits == top.samples)
  			ret = poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
078006012   Ingo Molnar   perf_counter tool...
1003
  	}
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
  out_delete:
  	perf_session__delete(top.session);
  	top.session = NULL;
  
  	return 0;
  }
  
  static int
  parse_callchain_opt(const struct option *opt __used, const char *arg,
  		    int unset)
  {
  	char *tok, *tok2;
  	char *endptr;
  
  	/*
  	 * --no-call-graph
  	 */
  	if (unset) {
  		dont_use_callchains = true;
  		return 0;
  	}
  
  	symbol_conf.use_callchain = true;
  
  	if (!arg)
  		return 0;
  
  	tok = strtok((char *)arg, ",");
  	if (!tok)
  		return -1;
  
  	/* get the output mode */
  	if (!strncmp(tok, "graph", strlen(arg)))
  		callchain_param.mode = CHAIN_GRAPH_ABS;
  
  	else if (!strncmp(tok, "flat", strlen(arg)))
  		callchain_param.mode = CHAIN_FLAT;
  
  	else if (!strncmp(tok, "fractal", strlen(arg)))
  		callchain_param.mode = CHAIN_GRAPH_REL;
  
  	else if (!strncmp(tok, "none", strlen(arg))) {
  		callchain_param.mode = CHAIN_NONE;
  		symbol_conf.use_callchain = false;
  
  		return 0;
  	}
  
  	else
  		return -1;
  
  	/* get the min percentage */
  	tok = strtok(NULL, ",");
  	if (!tok)
  		goto setup;
  
  	callchain_param.min_percent = strtod(tok, &endptr);
  	if (tok == endptr)
  		return -1;
  
  	/* get the print limit */
  	tok2 = strtok(NULL, ",");
  	if (!tok2)
  		goto setup;
  
  	if (tok2[0] != 'c') {
  		callchain_param.print_limit = strtod(tok2, &endptr);
  		tok2 = strtok(NULL, ",");
  		if (!tok2)
  			goto setup;
  	}
  
  	/* get the call chain order */
  	if (!strcmp(tok2, "caller"))
  		callchain_param.order = ORDER_CALLER;
  	else if (!strcmp(tok2, "callee"))
  		callchain_param.order = ORDER_CALLEE;
  	else
  		return -1;
  setup:
  	if (callchain_register_param(&callchain_param) < 0) {
  		fprintf(stderr, "Can't register callchain params
  ");
  		return -1;
  	}
078006012   Ingo Molnar   perf_counter tool...
1089
1090
  	return 0;
  }
b456bae0f   Ingo Molnar   perf top: Convert...
1091
1092
1093
1094
1095
  
  static const char * const top_usage[] = {
  	"perf top [<options>]",
  	NULL
  };
b456bae0f   Ingo Molnar   perf top: Convert...
1096
  static const struct option options[] = {
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1097
  	OPT_CALLBACK('e', "event", &top.evlist, "event",
86847b62f   Thomas Gleixner   perf_counter tool...
1098
  		     "event selector. use 'perf list' to list available events",
f120f9d51   Jiri Olsa   perf tools: De-op...
1099
  		     parse_events_option),
b456bae0f   Ingo Molnar   perf top: Convert...
1100
1101
  	OPT_INTEGER('c', "count", &default_interval,
  		    "event period to sample"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1102
  	OPT_INTEGER('p', "pid", &top.target_pid,
d6d901c23   Zhang, Yanmin   perf events: Chan...
1103
  		    "profile events on existing process id"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1104
  	OPT_INTEGER('t', "tid", &top.target_tid,
d6d901c23   Zhang, Yanmin   perf events: Chan...
1105
  		    "profile events on existing thread id"),
b456bae0f   Ingo Molnar   perf top: Convert...
1106
1107
  	OPT_BOOLEAN('a', "all-cpus", &system_wide,
  			    "system-wide collection from all CPUs"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1108
  	OPT_STRING('C', "cpu", &top.cpu_list, "cpu",
c45c6ea2e   Stephane Eranian   perf tools: Add t...
1109
  		    "list of cpus to monitor"),
b32d133ae   Arnaldo Carvalho de Melo   perf symbols: Sim...
1110
1111
  	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
  		   "file", "vmlinux pathname"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1112
  	OPT_BOOLEAN('K', "hide_kernel_symbols", &top.hide_kernel_symbols,
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
1113
  		    "hide kernel symbols"),
1967936d6   Arnaldo Carvalho de Melo   perf options: Che...
1114
  	OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"),
b456bae0f   Ingo Molnar   perf top: Convert...
1115
1116
  	OPT_INTEGER('r', "realtime", &realtime_prio,
  		    "collect data with this RT SCHED_FIFO priority"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1117
  	OPT_INTEGER('d', "delay", &top.delay_secs,
b456bae0f   Ingo Molnar   perf top: Convert...
1118
1119
1120
  		    "number of seconds to delay between refreshes"),
  	OPT_BOOLEAN('D', "dump-symtab", &dump_symtab,
  			    "dump the symbol table used for profiling"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1121
  	OPT_INTEGER('f', "count-filter", &top.count_filter,
b456bae0f   Ingo Molnar   perf top: Convert...
1122
1123
1124
  		    "only display functions with more events than this"),
  	OPT_BOOLEAN('g', "group", &group,
  			    "put the counters into a counter group"),
0fdc7e67d   Mike Galbraith   perf_counter tool...
1125
1126
  	OPT_BOOLEAN('i', "inherit", &inherit,
  		    "child tasks inherit counters"),
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
1127
  	OPT_STRING(0, "sym-annotate", &sym_filter, "symbol name",
6cff0e8db   Kirill Smelkov   perf top: Teach i...
1128
  		    "symbol to annotate"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1129
  	OPT_BOOLEAN('z', "zero", &top.zero,
b456bae0f   Ingo Molnar   perf top: Convert...
1130
  		    "zero history across updates"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1131
  	OPT_INTEGER('F', "freq", &top.freq,
b456bae0f   Ingo Molnar   perf top: Convert...
1132
  		    "profile at this frequency"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1133
  	OPT_INTEGER('E', "entries", &top.print_entries,
6e53cdf11   Ingo Molnar   perf top: Reduce ...
1134
  		    "display this many functions"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1135
  	OPT_BOOLEAN('U', "hide_user_symbols", &top.hide_user_symbols,
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
1136
  		    "hide user symbols"),
c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
1137
1138
  	OPT_BOOLEAN(0, "tui", &use_tui, "Use the TUI interface"),
  	OPT_BOOLEAN(0, "stdio", &use_stdio, "Use the stdio interface"),
c05556421   Ian Munsie   perf: Fix endiann...
1139
  	OPT_INCR('v', "verbose", &verbose,
3da297a60   Ingo Molnar   perf record: Fall...
1140
  		    "be more verbose (show counter open errors, etc)"),
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
1141
1142
1143
1144
  	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
  		   "sort by key(s): pid, comm, dso, symbol, parent"),
  	OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
  		    "Show a column with the number of samples"),
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
1145
1146
1147
1148
  	OPT_CALLBACK_DEFAULT('G', "call-graph", NULL, "output_type,min_percent, call_order",
  		     "Display callchains using output_type (graph, flat, fractal, or none), min percent threshold and callchain order. "
  		     "Default: fractal,0.5,callee", &parse_callchain_opt,
  		     callchain_default_opt),
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
1149
1150
1151
1152
1153
1154
1155
1156
  	OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
  		    "Show a column with the sum of periods"),
  	OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
  		   "only consider symbols in these dsos"),
  	OPT_STRING(0, "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
  		   "only consider symbols in these comms"),
  	OPT_STRING(0, "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
  		   "only consider these symbols"),
64c6f0c7f   Arnaldo Carvalho de Melo   perf tools: Make ...
1157
1158
1159
1160
1161
1162
  	OPT_BOOLEAN(0, "source", &symbol_conf.annotate_src,
  		    "Interleave source code with assembly code (default)"),
  	OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw,
  		    "Display raw encoding of assembly instructions (default)"),
  	OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
  		   "Specify disassembler style (e.g. -M intel for intel syntax)"),
b456bae0f   Ingo Molnar   perf top: Convert...
1163
1164
  	OPT_END()
  };
f37a291c5   Ingo Molnar   perf_counter tool...
1165
  int cmd_top(int argc, const char **argv, const char *prefix __used)
b456bae0f   Ingo Molnar   perf top: Convert...
1166
  {
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1167
1168
  	struct perf_evsel *pos;
  	int status = -ENOMEM;
b456bae0f   Ingo Molnar   perf top: Convert...
1169

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1170
1171
  	top.evlist = perf_evlist__new(NULL, NULL);
  	if (top.evlist == NULL)
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
1172
  		return -ENOMEM;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
1173
  	symbol_conf.exclude_other = false;
b456bae0f   Ingo Molnar   perf top: Convert...
1174

b456bae0f   Ingo Molnar   perf top: Convert...
1175
1176
1177
  	argc = parse_options(argc, argv, options, top_usage, 0);
  	if (argc)
  		usage_with_options(top_usage, options);
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
1178
1179
1180
1181
  	if (sort_order == default_sort_order)
  		sort_order = "dso,symbol";
  
  	setup_sorting(top_usage, options);
c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
1182
1183
1184
1185
1186
1187
  	if (use_stdio)
  		use_browser = 0;
  	else if (use_tui)
  		use_browser = 1;
  
  	setup_browser(false);
b456bae0f   Ingo Molnar   perf top: Convert...
1188
  	/* CPU and PID are mutually exclusive */
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1189
  	if (top.target_tid > 0 && top.cpu_list) {
b456bae0f   Ingo Molnar   perf top: Convert...
1190
1191
1192
  		printf("WARNING: PID switch overriding CPU
  ");
  		sleep(1);
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1193
  		top.cpu_list = NULL;
b456bae0f   Ingo Molnar   perf top: Convert...
1194
  	}
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1195
1196
  	if (top.target_pid != -1)
  		top.target_tid = top.target_pid;
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
1197

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1198
1199
  	if (perf_evlist__create_maps(top.evlist, top.target_pid,
  				     top.target_tid, top.cpu_list) < 0)
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
1200
  		usage_with_options(top_usage, options);
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1201
1202
  	if (!top.evlist->nr_entries &&
  	    perf_evlist__add_default(top.evlist) < 0) {
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1203
1204
1205
1206
  		pr_err("Not enough memory for event selector list
  ");
  		return -ENOMEM;
  	}
5a8e5a306   Arnaldo Carvalho de Melo   perf top: Allocat...
1207

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1208
1209
  	if (top.delay_secs < 1)
  		top.delay_secs = 1;
2f335a02b   Frederic Weisbecker   perf top: Fix zer...
1210

7e4ff9e3e   Mike Galbraith   perf tools: Fix c...
1211
1212
1213
1214
  	/*
  	 * User specified count overrides default frequency.
  	 */
  	if (default_interval)
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1215
1216
1217
  		top.freq = 0;
  	else if (top.freq) {
  		default_interval = top.freq;
7e4ff9e3e   Mike Galbraith   perf tools: Fix c...
1218
1219
1220
1221
1222
  	} else {
  		fprintf(stderr, "frequency and count are zero, aborting
  ");
  		exit(EXIT_FAILURE);
  	}
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1223
1224
1225
  	list_for_each_entry(pos, &top.evlist->entries, node) {
  		if (perf_evsel__alloc_fd(pos, top.evlist->cpus->nr,
  					 top.evlist->threads->nr) < 0)
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1226
1227
1228
1229
1230
1231
1232
1233
1234
  			goto out_free_fd;
  		/*
  		 * Fill in the ones not specifically initialized via -c:
  		 */
  		if (pos->attr.sample_period)
  			continue;
  
  		pos->attr.sample_period = default_interval;
  	}
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1235
1236
  	if (perf_evlist__alloc_pollfd(top.evlist) < 0 ||
  	    perf_evlist__alloc_mmap(top.evlist) < 0)
5c581041c   Arnaldo Carvalho de Melo   perf evlist: Adop...
1237
  		goto out_free_fd;
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1238
  	top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
cc841580a   Arnaldo Carvalho de Melo   perf top: Fix ann...
1239

ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
1240
  	symbol_conf.priv_size = sizeof(struct annotation);
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1241
1242
1243
1244
  
  	symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
  	if (symbol__init() < 0)
  		return -1;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
1245
1246
1247
  	sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout);
  	sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
  	sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
1248
1249
1250
1251
1252
  	/*
  	 * Avoid annotation data structures overhead when symbols aren't on the
  	 * sort list.
  	 */
  	sort_has_symbols = sort_sym.list.next != NULL;
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
1253
  	get_term_dimensions(&winsize);
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1254
  	if (top.print_entries == 0) {
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
1255
  		update_print_entries(&winsize);
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
1256
1257
  		signal(SIGWINCH, sig_winch_handler);
  	}
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1258
1259
  	status = __cmd_top();
  out_free_fd:
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1260
  	perf_evlist__delete(top.evlist);
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1261
1262
  
  	return status;
b456bae0f   Ingo Molnar   perf top: Convert...
1263
  }