builtin-top.c 30.1 KB
Newer Older
1
/*
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
 * 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>
 *
 * 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)
18
 */
19
#include "builtin.h"
20

21
#include "perf.h"
22

23
#include "util/color.h"
24 25
#include "util/session.h"
#include "util/symbol.h"
26
#include "util/thread.h"
27
#include "util/util.h"
28
#include <linux/rbtree.h>
29 30
#include "util/parse-options.h"
#include "util/parse-events.h"
31

32 33
#include "util/debug.h"

34 35
#include <assert.h>
#include <fcntl.h>
36

37
#include <stdio.h>
38 39
#include <termios.h>
#include <unistd.h>
40

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
#include <errno.h>
#include <time.h>
#include <sched.h>
#include <pthread.h>

#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>

57
static int			fd[MAX_NR_CPUS][MAX_COUNTERS];
58

59
static int			system_wide			=      0;
60

61
static int			default_interval		=      0;
62

63
static int			count_filter			=      5;
64
static int			print_entries;
65

66 67 68 69 70 71
static int			target_pid			=     -1;
static int			inherit				=      0;
static int			profile_cpu			=     -1;
static int			nr_cpus				=      0;
static unsigned int		realtime_prio			=      0;
static int			group				=      0;
72
static unsigned int		page_size;
73 74
static unsigned int		mmap_pages			=     16;
static int			freq				=   1000; /* 1 KHz */
75

76 77 78
static int			delay_secs			=      2;
static int			zero                            =      0;
static int			dump_symtab                     =      0;
79

80 81
static bool			hide_kernel_symbols		=  false;
static bool			hide_user_symbols		=  false;
82
static struct winsize		winsize;
83

84 85 86 87 88 89 90 91 92 93 94
/*
 * Source
 */

struct source_line {
	u64			eip;
	unsigned long		count[MAX_COUNTERS];
	char			*line;
	struct source_line	*next;
};

95 96 97 98 99
static char			*sym_filter			=   NULL;
struct sym_entry		*sym_filter_entry		=   NULL;
static int			sym_pcnt_filter			=      5;
static int			sym_counter			=      0;
static int			display_weighted		=     -1;
100

101 102 103 104
/*
 * Symbols
 */

105 106 107 108 109 110 111
struct sym_entry_source {
	struct source_line	*source;
	struct source_line	*lines;
	struct source_line	**lines_tail;
	pthread_mutex_t		lock;
};

112
struct sym_entry {
113 114
	struct rb_node		rb_node;
	struct list_head	node;
115 116
	unsigned long		snap_count;
	double			weight;
117
	int			skip;
118
	u16			name_len;
119
	u8			origin;
120
	struct map		*map;
121
	struct sym_entry_source	*src;
122
	unsigned long		count[0];
123 124
};

125 126 127 128
/*
 * Source functions
 */

129 130
static inline struct symbol *sym_entry__symbol(struct sym_entry *self)
{
131
       return ((void *)self) + symbol_conf.priv_size;
132 133
}

134
static void get_term_dimensions(struct winsize *ws)
135
{
136 137 138 139 140 141 142 143 144 145
	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;
		}
146
	}
147 148 149 150
#ifdef TIOCGWINSZ
	if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
	    ws->ws_row && ws->ws_col)
		return;
151
#endif
152 153
	ws->ws_row = 25;
	ws->ws_col = 80;
154 155
}

156
static void update_print_entries(struct winsize *ws)
157
{
158 159
	print_entries = ws->ws_row;

160 161 162 163 164 165
	if (print_entries > 9)
		print_entries -= 9;
}

static void sig_winch_handler(int sig __used)
{
166 167
	get_term_dimensions(&winsize);
	update_print_entries(&winsize);
168 169
}

