Blame view

tools/perf/builtin-top.c 31.9 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>
923c42c19   Mike Galbraith   perf_counter tool...
65

895f0edc3   Arnaldo Carvalho de Melo   perf top: Export ...
66
  void get_term_dimensions(struct winsize *ws)
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
67
  {
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
68
69
70
71
72
73
74
75
76
77
  	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...
78
  	}
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
79
80
81
82
  #ifdef TIOCGWINSZ
  	if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
  	    ws->ws_row && ws->ws_col)
  		return;
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
83
  #endif
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
84
85
  	ws->ws_row = 25;
  	ws->ws_col = 80;
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
86
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
87
  static void perf_top__update_print_entries(struct perf_top *top)
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
88
  {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
89
  	top->print_entries = top->winsize.ws_row;
13cc5079f   Arnaldo Carvalho de Melo   perf top: Auto ad...
90

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
91
92
  	if (top->print_entries > 9)
  		top->print_entries -= 9;
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
93
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
94
  static void perf_top__sig_winch(int sig __used, siginfo_t *info __used, void *arg)
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
95
  {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
96
97
98
99
  	struct perf_top *top = arg;
  
  	get_term_dimensions(&top->winsize);
  	perf_top__update_print_entries(top);
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
100
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
101
  static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
923c42c19   Mike Galbraith   perf_counter tool...
102
103
  {
  	struct symbol *sym;
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
104
  	struct annotation *notes;
439d473b4   Arnaldo Carvalho de Melo   perf tools: Rewri...
105
  	struct map *map;
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
106
  	int err = -1;
923c42c19   Mike Galbraith   perf_counter tool...
107

ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
108
  	if (!he || !he->ms.sym)
b0a9ab62a   Arnaldo Carvalho de Melo   perf top: Properl...
109
  		return -1;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
110
111
  	sym = he->ms.sym;
  	map = he->ms.map;
b0a9ab62a   Arnaldo Carvalho de Melo   perf top: Properl...
112
113
114
115
  
  	/*
  	 * We can't annotate with just /proc/kallsyms
  	 */
878b439dc   Arnaldo Carvalho de Melo   perf symbols: Ren...
116
  	if (map->dso->symtab_type == SYMTAB__KALLSYMS) {
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
117
118
119
120
  		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...
121
  		return -1;
b269876c8   Arnaldo Carvalho de Melo   perf top: Don't a...
122
  	}
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
123
124
125
  	notes = symbol__annotation(sym);
  	if (notes->src != NULL) {
  		pthread_mutex_lock(&notes->lock);
923c42c19   Mike Galbraith   perf_counter tool...
126
127
  		goto out_assign;
  	}
923c42c19   Mike Galbraith   perf_counter tool...
128

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

d04b35f80   Arnaldo Carvalho de Melo   perf symbols: Add...
131
  	if (symbol__alloc_hist(sym) < 0) {
c97cf4221   Arnaldo Carvalho de Melo   perf top: Live TU...
132
  		pthread_mutex_unlock(&notes->lock);
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
133
134
135
  		pr_err("Not enough memory for annotating '%s' symbol!
  ",
  		       sym->name);
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
136
  		sleep(1);
c97cf4221   Arnaldo Carvalho de Melo   perf top: Live TU...
137
  		return err;
923c42c19   Mike Galbraith   perf_counter tool...
138
  	}
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
139

ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
140
  	err = symbol__annotate(sym, map, 0);
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
141
  	if (err == 0) {
923c42c19   Mike Galbraith   perf_counter tool...
142
  out_assign:
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
143
  		top->sym_filter_entry = he;
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
144
  	}
c97cf4221   Arnaldo Carvalho de Melo   perf top: Live TU...
145

ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
146
  	pthread_mutex_unlock(&notes->lock);
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
147
  	return err;
923c42c19   Mike Galbraith   perf_counter tool...
148
  }
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
149
  static void __zero_source_counters(struct hist_entry *he)
923c42c19   Mike Galbraith   perf_counter tool...
150
  {
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
151
  	struct symbol *sym = he->ms.sym;
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
152
  	symbol__annotate_zero_histograms(sym);
923c42c19   Mike Galbraith   perf_counter tool...
153
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
154
155
156
  static void perf_top__record_precise_ip(struct perf_top *top,
  					struct hist_entry *he,
  					int counter, u64 ip)
923c42c19   Mike Galbraith   perf_counter tool...
157
  {
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
158
159
  	struct annotation *notes;
  	struct symbol *sym;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
160
  	if (he == NULL || he->ms.sym == NULL ||
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
161
162
  	    ((top->sym_filter_entry == NULL ||
  	      top->sym_filter_entry->ms.sym != he->ms.sym) && use_browser != 1))
923c42c19   Mike Galbraith   perf_counter tool...
163
  		return;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
164
  	sym = he->ms.sym;
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
165
166
167
  	notes = symbol__annotation(sym);
  
  	if (pthread_mutex_trylock(&notes->lock))
923c42c19   Mike Galbraith   perf_counter tool...
168
  		return;
d04b35f80   Arnaldo Carvalho de Melo   perf symbols: Add...
169
  	if (notes->src == NULL && symbol__alloc_hist(sym) < 0) {
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
170
171
172
173
174
175
176
177
178
179
  		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...
180

ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
181
  	pthread_mutex_unlock(&notes->lock);
923c42c19   Mike Galbraith   perf_counter tool...
182
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
183
  static void perf_top__show_details(struct perf_top *top)
923c42c19   Mike Galbraith   perf_counter tool...
184
  {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
185
  	struct hist_entry *he = top->sym_filter_entry;
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
186
  	struct annotation *notes;
923c42c19   Mike Galbraith   perf_counter tool...
187
  	struct symbol *symbol;
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
188
  	int more;
923c42c19   Mike Galbraith   perf_counter tool...
189

ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
190
  	if (!he)
923c42c19   Mike Galbraith   perf_counter tool...
191
  		return;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
192
  	symbol = he->ms.sym;
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
193
194
195
196
197
198
  	notes = symbol__annotation(symbol);
  
  	pthread_mutex_lock(&notes->lock);
  
  	if (notes->src == NULL)
  		goto out_unlock;
923c42c19   Mike Galbraith   perf_counter tool...
199

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
200
201
202
203
  	printf("Showing %s for %s
  ", event_name(top->sym_evsel), symbol->name);
  	printf("  Events  Pcnt (>=%d%%)
  ", top->sym_pcnt_filter);
923c42c19   Mike Galbraith   perf_counter tool...
204

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
205
206
207
208
  	more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel->idx,
  				       0, top->sym_pcnt_filter, top->print_entries, 4);
  	if (top->zero)
  		symbol__annotate_zero_histogram(symbol, top->sym_evsel->idx);
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
209
  	else
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
210
  		symbol__annotate_decay_histogram(symbol, top->sym_evsel->idx);
36532461a   Arnaldo Carvalho de Melo   perf top: Ditch p...
211
  	if (more != 0)
923c42c19   Mike Galbraith   perf_counter tool...
212
213
  		printf("%d lines not displayed, maybe increase display entries [e]
  ", more);
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
214
215
  out_unlock:
  	pthread_mutex_unlock(&notes->lock);
923c42c19   Mike Galbraith   perf_counter tool...
216
  }
078006012   Ingo Molnar   perf_counter tool...
217

078006012   Ingo Molnar   perf_counter tool...
218
  static const char		CONSOLE_CLEAR[] = "";
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
219
220
221
  static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
  						     struct addr_location *al,
  						     struct perf_sample *sample)
de04687f8   Arnaldo Carvalho de Melo   perf_counter tool...
222
  {
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
223
224
225
226
227
  	struct hist_entry *he;
  
  	he = __hists__add_entry(&evsel->hists, al, NULL, sample->period);
  	if (he == NULL)
  		return NULL;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
228
229
  	hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
  	return he;
de04687f8   Arnaldo Carvalho de Melo   perf_counter tool...
230
  }
078006012   Ingo Molnar   perf_counter tool...
231

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
232
  static void perf_top__print_sym_table(struct perf_top *top)
078006012   Ingo Molnar   perf_counter tool...
233
  {
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
234
235
  	char bf[160];
  	int printed = 0;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
236
  	const int win_width = top->winsize.ws_col - 1;
d94b94305   Mike Galbraith   perf top: Reduce ...
237

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

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
240
  	perf_top__header_snprintf(top, bf, sizeof(bf));
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
241
242
  	printf("%s
  ", bf);
078006012   Ingo Molnar   perf_counter tool...
243

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
244
  	perf_top__reset_sample_counters(top);
078006012   Ingo Molnar   perf_counter tool...
245

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

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
249
250
251
252
  	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];
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
253
254
  		color_fprintf(stdout, PERF_COLOR_RED,
  			      "WARNING: LOST %d chunks, Check IO/CPU overload",
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
255
  			      top->sym_evsel->hists.stats.nr_lost_warned);
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
256
  		++printed;
93fc64f14   Arnaldo Carvalho de Melo   perf top: Switch ...
257
  	}
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
258
259
  	if (top->sym_filter_entry) {
  		perf_top__show_details(top);
923c42c19   Mike Galbraith   perf_counter tool...
260
261
  		return;
  	}
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
262
263
264
265
266
267
268
  	hists__collapse_resort_threaded(&top->sym_evsel->hists);
  	hists__output_resort_threaded(&top->sym_evsel->hists);
  	hists__decay_entries_threaded(&top->sym_evsel->hists,
  				      top->hide_user_symbols,
  				      top->hide_kernel_symbols);
  	hists__output_recalc_col_len(&top->sym_evsel->hists,
  				     top->winsize.ws_row - 3);
7cc017edb   Arnaldo Carvalho de Melo   perf top: Always ...
269
270
  	putchar('
  ');
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
271
272
  	hists__fprintf(&top->sym_evsel->hists, NULL, false, false,
  		       top->winsize.ws_row - 4 - printed, win_width, stdout);
078006012   Ingo Molnar   perf_counter tool...
273
  }
923c42c19   Mike Galbraith   perf_counter tool...
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
  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;
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
310
  static void perf_top__prompt_symbol(struct perf_top *top, const char *msg)
923c42c19   Mike Galbraith   perf_counter tool...
311
312
  {
  	char *buf = malloc(0), *p;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
313
  	struct hist_entry *syme = top->sym_filter_entry, *n, *found = NULL;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
314
  	struct rb_node *next;
923c42c19   Mike Galbraith   perf_counter tool...
315
316
317
318
  	size_t dummy = 0;
  
  	/* zero counters of active symbol */
  	if (syme) {
923c42c19   Mike Galbraith   perf_counter tool...
319
  		__zero_source_counters(syme);
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
320
  		top->sym_filter_entry = NULL;
923c42c19   Mike Galbraith   perf_counter tool...
321
322
323
324
325
326
327
328
329
330
331
  	}
  
  	fprintf(stdout, "
  %s: ", msg);
  	if (getline(&buf, &dummy, stdin) < 0)
  		goto out_free;
  
  	p = strchr(buf, '
  ');
  	if (p)
  		*p = 0;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
332
  	next = rb_first(&top->sym_evsel->hists.entries);
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
333
334
335
336
  	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...
337
338
  			break;
  		}
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
339
  		next = rb_next(&n->rb_node);
923c42c19   Mike Galbraith   perf_counter tool...
340
341
342
  	}
  
  	if (!found) {
66aeb6d5c   Kirill Smelkov   perf top: Fix cod...
343
344
  		fprintf(stderr, "Sorry, %s is not active.
  ", buf);
923c42c19   Mike Galbraith   perf_counter tool...
345
  		sleep(1);
923c42c19   Mike Galbraith   perf_counter tool...
346
  	} else
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
347
  		perf_top__parse_source(top, found);
923c42c19   Mike Galbraith   perf_counter tool...
348
349
350
351
  
  out_free:
  	free(buf);
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
352
  static void perf_top__print_mapped_keys(struct perf_top *top)
923c42c19   Mike Galbraith   perf_counter tool...
353
  {
091bd2e99   Mike Galbraith   perf top: Improve...
354
  	char *name = NULL;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
355
356
  	if (top->sym_filter_entry) {
  		struct symbol *sym = top->sym_filter_entry->ms.sym;
091bd2e99   Mike Galbraith   perf top: Improve...
357
358
359
360
361
362
  		name = sym->name;
  	}
  
  	fprintf(stdout, "
  Mapped keys:
  ");
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
363
364
365
366
  	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...
367

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
368
369
370
  	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...
371

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
372
373
  	fprintf(stdout, "\t[f]     profile display filter (count).    \t(%d)
  ", top->count_filter);
091bd2e99   Mike Galbraith   perf top: Improve...
374

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
375
376
  	fprintf(stdout, "\t[F]     annotate display filter (percent). \t(%d%%)
  ", top->sym_pcnt_filter);
6cff0e8db   Kirill Smelkov   perf top: Teach i...
377
378
379
380
  	fprintf(stdout, "\t[s]     annotate symbol.                   \t(%s)
  ", name?: "NULL");
  	fprintf(stdout, "\t[S]     stop annotation.
  ");
091bd2e99   Mike Galbraith   perf top: Improve...
381

8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
382
  	fprintf(stdout,
1a72cfa68   Kirill Smelkov   perf top: Fix hel...
383
384
  		"\t[K]     hide kernel_symbols symbols.     \t(%s)
  ",
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
385
  		top->hide_kernel_symbols ? "yes" : "no");
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
386
387
388
  	fprintf(stdout,
  		"\t[U]     hide user symbols.               \t(%s)
  ",
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
389
390
391
  		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...
392
393
394
  	fprintf(stdout, "\t[qQ]    quit.
  ");
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
395
  static int perf_top__key_mapped(struct perf_top *top, int c)
091bd2e99   Mike Galbraith   perf top: Improve...
396
397
398
399
400
401
402
403
  {
  	switch (c) {
  		case 'd':
  		case 'e':
  		case 'f':
  		case 'z':
  		case 'q':
  		case 'Q':
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
404
405
  		case 'K':
  		case 'U':
6cff0e8db   Kirill Smelkov   perf top: Teach i...
406
407
408
  		case 'F':
  		case 's':
  		case 'S':
091bd2e99   Mike Galbraith   perf top: Improve...
409
410
  			return 1;
  		case 'E':
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
411
  			return top->evlist->nr_entries > 1 ? 1 : 0;
83a0944fa   Ingo Molnar   perf: Enable more...
412
413
  		default:
  			break;
091bd2e99   Mike Galbraith   perf top: Improve...
414
415
416
  	}
  
  	return 0;
923c42c19   Mike Galbraith   perf_counter tool...
417
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
418
  static void perf_top__handle_keypress(struct perf_top *top, int c)
923c42c19   Mike Galbraith   perf_counter tool...
419
  {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
420
  	if (!perf_top__key_mapped(top, c)) {
091bd2e99   Mike Galbraith   perf top: Improve...
421
422
  		struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
  		struct termios tc, save;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
423
  		perf_top__print_mapped_keys(top);
091bd2e99   Mike Galbraith   perf top: Improve...
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
  		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);
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
439
  		if (!perf_top__key_mapped(top, c))
091bd2e99   Mike Galbraith   perf top: Improve...
440
441
  			return;
  	}
923c42c19   Mike Galbraith   perf_counter tool...
442
443
  	switch (c) {
  		case 'd':
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
444
445
446
  			prompt_integer(&top->delay_secs, "Enter display delay");
  			if (top->delay_secs < 1)
  				top->delay_secs = 1;
923c42c19   Mike Galbraith   perf_counter tool...
447
448
  			break;
  		case 'e':
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
449
450
451
452
453
454
455
456
  			prompt_integer(&top->print_entries, "Enter display entries (lines)");
  			if (top->print_entries == 0) {
  				struct sigaction act = {
  					.sa_sigaction = perf_top__sig_winch,
  					.sa_flags     = SA_SIGINFO,
  				};
  				perf_top__sig_winch(SIGWINCH, NULL, top);
  				sigaction(SIGWINCH, &act, NULL);
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
457
458
  			} else
  				signal(SIGWINCH, SIG_DFL);
923c42c19   Mike Galbraith   perf_counter tool...
459
460
  			break;
  		case 'E':
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
461
  			if (top->evlist->nr_entries > 1) {
ce2d17ca7   Akihiro Nagai   perf top: Fix uni...
462
463
  				/* Select 0 as the default event: */
  				int counter = 0;
923c42c19   Mike Galbraith   perf_counter tool...
464
465
  				fprintf(stderr, "
  Available events:");
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
466

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
467
468
469
  				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...
470

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

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
473
474
475
476
  				if (counter >= top->evlist->nr_entries) {
  					top->sym_evsel = list_entry(top->evlist->entries.next, struct perf_evsel, node);
  					fprintf(stderr, "Sorry, no such event, using %s.
  ", event_name(top->sym_evsel));
923c42c19   Mike Galbraith   perf_counter tool...
477
  					sleep(1);
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
478
  					break;
923c42c19   Mike Galbraith   perf_counter tool...
479
  				}
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
480
481
  				list_for_each_entry(top->sym_evsel, &top->evlist->entries, node)
  					if (top->sym_evsel->idx == counter)
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
482
  						break;
ec52d9765   Arnaldo Carvalho de Melo   perf top: Remove ...
483
  			} else
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
484
  				top->sym_evsel = list_entry(top->evlist->entries.next, struct perf_evsel, node);
923c42c19   Mike Galbraith   perf_counter tool...
485
486
  			break;
  		case 'f':
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
487
  			prompt_integer(&top->count_filter, "Enter display event count filter");
923c42c19   Mike Galbraith   perf_counter tool...
488
489
  			break;
  		case 'F':
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
490
491
  			prompt_percent(&top->sym_pcnt_filter,
  				       "Enter details display event filter (percent)");
923c42c19   Mike Galbraith   perf_counter tool...
492
  			break;
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
493
  		case 'K':
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
494
  			top->hide_kernel_symbols = !top->hide_kernel_symbols;
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
495
  			break;
923c42c19   Mike Galbraith   perf_counter tool...
496
497
498
499
  		case 'q':
  		case 'Q':
  			printf("exiting.
  ");
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
500
501
  			if (top->dump_symtab)
  				perf_session__fprintf_dsos(top->session, stderr);
923c42c19   Mike Galbraith   perf_counter tool...
502
503
  			exit(0);
  		case 's':
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
504
  			perf_top__prompt_symbol(top, "Enter details symbol");
923c42c19   Mike Galbraith   perf_counter tool...
505
506
  			break;
  		case 'S':
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
507
  			if (!top->sym_filter_entry)
923c42c19   Mike Galbraith   perf_counter tool...
508
509
  				break;
  			else {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
510
  				struct hist_entry *syme = top->sym_filter_entry;
923c42c19   Mike Galbraith   perf_counter tool...
511

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
512
  				top->sym_filter_entry = NULL;
923c42c19   Mike Galbraith   perf_counter tool...
513
  				__zero_source_counters(syme);
923c42c19   Mike Galbraith   perf_counter tool...
514
515
  			}
  			break;
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
516
  		case 'U':
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
517
  			top->hide_user_symbols = !top->hide_user_symbols;
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
518
  			break;
923c42c19   Mike Galbraith   perf_counter tool...
519
  		case 'z':
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
520
  			top->zero = !top->zero;
923c42c19   Mike Galbraith   perf_counter tool...
521
  			break;
83a0944fa   Ingo Molnar   perf: Enable more...
522
523
  		default:
  			break;
923c42c19   Mike Galbraith   perf_counter tool...
524
525
  	}
  }
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
526
527
528
529
530
531
532
533
534
535
  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 ...
536
  	hists__decay_entries_threaded(&t->sym_evsel->hists,
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
537
538
  				      t->hide_user_symbols,
  				      t->hide_kernel_symbols);
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
539
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
540
  static void *display_thread_tui(void *arg)
c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
541
  {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
542
  	struct perf_top *top = arg;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
543
  	const char *help = "For a higher level overview, try: perf top --sort comm,dso";
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
544
545
  	perf_top__sort_new_samples(top);
  	perf_evlist__tui_browse_hists(top->evlist, help,
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
546
  				      perf_top__sort_new_samples,
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
547
  				      top, top->delay_secs);
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
548

c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
549
550
551
552
  	exit_browser(0);
  	exit(0);
  	return NULL;
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
553
  static void *display_thread(void *arg)
078006012   Ingo Molnar   perf_counter tool...
554
  {
0f5486b5c   Frederic Weisbecker   perf_counter: Sle...
555
  	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
923c42c19   Mike Galbraith   perf_counter tool...
556
  	struct termios tc, save;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
557
  	struct perf_top *top = arg;
923c42c19   Mike Galbraith   perf_counter tool...
558
559
560
561
562
563
564
  	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...
565

3af6e3386   Arnaldo Carvalho de Melo   perf ui browser: ...
566
  	pthread__unblock_sigwinch();
923c42c19   Mike Galbraith   perf_counter tool...
567
  repeat:
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
568
  	delay_msecs = top->delay_secs * 1000;
923c42c19   Mike Galbraith   perf_counter tool...
569
570
571
  	tcsetattr(0, TCSANOW, &tc);
  	/* trash return*/
  	getc(stdin);
078006012   Ingo Molnar   perf_counter tool...
572

3af6e3386   Arnaldo Carvalho de Melo   perf ui browser: ...
573
  	while (1) {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
574
  		perf_top__print_sym_table(top);
3af6e3386   Arnaldo Carvalho de Melo   perf ui browser: ...
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
  		/*
  		 * 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...
591
592
  	c = getc(stdin);
  	tcsetattr(0, TCSAFLUSH, &save);
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
593
  	perf_top__handle_keypress(top, c);
923c42c19   Mike Galbraith   perf_counter tool...
594
  	goto repeat;
078006012   Ingo Molnar   perf_counter tool...
595
596
597
  
  	return NULL;
  }
2ab52083f   Anton Blanchard   perf top: Move sk...
598
  /* Tag samples to be skipped. */
f37a291c5   Ingo Molnar   perf_counter tool...
599
  static const char *skip_symbols[] = {
2ab52083f   Anton Blanchard   perf top: Move sk...
600
  	"default_idle",
b0e8572f3   Arnaldo Carvalho de Melo   perf top: Add nat...
601
  	"native_safe_halt",
2ab52083f   Anton Blanchard   perf top: Move sk...
602
603
604
605
  	"cpu_idle",
  	"enter_idle",
  	"exit_idle",
  	"mwait_idle",
59b900569   Arnaldo Carvalho de Melo   perf top: Add mwa...
606
  	"mwait_idle_with_hints",
8357275bb   Arnaldo Carvalho de Melo   perf top: Add pol...
607
  	"poll_idle",
3a3393ef7   Anton Blanchard   perf top: Add ppc...
608
609
  	"ppc64_runlatch_off",
  	"pseries_dedicated_idle_sleep",
2ab52083f   Anton Blanchard   perf top: Move sk...
610
611
  	NULL
  };
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
612
  static int symbol_filter(struct map *map __used, struct symbol *sym)
078006012   Ingo Molnar   perf_counter tool...
613
  {
de04687f8   Arnaldo Carvalho de Melo   perf_counter tool...
614
  	const char *name = sym->name;
2ab52083f   Anton Blanchard   perf top: Move sk...
615
  	int i;
de04687f8   Arnaldo Carvalho de Melo   perf_counter tool...
616

3a3393ef7   Anton Blanchard   perf top: Add ppc...
617
618
619
620
621
622
  	/*
  	 * 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...
623
624
625
626
627
628
629
  	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...
630
  		return 1;
078006012   Ingo Molnar   perf_counter tool...
631

2ab52083f   Anton Blanchard   perf top: Move sk...
632
633
  	for (i = 0; skip_symbols[i]; i++) {
  		if (!strcmp(skip_symbols[i], name)) {
171b3be9c   Arnaldo Carvalho de Melo   perf symbol: Move...
634
  			sym->ignore = true;
2ab52083f   Anton Blanchard   perf top: Move sk...
635
636
637
  			break;
  		}
  	}
078006012   Ingo Molnar   perf_counter tool...
638

078006012   Ingo Molnar   perf_counter tool...
639
640
  	return 0;
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
641
642
  static void perf_event__process_sample(struct perf_tool *tool,
  				       const union perf_event *event,
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
643
  				       struct perf_evsel *evsel,
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
644
  				       struct perf_sample *sample,
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
645
  				       struct machine *machine)
078006012   Ingo Molnar   perf_counter tool...
646
  {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
647
  	struct perf_top *top = container_of(tool, struct perf_top, tool);
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
648
  	struct symbol *parent = NULL;
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
649
  	u64 ip = event->ip.ip;
1ed091c45   Arnaldo Carvalho de Melo   perf tools: Conso...
650
  	struct addr_location al;
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
651
  	int err;
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
652

23346f21b   Arnaldo Carvalho de Melo   perf tools: Renam...
653
  	if (!machine && perf_guest) {
a1645ce12   Zhang, Yanmin   perf: 'perf kvm' ...
654
655
  		pr_err("Can't find guest [%d]'s kernel information
  ",
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
656
  			event->ip.pid);
a1645ce12   Zhang, Yanmin   perf: 'perf kvm' ...
657
658
  		return;
  	}
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
659
  	if (event->header.misc & PERF_RECORD_MISC_EXACT_IP)
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
660
  		top->exact_samples++;
1676b8a07   Peter Zijlstra   perf-top: Show th...
661

743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
662
  	if (perf_event__preprocess_sample(event, machine, &al, sample,
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
663
  					  symbol_filter) < 0 ||
72b8fa173   Arnaldo Carvalho de Melo   perf top: Exit if...
664
  	    al.filtered)
1ed091c45   Arnaldo Carvalho de Melo   perf tools: Conso...
665
  		return;
078006012   Ingo Molnar   perf_counter tool...
666

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
667
  	if (!top->kptr_restrict_warned &&
5f6f55809   Arnaldo Carvalho de Melo   perf top: Handle ...
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
  	    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);
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
683
  		top->kptr_restrict_warned = true;
5f6f55809   Arnaldo Carvalho de Melo   perf top: Handle ...
684
  	}
72b8fa173   Arnaldo Carvalho de Melo   perf top: Exit if...
685
  	if (al.sym == NULL) {
e4a338d05   Arnaldo Carvalho de Melo   perf top: Don't s...
686
687
  		const char *msg = "Kernel samples will not be resolved.
  ";
72b8fa173   Arnaldo Carvalho de Melo   perf top: Exit if...
688
689
690
691
692
693
694
695
696
697
698
  		/*
  		 * 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 ;-)
  		 */
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
699
  		if (!top->kptr_restrict_warned && !top->vmlinux_warned &&
e4a338d05   Arnaldo Carvalho de Melo   perf top: Don't s...
700
  		    al.map == machine->vmlinux_maps[MAP__FUNCTION] &&
72b8fa173   Arnaldo Carvalho de Melo   perf top: Exit if...
701
  		    RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
e4a338d05   Arnaldo Carvalho de Melo   perf top: Don't s...
702
703
704
705
706
707
708
709
710
711
712
713
  			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);
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
714
  			top->vmlinux_warned = true;
72b8fa173   Arnaldo Carvalho de Melo   perf top: Exit if...
715
  		}
6cff0e8db   Kirill Smelkov   perf top: Teach i...
716
  	}
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
717
  	if (al.sym == NULL || !al.sym->ignore) {
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
718
  		struct hist_entry *he;
70db7533c   Arnaldo Carvalho de Melo   perf evlist: Move...
719

19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
720
721
  		if ((sort__has_parent || symbol_conf.use_callchain) &&
  		    sample->callchain) {
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
722
723
  			err = machine__resolve_callchain(machine, evsel, al.thread,
  							 sample->callchain, &parent);
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
724
725
726
  			if (err)
  				return;
  		}
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
727
  		he = perf_evsel__add_hist_entry(evsel, &al, sample);
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
728
729
730
731
  		if (he == NULL) {
  			pr_err("Problem incrementing symbol period, skipping event
  ");
  			return;
5807806a9   Arnaldo Carvalho de Melo   perf top tui: Wai...
732
  		}
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
733

19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
734
  		if (symbol_conf.use_callchain) {
246d4ce81   Arnaldo Carvalho de Melo   perf session: Rem...
735
  			err = callchain_append(he->callchain, &evsel->hists.callchain_cursor,
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
736
737
738
739
  					       sample->period);
  			if (err)
  				return;
  		}
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
740
741
  		if (top->sort_has_symbols)
  			perf_top__record_precise_ip(top, he, evsel->idx, ip);
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
742
  	}
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
743
744
  
  	return;
078006012   Ingo Molnar   perf_counter tool...
745
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
746
  static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
078006012   Ingo Molnar   perf_counter tool...
747
  {
8d50e5b41   Arnaldo Carvalho de Melo   perf tools: Renam...
748
  	struct perf_sample sample;
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
749
  	struct perf_evsel *evsel;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
750
  	struct perf_session *session = top->session;
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
751
  	union perf_event *event;
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
752
753
  	struct machine *machine;
  	u8 origin;
5538becae   Frederic Weisbecker   perf tools: Propa...
754
  	int ret;
078006012   Ingo Molnar   perf_counter tool...
755

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
756
757
  	while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) {
  		ret = perf_session__parse_sample(session, event, &sample);
5538becae   Frederic Weisbecker   perf tools: Propa...
758
759
760
761
762
  		if (ret) {
  			pr_err("Can't parse sample, err = %d
  ", ret);
  			continue;
  		}
04391debc   Arnaldo Carvalho de Melo   perf evlist: Stea...
763

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
764
  		evsel = perf_evlist__id2evsel(session->evlist, sample.id);
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
765
  		assert(evsel != NULL);
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
766
  		origin = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
767
  		if (event->header.type == PERF_RECORD_SAMPLE)
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
768
  			++top->samples;
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
769
770
771
  
  		switch (origin) {
  		case PERF_RECORD_MISC_USER:
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
772
773
  			++top->us_samples;
  			if (top->hide_user_symbols)
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
774
  				continue;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
775
  			machine = perf_session__find_host_machine(session);
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
776
777
  			break;
  		case PERF_RECORD_MISC_KERNEL:
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
778
779
  			++top->kernel_samples;
  			if (top->hide_kernel_symbols)
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
780
  				continue;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
781
  			machine = perf_session__find_host_machine(session);
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
782
783
  			break;
  		case PERF_RECORD_MISC_GUEST_KERNEL:
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
784
785
  			++top->guest_kernel_samples;
  			machine = perf_session__find_machine(session, event->ip.pid);
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
786
787
  			break;
  		case PERF_RECORD_MISC_GUEST_USER:
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
788
  			++top->guest_us_samples;
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
789
790
791
792
793
794
795
796
  			/*
  			 * TODO: we don't process guest user from host side
  			 * except simple counting.
  			 */
  			/* Fall thru */
  		default:
  			continue;
  		}
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
797
798
799
800
  		if (event->header.type == PERF_RECORD_SAMPLE) {
  			perf_event__process_sample(&top->tool, event, evsel,
  						   &sample, machine);
  		} else if (event->header.type < PERF_RECORD_MAX) {
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
801
  			hists__inc_nr_events(&evsel->hists, event->header.type);
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
802
  			perf_event__process(&top->tool, event, &sample, machine);
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
803
  		} else
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
804
  			++session->hists.stats.nr_unknown_events;
078006012   Ingo Molnar   perf_counter tool...
805
  	}
078006012   Ingo Molnar   perf_counter tool...
806
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
807
  static void perf_top__mmap_read(struct perf_top *top)
2f01190aa   Frederic Weisbecker   perf top: Wait fo...
808
  {
70db7533c   Arnaldo Carvalho de Melo   perf evlist: Move...
809
  	int i;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
810
811
  	for (i = 0; i < top->evlist->nr_mmaps; i++)
  		perf_top__mmap_read_idx(top, i);
2f01190aa   Frederic Weisbecker   perf top: Wait fo...
812
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
813
  static void perf_top__start_counters(struct perf_top *top)
72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
814
  {
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
815
  	struct perf_evsel *counter, *first;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
816
  	struct perf_evlist *evlist = top->evlist;
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
817
818
  
  	first = list_entry(evlist->entries.next, struct perf_evsel, node);
7e4ff9e3e   Mike Galbraith   perf tools: Fix c...
819

72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
820
821
  	list_for_each_entry(counter, &evlist->entries, node) {
  		struct perf_event_attr *attr = &counter->attr;
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
822
  		struct xyarray *group_fd = NULL;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
823
  		if (top->group && counter != first)
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
824
  			group_fd = first->fd;
716c69fec   Ingo Molnar   perf top: Fall ba...
825

72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
826
  		attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
827
  		if (top->freq) {
72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
828
829
  			attr->sample_type |= PERF_SAMPLE_PERIOD;
  			attr->freq	  = 1;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
830
  			attr->sample_freq = top->freq;
72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
831
  		}
d6d901c23   Zhang, Yanmin   perf events: Chan...
832

70db7533c   Arnaldo Carvalho de Melo   perf evlist: Move...
833
834
835
836
  		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...
837
838
  		if (symbol_conf.use_callchain)
  			attr->sample_type |= PERF_SAMPLE_CALLCHAIN;
72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
839
  		attr->mmap = 1;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
840
  		attr->comm = 1;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
841
  		attr->inherit = top->inherit;
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
842
  retry_sample_id:
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
843
  		attr->sample_id_all = top->sample_id_all_avail ? 1 : 0;
72cb7013e   Arnaldo Carvalho de Melo   perf top: Use per...
844
  try_again:
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
845
846
  		if (perf_evsel__open(counter, top->evlist->cpus,
  				     top->evlist->threads, top->group,
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
847
  				     group_fd) < 0) {
d6d901c23   Zhang, Yanmin   perf events: Chan...
848
  			int err = errno;
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
849
  			if (err == EPERM || err == EACCES) {
b8631e6eb   Arnaldo Carvalho de Melo   perf ui: Rename u...
850
  				ui__error_paranoid();
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
851
  				goto out_err;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
852
  			} else if (err == EINVAL && top->sample_id_all_avail) {
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
853
854
855
  				/*
  				 * Old kernel, no attr->sample_id_type_all field
  				 */
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
856
  				top->sample_id_all_avail = false;
7b27509fc   Arnaldo Carvalho de Melo   perf hists browse...
857
  				goto retry_sample_id;
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
858
  			}
d6d901c23   Zhang, Yanmin   perf events: Chan...
859
860
861
862
863
  			/*
  			 * 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...
864
865
  			if (attr->type == PERF_TYPE_HARDWARE &&
  			    attr->config == PERF_COUNT_HW_CPU_CYCLES) {
d6d901c23   Zhang, Yanmin   perf events: Chan...
866
  				if (verbose)
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
867
868
869
870
  					ui__warning("Cycles event not supported,
  "
  						    "trying to fall back to cpu-clock-ticks
  ");
d6d901c23   Zhang, Yanmin   perf events: Chan...
871
872
873
874
875
  
  				attr->type = PERF_TYPE_SOFTWARE;
  				attr->config = PERF_COUNT_SW_CPU_CLOCK;
  				goto try_again;
  			}
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
876

ca6a42586   David Ahern   perf tools: Emit ...
877
878
879
880
881
  			if (err == ENOENT) {
  				ui__warning("The %s event is not supported.
  ",
  					    event_name(counter));
  				goto out_err;
cdce44590   Namhyung Kim   perf top: Add err...
882
883
884
885
886
887
  			} else if (err == EMFILE) {
  				ui__warning("Too many events are opened.
  "
  					    "Try again after reducing the number of events
  ");
  				goto out_err;
ca6a42586   David Ahern   perf tools: Emit ...
888
  			}
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
889
890
891
892
893
894
895
896
  			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...
897
  		}
716c69fec   Ingo Molnar   perf top: Fall ba...
898
  	}
70db7533c   Arnaldo Carvalho de Melo   perf evlist: Move...
899

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
900
  	if (perf_evlist__mmap(evlist, top->mmap_pages, false) < 0) {
c286c419c   Arnaldo Carvalho de Melo   perf tools: Fixup...
901
902
903
904
905
906
907
908
909
910
911
  		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...
912
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
913
  static int perf_top__setup_sample_type(struct perf_top *top)
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
914
  {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
915
  	if (!top->sort_has_symbols) {
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
916
917
918
919
  		if (symbol_conf.use_callchain) {
  			ui__warning("Selected -g but \"sym\" not present in --sort/-s.");
  			return -EINVAL;
  		}
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
920
  	} else if (!top->dont_use_callchains && callchain_param.mode != CHAIN_NONE) {
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
921
922
923
924
925
926
927
928
929
  		if (callchain_register_param(&callchain_param) < 0) {
  			ui__warning("Can't register callchain params.
  ");
  			return -EINVAL;
  		}
  	}
  
  	return 0;
  }
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
930
  static int __cmd_top(struct perf_top *top)
716c69fec   Ingo Molnar   perf top: Fall ba...
931
932
  {
  	pthread_t thread;
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
933
  	int ret;
d8f66248d   Arnaldo Carvalho de Melo   perf session: Pas...
934
  	/*
b3165f414   Arnaldo Carvalho de Melo   perf session: Mov...
935
936
  	 * 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...
937
  	 */
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
938
939
  	top->session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
  	if (top->session == NULL)
b3165f414   Arnaldo Carvalho de Melo   perf session: Mov...
940
  		return -ENOMEM;
078006012   Ingo Molnar   perf_counter tool...
941

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
942
  	ret = perf_top__setup_sample_type(top);
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
943
944
  	if (ret)
  		goto out_delete;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
945
946
  	if (top->target_tid != -1)
  		perf_event__synthesize_thread_map(&top->tool, top->evlist->threads,
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
947
  						  perf_event__process,
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
948
  						  &top->session->host_machine);
5b2bb75a0   Arnaldo Carvalho de Melo   perf top: Support...
949
  	else
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
950
951
952
953
954
  		perf_event__synthesize_threads(&top->tool, perf_event__process,
  					       &top->session->host_machine);
  	perf_top__start_counters(top);
  	top->session->evlist = top->evlist;
  	perf_session__update_sample_type(top->session);
078006012   Ingo Molnar   perf_counter tool...
955

2f01190aa   Frederic Weisbecker   perf top: Wait fo...
956
  	/* Wait for a minimal set of events before starting the snapshot */
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
957
  	poll(top->evlist->pollfd, top->evlist->nr_fds, 100);
2f01190aa   Frederic Weisbecker   perf top: Wait fo...
958

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
959
  	perf_top__mmap_read(top);
2f01190aa   Frederic Weisbecker   perf top: Wait fo...
960

c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
961
  	if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui :
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
962
  							    display_thread), top)) {
078006012   Ingo Molnar   perf_counter tool...
963
964
965
966
  		printf("Could not create display thread.
  ");
  		exit(-1);
  	}
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
967
  	if (top->realtime_prio) {
078006012   Ingo Molnar   perf_counter tool...
968
  		struct sched_param param;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
969
  		param.sched_priority = top->realtime_prio;
078006012   Ingo Molnar   perf_counter tool...
970
971
972
973
974
975
976
977
  		if (sched_setscheduler(0, SCHED_FIFO, &param)) {
  			printf("Could not set realtime priority.
  ");
  			exit(-1);
  		}
  	}
  
  	while (1) {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
978
  		u64 hits = top->samples;
078006012   Ingo Molnar   perf_counter tool...
979

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
980
  		perf_top__mmap_read(top);
078006012   Ingo Molnar   perf_counter tool...
981

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
982
983
  		if (hits == top->samples)
  			ret = poll(top->evlist->pollfd, top->evlist->nr_fds, 100);
078006012   Ingo Molnar   perf_counter tool...
984
  	}
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
985
  out_delete:
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
986
987
  	perf_session__delete(top->session);
  	top->session = NULL;
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
988
989
990
991
992
  
  	return 0;
  }
  
  static int
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
993
  parse_callchain_opt(const struct option *opt, const char *arg, int unset)
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
994
  {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
995
  	struct perf_top *top = (struct perf_top *)opt->value;
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
996
997
998
999
1000
1001
1002
  	char *tok, *tok2;
  	char *endptr;
  
  	/*
  	 * --no-call-graph
  	 */
  	if (unset) {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1003
  		top->dont_use_callchains = true;
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
  		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;
806fb6300   Arnaldo Carvalho de Melo   perf evlist: Alwa...
1031
  	} else
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
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
  		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...
1068
1069
  	return 0;
  }
b456bae0f   Ingo Molnar   perf top: Convert...
1070
1071
1072
1073
1074
  
  static const char * const top_usage[] = {
  	"perf top [<options>]",
  	NULL
  };
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
  int cmd_top(int argc, const char **argv, const char *prefix __used)
  {
  	struct perf_evsel *pos;
  	int status = -ENOMEM;
  	struct perf_top top = {
  		.count_filter	     = 5,
  		.delay_secs	     = 2,
  		.target_pid	     = -1,
  		.target_tid	     = -1,
  		.freq		     = 1000, /* 1 KHz */
  		.sample_id_all_avail = true,
  		.mmap_pages	     = 128,
  		.sym_pcnt_filter     = 5,
  	};
  	char callchain_default_opt[] = "fractal,0.5,callee";
  	const struct option options[] = {
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1091
  	OPT_CALLBACK('e', "event", &top.evlist, "event",
86847b62f   Thomas Gleixner   perf_counter tool...
1092
  		     "event selector. use 'perf list' to list available events",
f120f9d51   Jiri Olsa   perf tools: De-op...
1093
  		     parse_events_option),
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1094
  	OPT_INTEGER('c', "count", &top.default_interval,
b456bae0f   Ingo Molnar   perf top: Convert...
1095
  		    "event period to sample"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1096
  	OPT_INTEGER('p', "pid", &top.target_pid,
d6d901c23   Zhang, Yanmin   perf events: Chan...
1097
  		    "profile events on existing process id"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1098
  	OPT_INTEGER('t', "tid", &top.target_tid,
d6d901c23   Zhang, Yanmin   perf events: Chan...
1099
  		    "profile events on existing thread id"),
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1100
  	OPT_BOOLEAN('a', "all-cpus", &top.system_wide,
b456bae0f   Ingo Molnar   perf top: Convert...
1101
  			    "system-wide collection from all CPUs"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1102
  	OPT_STRING('C', "cpu", &top.cpu_list, "cpu",
c45c6ea2e   Stephane Eranian   perf tools: Add t...
1103
  		    "list of cpus to monitor"),
b32d133ae   Arnaldo Carvalho de Melo   perf symbols: Sim...
1104
1105
  	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
  		   "file", "vmlinux pathname"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1106
  	OPT_BOOLEAN('K', "hide_kernel_symbols", &top.hide_kernel_symbols,
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
1107
  		    "hide kernel symbols"),
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1108
1109
  	OPT_UINTEGER('m', "mmap-pages", &top.mmap_pages, "number of mmap data pages"),
  	OPT_INTEGER('r', "realtime", &top.realtime_prio,
b456bae0f   Ingo Molnar   perf top: Convert...
1110
  		    "collect data with this RT SCHED_FIFO priority"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1111
  	OPT_INTEGER('d', "delay", &top.delay_secs,
b456bae0f   Ingo Molnar   perf top: Convert...
1112
  		    "number of seconds to delay between refreshes"),
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1113
  	OPT_BOOLEAN('D', "dump-symtab", &top.dump_symtab,
b456bae0f   Ingo Molnar   perf top: Convert...
1114
  			    "dump the symbol table used for profiling"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1115
  	OPT_INTEGER('f', "count-filter", &top.count_filter,
b456bae0f   Ingo Molnar   perf top: Convert...
1116
  		    "only display functions with more events than this"),
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1117
  	OPT_BOOLEAN('g', "group", &top.group,
b456bae0f   Ingo Molnar   perf top: Convert...
1118
  			    "put the counters into a counter group"),
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1119
  	OPT_BOOLEAN('i', "inherit", &top.inherit,
0fdc7e67d   Mike Galbraith   perf_counter tool...
1120
  		    "child tasks inherit counters"),
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1121
  	OPT_STRING(0, "sym-annotate", &top.sym_filter, "symbol name",
6cff0e8db   Kirill Smelkov   perf top: Teach i...
1122
  		    "symbol to annotate"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1123
  	OPT_BOOLEAN('z', "zero", &top.zero,
b456bae0f   Ingo Molnar   perf top: Convert...
1124
  		    "zero history across updates"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1125
  	OPT_INTEGER('F', "freq", &top.freq,
b456bae0f   Ingo Molnar   perf top: Convert...
1126
  		    "profile at this frequency"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1127
  	OPT_INTEGER('E', "entries", &top.print_entries,
6e53cdf11   Ingo Molnar   perf top: Reduce ...
1128
  		    "display this many functions"),
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1129
  	OPT_BOOLEAN('U', "hide_user_symbols", &top.hide_user_symbols,
8ffcda173   Arnaldo Carvalho de Melo   perf top: Introdu...
1130
  		    "hide user symbols"),
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1131
1132
  	OPT_BOOLEAN(0, "tui", &top.use_tui, "Use the TUI interface"),
  	OPT_BOOLEAN(0, "stdio", &top.use_stdio, "Use the stdio interface"),
c05556421   Ian Munsie   perf: Fix endiann...
1133
  	OPT_INCR('v', "verbose", &verbose,
3da297a60   Ingo Molnar   perf record: Fall...
1134
  		    "be more verbose (show counter open errors, etc)"),
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
1135
1136
1137
1138
  	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"),
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1139
  	OPT_CALLBACK_DEFAULT('G', "call-graph", &top, "output_type,min_percent, call_order",
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
1140
1141
1142
  		     "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...
1143
1144
1145
1146
1147
1148
1149
1150
  	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 ...
1151
1152
1153
1154
1155
1156
  	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...
1157
  	OPT_END()
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1158
  	};
b456bae0f   Ingo Molnar   perf top: Convert...
1159

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1160
1161
  	top.evlist = perf_evlist__new(NULL, NULL);
  	if (top.evlist == NULL)
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
1162
  		return -ENOMEM;
ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
1163
  	symbol_conf.exclude_other = false;
b456bae0f   Ingo Molnar   perf top: Convert...
1164

b456bae0f   Ingo Molnar   perf top: Convert...
1165
1166
1167
  	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...
1168
1169
1170
1171
  	if (sort_order == default_sort_order)
  		sort_order = "dso,symbol";
  
  	setup_sorting(top_usage, options);
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1172
  	if (top.use_stdio)
c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
1173
  		use_browser = 0;
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1174
  	else if (top.use_tui)
c0443df1b   Arnaldo Carvalho de Melo   perf top: Introdu...
1175
1176
1177
  		use_browser = 1;
  
  	setup_browser(false);
b456bae0f   Ingo Molnar   perf top: Convert...
1178
  	/* CPU and PID are mutually exclusive */
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1179
  	if (top.target_tid > 0 && top.cpu_list) {
b456bae0f   Ingo Molnar   perf top: Convert...
1180
1181
1182
  		printf("WARNING: PID switch overriding CPU
  ");
  		sleep(1);
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1183
  		top.cpu_list = NULL;
b456bae0f   Ingo Molnar   perf top: Convert...
1184
  	}
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1185
1186
  	if (top.target_pid != -1)
  		top.target_tid = top.target_pid;
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
1187

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1188
1189
  	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...
1190
  		usage_with_options(top_usage, options);
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1191
1192
  	if (!top.evlist->nr_entries &&
  	    perf_evlist__add_default(top.evlist) < 0) {
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1193
1194
1195
1196
  		pr_err("Not enough memory for event selector list
  ");
  		return -ENOMEM;
  	}
5a8e5a306   Arnaldo Carvalho de Melo   perf top: Allocat...
1197

d04b35f80   Arnaldo Carvalho de Melo   perf symbols: Add...
1198
  	symbol_conf.nr_events = top.evlist->nr_entries;
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1199
1200
  	if (top.delay_secs < 1)
  		top.delay_secs = 1;
2f335a02b   Frederic Weisbecker   perf top: Fix zer...
1201

7e4ff9e3e   Mike Galbraith   perf tools: Fix c...
1202
1203
1204
  	/*
  	 * User specified count overrides default frequency.
  	 */
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1205
  	if (top.default_interval)
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1206
1207
  		top.freq = 0;
  	else if (top.freq) {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1208
  		top.default_interval = top.freq;
7e4ff9e3e   Mike Galbraith   perf tools: Fix c...
1209
1210
1211
1212
1213
  	} else {
  		fprintf(stderr, "frequency and count are zero, aborting
  ");
  		exit(EXIT_FAILURE);
  	}
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1214
  	list_for_each_entry(pos, &top.evlist->entries, node) {
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1215
1216
1217
  		/*
  		 * Fill in the ones not specifically initialized via -c:
  		 */
806fb6300   Arnaldo Carvalho de Melo   perf evlist: Alwa...
1218
1219
  		if (!pos->attr.sample_period)
  			pos->attr.sample_period = top.default_interval;
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1220
  	}
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1221
  	top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
cc841580a   Arnaldo Carvalho de Melo   perf top: Fix ann...
1222

ab81f3fd3   Arnaldo Carvalho de Melo   perf top: Reuse t...
1223
  	symbol_conf.priv_size = sizeof(struct annotation);
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1224
1225
1226
1227
  
  	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...
1228
1229
1230
  	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...
1231
1232
1233
1234
  	/*
  	 * Avoid annotation data structures overhead when symbols aren't on the
  	 * sort list.
  	 */
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1235
  	top.sort_has_symbols = sort_sym.list.next != NULL;
19d4ac3c1   Arnaldo Carvalho de Melo   perf top: Add cal...
1236

1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1237
  	get_term_dimensions(&top.winsize);
8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1238
  	if (top.print_entries == 0) {
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1239
1240
1241
1242
1243
1244
  		struct sigaction act = {
  			.sa_sigaction = perf_top__sig_winch,
  			.sa_flags     = SA_SIGINFO,
  		};
  		perf_top__update_print_entries(&top);
  		sigaction(SIGWINCH, &act, NULL);
3b6ed9889   Arnaldo Carvalho de Melo   perf top: Use all...
1245
  	}
1758af10c   Arnaldo Carvalho de Melo   perf top: Stop us...
1246
  	status = __cmd_top(&top);
806fb6300   Arnaldo Carvalho de Melo   perf evlist: Alwa...
1247

8c3e10eb1   Arnaldo Carvalho de Melo   perf top: Move di...
1248
  	perf_evlist__delete(top.evlist);
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1249
1250
  
  	return status;
b456bae0f   Ingo Molnar   perf top: Convert...
1251
  }