170 171 172
static void parse_source(struct sym_entry *syme)
{
	struct symbol *sym;
173
	struct sym_entry_source *source;
174
	struct map *map;
175
	FILE *file;
176
	char command[PATH_MAX*2];
177 178
	const char *path;
	u64 len;
179 180 181 182

	if (!syme)
		return;

183
	if (syme->src == NULL) {
184
		syme->src = zalloc(sizeof(*source));
185 186 187 188 189 190 191 192 193
		if (syme->src == NULL)
			return;
		pthread_mutex_init(&syme->src->lock, NULL);
	}

	source = syme->src;

	if (source->lines) {
		pthread_mutex_lock(&source->lock);
194 195 196
		goto out_assign;
	}

197
	sym = sym_entry__symbol(syme);
198 199
	map = syme->map;
	path = map->dso->long_name;
200 201 202

	len = sym->end - sym->start;

203 204 205
	sprintf(command,
		"objdump --start-address=0x%016Lx "
			 "--stop-address=0x%016Lx -dS %s",
206 207
		map->unmap_ip(map, sym->start),
		map->unmap_ip(map, sym->end), path);
208 209 210 211 212

	file = popen(command, "r");
	if (!file)
		return;

213 214
	pthread_mutex_lock(&source->lock);
	source->lines_tail = &source->lines;
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
	while (!feof(file)) {
		struct source_line *src;
		size_t dummy = 0;
		char *c;

		src = malloc(sizeof(struct source_line));
		assert(src != NULL);
		memset(src, 0, sizeof(struct source_line));

		if (getline(&src->line, &dummy, file) < 0)
			break;
		if (!src->line)
			break;

		c = strchr(src->line, '\n');
		if (c)
			*c = 0;

		src->next = NULL;
234 235
		*source->lines_tail = src;
		source->lines_tail = &src->next;
236 237 238

		if (strlen(src->line)>8 && src->line[8] == ':') {
			src->eip = strtoull(src->line, NULL, 16);
239
			src->eip = map->unmap_ip(map, src->eip);
240 241 242
		}
		if (strlen(src->line)>8 && src->line[16] == ':') {
			src->eip = strtoull(src->line, NULL, 16);
243
			src->eip = map->unmap_ip(map, src->eip);
244 245 246 247 248
		}
	}
	pclose(file);
out_assign:
	sym_filter_entry = syme;
249
	pthread_mutex_unlock(&source->lock);
250 251 252 253 254 255 256
}

static void __zero_source_counters(struct sym_entry *syme)
{
	int i;
	struct source_line *line;

257
	line = syme->src->lines;
258 259 260 261 262 263 264 265 266 267 268 269 270 271
	while (line) {
		for (i = 0; i < nr_counters; i++)
			line->count[i] = 0;
		line = line->next;
	}
}

static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip)
{
	struct source_line *line;

	if (syme != sym_filter_entry)
		return;

272
	if (pthread_mutex_trylock(&syme->src->lock))
273 274
		return;

275
	if (syme->src == NULL || syme->src->source == NULL)
276 277
		goto out_unlock;

278
	for (line = syme->src->lines; line; line = line->next) {
279 280 281 282 283 284 285 286
		if (line->eip == ip) {
			line->count[counter]++;
			break;
		}
		if (line->eip > ip)
			break;
	}
out_unlock:
287
	pthread_mutex_unlock(&syme->src->lock);
288 289 290 291
}

static void lookup_sym_source(struct sym_entry *syme)
{
292
	struct symbol *symbol = sym_entry__symbol(syme);
293 294 295 296 297
	struct source_line *line;
	char pattern[PATH_MAX];

	sprintf(pattern, "<%s>:", symbol->name);

298 299
	pthread_mutex_lock(&syme->src->lock);
	for (line = syme->src->lines; line; line = line->next) {
300
		if (strstr(line->line, pattern)) {
301
			syme->src->source = line;
302 303 304
			break;
		}
	}
305
	pthread_mutex_unlock(&syme->src->lock);
306 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
}

static void show_lines(struct source_line *queue, int count, int total)
{
	int i;
	struct source_line *line;

	line = queue;
	for (i = 0; i < count; i++) {
		float pcnt = 100.0*(float)line->count[sym_counter]/(float)total;

		printf("%8li %4.1f%%\t%s\n", line->count[sym_counter], pcnt, line->line);
		line = line->next;
	}
}

#define TRACE_COUNT     3

static void show_details(struct sym_entry *syme)
{
	struct symbol *symbol;
	struct source_line *line;
	struct source_line *line_queue = NULL;
	int displayed = 0;
	int line_queue_count = 0, total = 0, more = 0;

	if (!syme)
		return;

335
	if (!syme->src->source)
336 337
		lookup_sym_source(syme);

338
	if (!syme->src->source)
339 340
		return;

341
	symbol = sym_entry__symbol(syme);
342 343 344
	printf("Showing %s for %s\n", event_name(sym_counter), symbol->name);
	printf("  Events  Pcnt (>=%d%%)\n", sym_pcnt_filter);

345 346
	pthread_mutex_lock(&syme->src->lock);
	line = syme->src->source;
347 348 349 350 351
	while (line) {
		total += line->count[sym_counter];
		line = line->next;
	}

352
	line = syme->src->source;
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
	while (line) {
		float pcnt = 0.0;

		if (!line_queue_count)
			line_queue = line;
		line_queue_count++;

		if (line->count[sym_counter])
			pcnt = 100.0 * line->count[sym_counter] / (float)total;
		if (pcnt >= (float)sym_pcnt_filter) {
			if (displayed <= print_entries)
				show_lines(line_queue, line_queue_count, total);
			else more++;
			displayed += line_queue_count;
			line_queue_count = 0;
			line_queue = NULL;
		} else if (line_queue_count > TRACE_COUNT) {
			line_queue = line_queue->next;
			line_queue_count--;
		}

		line->count[sym_counter] = zero ? 0 : line->count[sym_counter] * 7 / 8;
		line = line->next;
	}
377
	pthread_mutex_unlock(&syme->src->lock);
378 379 380
	if (more)
		printf("%d lines not displayed, maybe increase display entries [e]\n", more);
}
381

382
/*
383
 * Symbols will be added here in event__process_sample and will get out
384 385 386
 * after decayed.
 */
static LIST_HEAD(active_symbols);
387
static pthread_mutex_t active_symbols_lock = PTHREAD_MUTEX_INITIALIZER;
388 389 390 391 392 393

/*
 * Ordering weight: count-1 * count-2 * ... / count-n
 */
static double sym_weight(const struct sym_entry *sym)
{
394
	double weight = sym->snap_count;
395 396
	int counter;

397 398 399
	if (!display_weighted)
		return weight;

400 401 402 403 404 405 406 407
	for (counter = 1; counter < nr_counters-1; counter++)
		weight *= sym->count[counter];

	weight /= (sym->count[counter] + 1);

	return weight;
}

408 409
static long			samples;
static long			userspace_samples;
410 411
static const char		CONSOLE_CLEAR[] = "";

412
static void __list_insert_active_sym(struct sym_entry *syme)
413 414 415 416
{
	list_add(&syme->node, &active_symbols);
}

417 418 419 420 421 422 423
static void list_remove_active_sym(struct sym_entry *syme)
{
	pthread_mutex_lock(&active_symbols_lock);
	list_del_init(&syme->node);
	pthread_mutex_unlock(&active_symbols_lock);
}

424 425 426 427 428 429 430 431 432 433
static void rb_insert_active_sym(struct rb_root *tree, struct sym_entry *se)
{
	struct rb_node **p = &tree->rb_node;
	struct rb_node *parent = NULL;
	struct sym_entry *iter;

	while (*p != NULL) {
		parent = *p;
		iter = rb_entry(parent, struct sym_entry, rb_node);

434
		if (se->weight > iter->weight)
435 436 437 438 439 440 441 442
			p = &(*p)->rb_left;
		else
			p = &(*p)->rb_right;
	}

	rb_link_node(&se->rb_node, parent, p);
	rb_insert_color(&se->rb_node, tree);
}
443 444 445

static void print_sym_table(void)
{
446
	int printed = 0, j;
447
	int counter, snap = !display_weighted ? sym_counter : 0;
448 449 450
	float samples_per_sec = samples/delay_secs;
	float ksamples_per_sec = (samples-userspace_samples)/delay_secs;
	float sum_ksamples = 0.0;
451 452 453
	struct sym_entry *syme, *n;
	struct rb_root tmp = RB_ROOT;
	struct rb_node *nd;
454
	int sym_width = 0, dso_width = 0, max_dso_width;
455
	const int win_width = winsize.ws_col - 1;
456

457
	samples = userspace_samples = 0;
458

459
	/* Sort the active symbols */
460 461 462 463 464
	pthread_mutex_lock(&active_symbols_lock);
	syme = list_entry(active_symbols.next, struct sym_entry, node);
	pthread_mutex_unlock(&active_symbols_lock);

	list_for_each_entry_safe_from(syme, n, &active_symbols, node) {
465
		syme->snap_count = syme->count[snap];
466
		if (syme->snap_count != 0) {
467

468 469 470 471 472 473 474
			if ((hide_user_symbols &&
			     syme->origin == PERF_RECORD_MISC_USER) ||
			    (hide_kernel_symbols &&
			     syme->origin == PERF_RECORD_MISC_KERNEL)) {
				list_remove_active_sym(syme);
				continue;
			}
475
			syme->weight = sym_weight(syme);
476
			rb_insert_active_sym(&tmp, syme);
477
			sum_ksamples += syme->snap_count;
478 479

			for (j = 0; j < nr_counters; j++)
480 481
				syme->count[j] = zero ? 0 : syme->count[j] * 7 / 8;
		} else
482
			list_remove_active_sym(syme);
483 484
	}

485
	puts(CONSOLE_CLEAR);
486

487
	printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
488
	printf( "   PerfTop:%8.0f irqs/sec  kernel:%4.1f%% [",
489 490
		samples_per_sec,
		100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec)));
491

492
	if (nr_counters == 1 || !display_weighted) {
493
		printf("%Ld", (u64)attrs[0].sample_period);
I
Ingo Molnar 已提交
494 495 496 497 498
		if (freq)
			printf("Hz ");
		else
			printf(" ");
	}
499

500 501 502
	if (!display_weighted)
		printf("%s", event_name(sym_counter));
	else for (counter = 0; counter < nr_counters; counter++) {
503 504 505 506 507 508 509 510
		if (counter)
			printf("/");

		printf("%s", event_name(counter));
	}

	printf( "], ");

511 512
	if (target_pid != -1)
		printf(" (target_pid: %d", target_pid);
513 514 515 516 517 518
	else
		printf(" (all");

	if (profile_cpu != -1)
		printf(", cpu: %d)\n", profile_cpu);
	else {
519
		if (target_pid != -1)
520 521 522 523 524
			printf(")\n");
		else
			printf(", %d CPUs)\n", nr_cpus);
	}

525
	printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
526

527 528 529 530 531
	if (sym_filter_entry) {
		show_details(sym_filter_entry);
		return;
	}

532 533 534 535 536 537 538 539 540
	/*
	 * Find the longest symbol name that will be displayed
	 */
	for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
		syme = rb_entry(nd, struct sym_entry, rb_node);
		if (++printed > print_entries ||
		    (int)syme->snap_count < count_filter)
			continue;

541 542 543
		if (syme->map->dso->long_name_len > dso_width)
			dso_width = syme->map->dso->long_name_len;

544 545 546 547 548 549
		if (syme->name_len > sym_width)
			sym_width = syme->name_len;
	}

	printed = 0;

550 551 552 553
	max_dso_width = winsize.ws_col - sym_width - 29;
	if (dso_width > max_dso_width)
		dso_width = max_dso_width;
	putchar('\n');
554
	if (nr_counters == 1)
555
		printf("             samples  pcnt");
556
	else
557
		printf("   weight    samples  pcnt");
558

559 560
	if (verbose)
		printf("         RIP       ");
561
	printf(" %-*.*s DSO\n", sym_width, sym_width, "function");
562
	printf("   %s    _______ _____",
563 564
	       nr_counters == 1 ? "      " : "______");
	if (verbose)
565
		printf(" ________________");
566
	printf(" %-*.*s", sym_width, sym_width, graph_line);
567
	printf(" %-*.*s", dso_width, dso_width, graph_line);
568
	puts("\n");
569

570
	for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
571
		struct symbol *sym;
572
		double pcnt;
573

574
		syme = rb_entry(nd, struct sym_entry, rb_node);
575
		sym = sym_entry__symbol(syme);
576

577
		if (++printed > print_entries || (int)syme->snap_count < count_filter)
578
			continue;
579

580 581
		pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) /
					 sum_ksamples));
582

583
		if (nr_counters == 1 || !display_weighted)
584
			printf("%20.2f ", syme->weight);
585
		else
586
			printf("%9.1f %10ld ", syme->weight, syme->snap_count);
587

588
		percent_color_fprintf(stdout, "%4.1f%%", pcnt);
589
		if (verbose)
590
			printf(" %016llx", sym->start);
591
		printf(" %-*.*s", sym_width, sym_width, sym->name);
592 593 594 595
		printf(" %-*.*s\n", dso_width, dso_width,
		       dso_width >= syme->map->dso->long_name_len ?
					syme->map->dso->long_name :
					syme->map->dso->short_name);
596 597 598
	}
}

599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
static void prompt_integer(int *target, const char *msg)
{
	char *buf = malloc(0), *p;
	size_t dummy = 0;
	int tmp;

	fprintf(stdout, "\n%s: ", msg);
	if (getline(&buf, &dummy, stdin) < 0)
		return;

	p = strchr(buf, '\n');
	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;
}

static void prompt_symbol(struct sym_entry **target, const char *msg)
{
	char *buf = malloc(0), *p;
	struct sym_entry *syme = *target, *n, *found = NULL;
	size_t dummy = 0;

	/* zero counters of active symbol */
	if (syme) {
642
		pthread_mutex_lock(&syme->src->lock);
643 644
		__zero_source_counters(syme);
		*target = NULL;
645
		pthread_mutex_unlock(&syme->src->lock);
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
	}

	fprintf(stdout, "\n%s: ", msg);
	if (getline(&buf, &dummy, stdin) < 0)
		goto out_free;

	p = strchr(buf, '\n');
	if (p)
		*p = 0;

	pthread_mutex_lock(&active_symbols_lock);
	syme = list_entry(active_symbols.next, struct sym_entry, node);
	pthread_mutex_unlock(&active_symbols_lock);

	list_for_each_entry_safe_from(syme, n, &active_symbols, node) {
661
		struct symbol *sym = sym_entry__symbol(syme);
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679

		if (!strcmp(buf, sym->name)) {
			found = syme;
			break;
		}
	}

	if (!found) {
		fprintf(stderr, "Sorry, %s is not active.\n", sym_filter);
		sleep(1);
		return;
	} else
		parse_source(found);

out_free:
	free(buf);
}

680
static void print_mapped_keys(void)
681
{
682 683 684
	char *name = NULL;

	if (sym_filter_entry) {
685
		struct symbol *sym = sym_entry__symbol(sym_filter_entry);
686 687 688 689 690 691 692 693 694 695 696 697
		name = sym->name;
	}

	fprintf(stdout, "\nMapped keys:\n");
	fprintf(stdout, "\t[d]     display refresh delay.             \t(%d)\n", delay_secs);
	fprintf(stdout, "\t[e]     display entries (lines).           \t(%d)\n", print_entries);

	if (nr_counters > 1)
		fprintf(stdout, "\t[E]     active event counter.              \t(%s)\n", event_name(sym_counter));

	fprintf(stdout, "\t[f]     profile display filter (count).    \t(%d)\n", count_filter);

698
	if (symbol_conf.vmlinux_name) {
699 700 701 702 703 704 705 706
		fprintf(stdout, "\t[F]     annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter);
		fprintf(stdout, "\t[s]     annotate symbol.                   \t(%s)\n", name?: "NULL");
		fprintf(stdout, "\t[S]     stop annotation.\n");
	}

	if (nr_counters > 1)
		fprintf(stdout, "\t[w]     toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0);

707 708 709 710 711 712
	fprintf(stdout,
		"\t[K]     hide kernel_symbols symbols.             \t(%s)\n",
		hide_kernel_symbols ? "yes" : "no");
	fprintf(stdout,
		"\t[U]     hide user symbols.               \t(%s)\n",
		hide_user_symbols ? "yes" : "no");
713
	fprintf(stdout, "\t[z]     toggle sample zeroing.             \t(%d)\n", zero ? 1 : 0);
714 715 716 717 718 719 720 721 722 723 724 725
	fprintf(stdout, "\t[qQ]    quit.\n");
}

static int key_mapped(int c)
{
	switch (c) {
		case 'd':
		case 'e':
		case 'f':
		case 'z':
		case 'q':
		case 'Q':
726 727
		case 'K':
		case 'U':
728 729 730 731 732 733 734
			return 1;
		case 'E':
		case 'w':
			return nr_counters > 1 ? 1 : 0;
		case 'F':
		case 's':
		case 'S':
735
			return symbol_conf.vmlinux_name ? 1 : 0;
736 737
		default:
			break;
738 739 740
	}

	return 0;
741 742 743 744
}

static void handle_keypress(int c)
{
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
	if (!key_mapped(c)) {
		struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
		struct termios tc, save;

		print_mapped_keys();
		fprintf(stdout, "\nEnter 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;
	}

768 769 770
	switch (c) {
		case 'd':
			prompt_integer(&delay_secs, "Enter display delay");
771 772
			if (delay_secs < 1)
				delay_secs = 1;
773 774 775
			break;
		case 'e':
			prompt_integer(&print_entries, "Enter display entries (lines)");
776
			if (print_entries == 0) {
777
				sig_winch_handler(SIGWINCH);
778 779 780
				signal(SIGWINCH, sig_winch_handler);
			} else
				signal(SIGWINCH, SIG_DFL);
781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
			break;
		case 'E':
			if (nr_counters > 1) {
				int i;

				fprintf(stderr, "\nAvailable events:");
				for (i = 0; i < nr_counters; i++)
					fprintf(stderr, "\n\t%d %s", i, event_name(i));

				prompt_integer(&sym_counter, "Enter details event counter");

				if (sym_counter >= nr_counters) {
					fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(0));
					sym_counter = 0;
					sleep(1);
				}
			} else sym_counter = 0;
			break;
		case 'f':
			prompt_integer(&count_filter, "Enter display event count filter");
			break;
		case 'F':
			prompt_percent(&sym_pcnt_filter, "Enter details display event filter (percent)");
			break;
805 806 807
		case 'K':
			hide_kernel_symbols = !hide_kernel_symbols;
			break;
808 809 810
		case 'q':
		case 'Q':
			printf("exiting.\n");
811 812
			if (dump_symtab)
				dsos__fprintf(stderr);
813 814 815 816 817 818 819 820 821 822
			exit(0);
		case 's':
			prompt_symbol(&sym_filter_entry, "Enter details symbol");
			break;
		case 'S':
			if (!sym_filter_entry)
				break;
			else {
				struct sym_entry *syme = sym_filter_entry;

823
				pthread_mutex_lock(&syme->src->lock);
824 825
				sym_filter_entry = NULL;
				__zero_source_counters(syme);
826
				pthread_mutex_unlock(&syme->src->lock);
827 828
			}
			break;
829 830 831
		case 'U':
			hide_user_symbols = !hide_user_symbols;
			break;
832 833 834
		case 'w':
			display_weighted = ~display_weighted;
			break;
835 836 837
		case 'z':
			zero = ~zero;
			break;
838 839
		default:
			break;
840 841 842
	}
}

843
static void *display_thread(void *arg __used)
844
{
845
	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
846 847 848 849 850 851 852 853
	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;
854

855 856 857 858 859
repeat:
	delay_msecs = delay_secs * 1000;
	tcsetattr(0, TCSANOW, &tc);
	/* trash return*/
	getc(stdin);
860

861
	do {
862
		print_sym_table();
863 864
	} while (!poll(&stdin_poll, 1, delay_msecs) == 1);

865 866 867 868 869
	c = getc(stdin);
	tcsetattr(0, TCSAFLUSH, &save);

	handle_keypress(c);
	goto repeat;
870 871 872 873

	return NULL;
}

874
/* Tag samples to be skipped. */
875
static const char *skip_symbols[] = {
876 877 878 879 880
	"default_idle",
	"cpu_idle",
	"enter_idle",
	"exit_idle",
	"mwait_idle",
881
	"mwait_idle_with_hints",
882
	"poll_idle",
883 884
	"ppc64_runlatch_off",
	"pseries_dedicated_idle_sleep",
885 886 887
	NULL
};

888
static int symbol_filter(struct map *map, struct symbol *sym)
889
{
890 891
	struct sym_entry *syme;
	const char *name = sym->name;
892
	int i;
893

894 895 896 897 898 899 900
	/*
	 * ppc64 uses function descriptors and appends a '.' to the
	 * start of every instruction address. Remove it.
	 */
	if (name[0] == '.')
		name++;

901 902 903 904 905 906 907
	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"))
908 909
		return 1;

910
	syme = symbol__priv(sym);
911
	syme->map = map;
912
	syme->src = NULL;
913 914 915
	if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter))
		sym_filter_entry = syme;

916 917 918 919 920 921
	for (i = 0; skip_symbols[i]; i++) {
		if (!strcmp(skip_symbols[i], name)) {
			syme->skip = 1;
			break;
		}
	}
922

923 924 925
	if (!syme->skip)
		syme->name_len = strlen(sym->name);

926 927 928
	return 0;
}

929 930
static void event__process_sample(const event_t *self,
				 struct perf_session *session, int counter)
931
{
932 933
	u64 ip = self->ip.ip;
	struct sym_entry *syme;
934
	struct addr_location al;
935
	u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
936

937
	switch (origin) {
938
	case PERF_RECORD_MISC_USER:
939 940
		if (hide_user_symbols)
			return;
941
		break;
942
	case PERF_RECORD_MISC_KERNEL:
943 944
		if (hide_kernel_symbols)
			return;
945 946 947 948 949
		break;
	default:
		return;
	}

950
	if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 ||
951
	    al.sym == NULL || al.filtered)
952
		return;
953

954
	syme = symbol__priv(al.sym);
955 956
	if (!syme->skip) {
		syme->count[counter]++;
957
		syme->origin = origin;
958 959 960 961 962
		record_precise_ip(syme, counter, ip);
		pthread_mutex_lock(&active_symbols_lock);
		if (list_empty(&syme->node) || !syme->node.next)
			__list_insert_active_sym(syme);
		pthread_mutex_unlock(&active_symbols_lock);
963 964
		if (origin == PERF_RECORD_MISC_USER)
			++userspace_samples;
965 966
		++samples;
	}
967 968
}

969
static int event__process(event_t *event, struct perf_session *session)
970 971 972
{
	switch (event->header.type) {
	case PERF_RECORD_COMM:
973
		event__process_comm(event, session);
974 975
		break;
	case PERF_RECORD_MMAP:
976
		event__process_mmap(event, session);
977 978 979
		break;
	default:
		break;
980 981
	}

982
	return 0;
983 984 985
}

struct mmap_data {
986 987
	int			counter;
	void			*base;
988
	int			mask;
989
	unsigned int		prev;
990 991 992 993
};

static unsigned int mmap_read_head(struct mmap_data *md)
{
994
	struct perf_event_mmap_page *pc = md->base;
995 996 997 998 999 1000 1001 1002
	int head;

	head = pc->data_head;
	rmb();

	return head;
}

1003 1004
static void perf_session__mmap_read_counter(struct perf_session *self,
					    struct mmap_data *md)
1005 1006 1007 1008 1009 1010 1011 1012
{
	unsigned int head = mmap_read_head(md);
	unsigned int old = md->prev;
	unsigned char *data = md->base + page_size;
	int diff;

	/*
	 * If we're further behind than half the buffer, there's a chance
1013
	 * the writer will bite our tail and mess up the samples under us.
1014 1015 1016 1017 1018 1019 1020
	 *
	 * If we somehow ended up ahead of the head, we got messed up.
	 *
	 * In either case, truncate and restart at head.
	 */
	diff = head - old;
	if (diff > md->mask / 2 || diff < 0) {
1021
		fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033

		/*
		 * head points to a known good entry, start there.
		 */
		old = head;
	}

	for (; old != head;) {
		event_t *event = (event_t *)&data[old & md->mask];

		event_t event_copy;

1034
		size_t size = event->header.size;
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055

		/*
		 * Event straddles the mmap boundary -- header should always
		 * be inside due to u64 alignment of output.
		 */
		if ((old & md->mask) + size != ((old + size) & md->mask)) {
			unsigned int offset = old;
			unsigned int len = min(sizeof(*event), size), cpy;
			void *dst = &event_copy;

			do {
				cpy = min(md->mask + 1 - (offset & md->mask), len);
				memcpy(dst, &data[offset & md->mask], cpy);
				offset += cpy;
				dst += cpy;
				len -= cpy;
			} while (len);

			event = &event_copy;
		}

1056
		if (event->header.type == PERF_RECORD_SAMPLE)
1057
			event__process_sample(event, self, md->counter);
1058
		else
1059
			event__process(event, self);
1060 1061 1062 1063 1064 1065
		old += size;
	}

	md->prev = old;
}

M
Mike Galbraith 已提交
1066 1067 1068
static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS];
static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS];

1069
static void perf_session__mmap_read(struct perf_session *self)
1070 1071 1072 1073 1074
{
	int i, counter;

	for (i = 0; i < nr_cpus; i++) {
		for (counter = 0; counter < nr_counters; counter++)
1075
			perf_session__mmap_read_counter(self, &mmap_array[i][counter]);
1076 1077 1078
	}
}

1079 1080 1081 1082
int nr_poll;
int group_fd;

static void start_counter(int i, int counter)
1083
{
1084
	struct perf_event_attr *attr;
1085
	int cpu;
1086 1087 1088 1089 1090 1091 1092 1093

	cpu = profile_cpu;
	if (target_pid == -1 && profile_cpu == -1)
		cpu = i;

	attr = attrs + counter;

	attr->sample_type	= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
1094 1095 1096 1097 1098 1099 1100

	if (freq) {
		attr->sample_type	|= PERF_SAMPLE_PERIOD;
		attr->freq		= 1;
		attr->sample_freq	= freq;
	}

1101
	attr->inherit		= (cpu < 0) && inherit;
1102
	attr->mmap		= 1;
1103 1104

try_again:
1105
	fd[i][counter] = sys_perf_event_open(attr, target_pid, cpu, group_fd, 0);
1106 1107 1108 1109

	if (fd[i][counter] < 0) {
		int err = errno;

P
Pekka Enberg 已提交
1110
		if (err == EPERM || err == EACCES)
1111
			die("No permission - are you root?\n");
1112 1113 1114 1115 1116 1117
		/*
		 * If it's cycles then fall back to hrtimer
		 * based cpu-clock-tick sw counter, which
		 * is always available even if no PMU support:
		 */
		if (attr->type == PERF_TYPE_HARDWARE
1118
			&& attr->config == PERF_COUNT_HW_CPU_CYCLES) {
1119

1120 1121 1122
			if (verbose)
				warning(" ... trying to fall back to cpu-clock-ticks\n");

1123
			attr->type = PERF_TYPE_SOFTWARE;
1124
			attr->config = PERF_COUNT_SW_CPU_CLOCK;
1125 1126
			goto try_again;
		}
1127 1128 1129
		printf("\n");
		error("perfcounter syscall returned with %d (%s)\n",
			fd[i][counter], strerror(err));
1130
		die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158
		exit(-1);
	}
	assert(fd[i][counter] >= 0);
	fcntl(fd[i][counter], F_SETFL, O_NONBLOCK);

	/*
	 * First counter acts as the group leader:
	 */
	if (group && group_fd == -1)
		group_fd = fd[i][counter];

	event_array[nr_poll].fd = fd[i][counter];
	event_array[nr_poll].events = POLLIN;
	nr_poll++;

	mmap_array[i][counter].counter = counter;
	mmap_array[i][counter].prev = 0;
	mmap_array[i][counter].mask = mmap_pages*page_size - 1;
	mmap_array[i][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
			PROT_READ, MAP_SHARED, fd[i][counter], 0);
	if (mmap_array[i][counter].base == MAP_FAILED)
		die("failed to mmap with %d (%s)\n", errno, strerror(errno));
}

static int __cmd_top(void)
{
	pthread_t thread;
	int i, counter;
1159
	int ret;
1160
	/*
1161 1162
	 * 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.
1163
	 */
1164
	struct perf_session *session = perf_session__new(NULL, O_WRONLY, false);
1165 1166
	if (session == NULL)
		return -ENOMEM;
1167

1168
	if (target_pid != -1)
1169
		event__synthesize_thread(target_pid, event__process, session);
1170
	else
1171
		event__synthesize_threads(event__process, session);
1172

1173 1174
	for (i = 0; i < nr_cpus; i++) {
		group_fd = -1;
1175 1176
		for (counter = 0; counter < nr_counters; counter++)
			start_counter(i, counter);
1177 1178
	}

1179 1180 1181
	/* Wait for a minimal set of events before starting the snapshot */
	poll(event_array, nr_poll, 100);

1182
	perf_session__mmap_read(session);
1183

1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
	if (pthread_create(&thread, NULL, display_thread, NULL)) {
		printf("Could not create display thread.\n");
		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.\n");
			exit(-1);
		}
	}

	while (1) {
1200
		int hits = samples;
1201

1202
		perf_session__mmap_read(session);
1203

1204
		if (hits == samples)
1205 1206 1207 1208 1209
			ret = poll(event_array, nr_poll, 100);
	}

	return 0;
}
1210 1211 1212 1213 1214 1215 1216 1217

static const char * const top_usage[] = {
	"perf top [<options>]",
	NULL
};

static const struct option options[] = {
	OPT_CALLBACK('e', "event", NULL, "event",
1218 1219
		     "event selector. use 'perf list' to list available events",
		     parse_events),
1220 1221 1222 1223 1224 1225 1226 1227
	OPT_INTEGER('c', "count", &default_interval,
		    "event period to sample"),
	OPT_INTEGER('p', "pid", &target_pid,
		    "profile events on existing pid"),
	OPT_BOOLEAN('a', "all-cpus", &system_wide,
			    "system-wide collection from all CPUs"),
	OPT_INTEGER('C', "CPU", &profile_cpu,
		    "CPU to profile on"),
1228 1229
	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
		   "file", "vmlinux pathname"),
1230 1231
	OPT_BOOLEAN('K', "hide_kernel_symbols", &hide_kernel_symbols,
		    "hide kernel symbols"),
1232 1233 1234 1235
	OPT_INTEGER('m', "mmap-pages", &mmap_pages,
		    "number of mmap data pages"),
	OPT_INTEGER('r', "realtime", &realtime_prio,
		    "collect data with this RT SCHED_FIFO priority"),
M
Mike Galbraith 已提交
1236
	OPT_INTEGER('d', "delay", &delay_secs,
1237 1238 1239
		    "number of seconds to delay between refreshes"),
	OPT_BOOLEAN('D', "dump-symtab", &dump_symtab,
			    "dump the symbol table used for profiling"),
1240
	OPT_INTEGER('f', "count-filter", &count_filter,
1241 1242 1243
		    "only display functions with more events than this"),
	OPT_BOOLEAN('g', "group", &group,
			    "put the counters into a counter group"),
1244 1245
	OPT_BOOLEAN('i', "inherit", &inherit,
		    "child tasks inherit counters"),
1246 1247
	OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name",
		    "symbol to annotate - requires -k option"),
A
Anton Blanchard 已提交
1248
	OPT_BOOLEAN('z', "zero", &zero,
1249
		    "zero history across updates"),
1250
	OPT_INTEGER('F', "freq", &freq,
1251
		    "profile at this frequency"),
1252 1253
	OPT_INTEGER('E', "entries", &print_entries,
		    "display this many functions"),
1254 1255
	OPT_BOOLEAN('U', "hide_user_symbols", &hide_user_symbols,
		    "hide user symbols"),
1256 1257
	OPT_BOOLEAN('v', "verbose", &verbose,
		    "be more verbose (show counter open errors, etc)"),
1258 1259 1260
	OPT_END()
};

1261
int cmd_top(int argc, const char **argv, const char *prefix __used)
1262
{
1263
	int counter;
1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277

	page_size = sysconf(_SC_PAGE_SIZE);

	argc = parse_options(argc, argv, options, top_usage, 0);
	if (argc)
		usage_with_options(top_usage, options);

	/* CPU and PID are mutually exclusive */
	if (target_pid != -1 && profile_cpu != -1) {
		printf("WARNING: PID switch overriding CPU\n");
		sleep(1);
		profile_cpu = -1;
	}

1278
	if (!nr_counters)
1279 1280
		nr_counters = 1;

1281 1282 1283 1284
	symbol_conf.priv_size = (sizeof(struct sym_entry) +
				 (nr_counters + 1) * sizeof(unsigned long));
	if (symbol_conf.vmlinux_name == NULL)
		symbol_conf.try_vmlinux_path = true;
1285
	if (symbol__init() < 0)
1286
		return -1;
1287

1288 1289 1290
	if (delay_secs < 1)
		delay_secs = 1;

1291
	parse_source(sym_filter_entry);
1292

1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304
	/*
	 * User specified count overrides default frequency.
	 */
	if (default_interval)
		freq = 0;
	else if (freq) {
		default_interval = freq;
	} else {
		fprintf(stderr, "frequency and count are zero, aborting\n");
		exit(EXIT_FAILURE);
	}

1305 1306 1307
	/*
	 * Fill in the ones not specifically initialized via -c:
	 */
1308
	for (counter = 0; counter < nr_counters; counter++) {
1309
		if (attrs[counter].sample_period)
1310 1311
			continue;

1312
		attrs[counter].sample_period = default_interval;
1313 1314 1315 1316 1317 1318 1319 1320 1321
	}

	nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
	assert(nr_cpus <= MAX_NR_CPUS);
	assert(nr_cpus >= 0);

	if (target_pid != -1 || profile_cpu != -1)
		nr_cpus = 1;

1322
	get_term_dimensions(&winsize);
1323
	if (print_entries == 0) {
1324
		update_print_entries(&winsize);
1325 1326 1327
		signal(SIGWINCH, sig_winch_handler);
	}

1328 1329
	return __cmd_top();
}