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
struct symbol_conf		symbol_conf;
84

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

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

96 97 98 99 100
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;
101

102 103 104 105
/*
 * Symbols
 */

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

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

126 127 128 129
/*
 * Source functions
 */

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

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

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

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

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

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

	if (!syme)
		return;

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

	source = syme->src;

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

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

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

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

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

214 215
	pthread_mutex_lock(&source->lock);
	source->lines_tail = &source->lines;
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
	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;
235 236
		*source->lines_tail = src;
		source->lines_tail = &src->next;
237 238 239

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

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

258
	line = syme->src->lines;
259 260 261 262 263 264 265 266 267 268 269 270 271 272
	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;

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

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

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

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

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

299 300
	pthread_mutex_lock(&syme->src->lock);
	for (line = syme->src->lines; line; line = line->next) {
301
		if (strstr(line->line, pattern)) {
302
			syme->src->source = line;
303 304 305
			break;
		}
	}
306
	pthread_mutex_unlock(&syme->src->lock);
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
}

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;

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

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

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

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

353
	line = syme->src->source;
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
	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;
	}
378
	pthread_mutex_unlock(&syme->src->lock);
379 380 381
	if (more)
		printf("%d lines not displayed, maybe increase display entries [e]\n", more);
}
382

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

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

398 399 400
	if (!display_weighted)
		return weight;

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

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

	return weight;
}

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

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

418 419 420 421 422 423 424
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);
}

425 426 427 428 429 430 431 432 433 434
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);

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

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

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

458
	samples = userspace_samples = 0;
459

460
	/* Sort the active symbols */
461 462 463 464 465
	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) {
466
		syme->snap_count = syme->count[snap];
467
		if (syme->snap_count != 0) {
468

469 470 471 472 473 474 475
			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;
			}
476
			syme->weight = sym_weight(syme);
477
			rb_insert_active_sym(&tmp, syme);
478
			sum_ksamples += syme->snap_count;
479 480

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

486
	puts(CONSOLE_CLEAR);
487

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

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

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

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

	printf( "], ");

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

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

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

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

533 534 535 536 537 538 539 540 541
	/*
	 * 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;

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

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

	printed = 0;

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

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

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

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

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

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

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

589
		percent_color_fprintf(stdout, "%4.1f%%", pcnt);
590
		if (verbose)
591
			printf(" %016llx", sym->start);
592
		printf(" %-*.*s", sym_width, sym_width, sym->name);
593 594 595 596
		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);
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 642
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) {
643
		pthread_mutex_lock(&syme->src->lock);
644 645
		__zero_source_counters(syme);
		*target = NULL;
646
		pthread_mutex_unlock(&syme->src->lock);
647 648 649 650 651 652 653 654 655 656 657 658 659 660 661
	}

	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) {
662
		struct symbol *sym = sym_entry__symbol(syme);
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680

		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);
}

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

	if (sym_filter_entry) {
686
		struct symbol *sym = sym_entry__symbol(sym_filter_entry);
687 688 689 690 691 692 693 694 695 696 697 698
		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);

699
	if (symbol_conf.vmlinux_name) {
700 701 702 703 704 705 706 707
		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);

708 709 710 711 712 713
	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");
714
	fprintf(stdout, "\t[z]     toggle sample zeroing.             \t(%d)\n", zero ? 1 : 0);
715 716 717 718 719 720 721 722 723 724 725 726
	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':
727 728
		case 'K':
		case 'U':
729 730 731 732 733 734 735
			return 1;
		case 'E':
		case 'w':
			return nr_counters > 1 ? 1 : 0;
		case 'F':
		case 's':
		case 'S':
736
			return symbol_conf.vmlinux_name ? 1 : 0;
737 738
		default:
			break;
739 740 741
	}

	return 0;
742 743 744 745
}

static void handle_keypress(int c)
{
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
	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;
	}

769 770 771
	switch (c) {
		case 'd':
			prompt_integer(&delay_secs, "Enter display delay");
772 773
			if (delay_secs < 1)
				delay_secs = 1;
774 775 776
			break;
		case 'e':
			prompt_integer(&print_entries, "Enter display entries (lines)");
777
			if (print_entries == 0) {
778
				sig_winch_handler(SIGWINCH);
779 780 781
				signal(SIGWINCH, sig_winch_handler);
			} else
				signal(SIGWINCH, SIG_DFL);
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
			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;
806 807 808
		case 'K':
			hide_kernel_symbols = !hide_kernel_symbols;
			break;
809 810 811
		case 'q':
		case 'Q':
			printf("exiting.\n");
812 813
			if (dump_symtab)
				dsos__fprintf(stderr);
814 815 816 817 818 819 820 821 822 823
			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;

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

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

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

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

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

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

	return NULL;
}

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

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

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

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

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

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

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

927 928 929
	return 0;
}

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

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

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

955
	syme = symbol__priv(al.sym);
956 957
	if (!syme->skip) {
		syme->count[counter]++;
958
		syme->origin = origin;
959 960 961 962 963
		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);
964 965
		if (origin == PERF_RECORD_MISC_USER)
			++userspace_samples;
966 967
		++samples;
	}
968 969
}

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

983
	return 0;
984 985 986
}

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

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

	head = pc->data_head;
	rmb();

	return head;
}

1004 1005
static void perf_session__mmap_read_counter(struct perf_session *self,
					    struct mmap_data *md)
1006 1007 1008 1009 1010 1011 1012 1013
{
	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
1014
	 * the writer will bite our tail and mess up the samples under us.
1015 1016 1017 1018 1019 1020 1021
	 *
	 * 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) {
1022
		fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034

		/*
		 * 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;

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

		/*
		 * 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;
		}

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

	md->prev = old;
}

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

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

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

1080 1081 1082 1083
int nr_poll;
int group_fd;

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

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

	attr = attrs + counter;

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

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

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

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

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

P
Pekka Enberg 已提交
1111
		if (err == EPERM || err == EACCES)
1112
			die("No permission - are you root?\n");
1113 1114 1115 1116 1117 1118
		/*
		 * 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
1119
			&& attr->config == PERF_COUNT_HW_CPU_CYCLES) {
1120

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

1124
			attr->type = PERF_TYPE_SOFTWARE;
1125
			attr->config = PERF_COUNT_SW_CPU_CLOCK;
1126 1127
			goto try_again;
		}
1128 1129 1130
		printf("\n");
		error("perfcounter syscall returned with %d (%s)\n",
			fd[i][counter], strerror(err));
1131
		die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
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 1159
		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;
1160
	int ret;
1161
	/*
1162 1163
	 * 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.
1164
	 */
1165 1166 1167 1168
	struct perf_session *session = perf_session__new(NULL, O_WRONLY, false);

	if (session == NULL)
		return -ENOMEM;
1169

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

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

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

1184
	perf_session__mmap_read(session);
1185

1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201
	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) {
1202
		int hits = samples;
1203

1204
		perf_session__mmap_read(session);
1205

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

	return 0;
}
1212 1213 1214 1215 1216 1217 1218 1219

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

static const struct option options[] = {
	OPT_CALLBACK('e', "event", NULL, "event",
1220 1221
		     "event selector. use 'perf list' to list available events",
		     parse_events),
1222 1223 1224 1225 1226 1227 1228 1229
	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"),
1230 1231
	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
		   "file", "vmlinux pathname"),
1232 1233
	OPT_BOOLEAN('K', "hide_kernel_symbols", &hide_kernel_symbols,
		    "hide kernel symbols"),
1234 1235 1236 1237
	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 已提交
1238
	OPT_INTEGER('d', "delay", &delay_secs,
1239 1240 1241
		    "number of seconds to delay between refreshes"),
	OPT_BOOLEAN('D', "dump-symtab", &dump_symtab,
			    "dump the symbol table used for profiling"),
1242
	OPT_INTEGER('f', "count-filter", &count_filter,
1243 1244 1245
		    "only display functions with more events than this"),
	OPT_BOOLEAN('g', "group", &group,
			    "put the counters into a counter group"),
1246 1247
	OPT_BOOLEAN('i', "inherit", &inherit,
		    "child tasks inherit counters"),
1248 1249
	OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name",
		    "symbol to annotate - requires -k option"),
A
Anton Blanchard 已提交
1250
	OPT_BOOLEAN('z', "zero", &zero,
1251
		    "zero history across updates"),
1252
	OPT_INTEGER('F', "freq", &freq,
1253
		    "profile at this frequency"),
1254 1255
	OPT_INTEGER('E', "entries", &print_entries,
		    "display this many functions"),
1256 1257
	OPT_BOOLEAN('U', "hide_user_symbols", &hide_user_symbols,
		    "hide user symbols"),
1258 1259
	OPT_BOOLEAN('v', "verbose", &verbose,
		    "be more verbose (show counter open errors, etc)"),
1260 1261 1262
	OPT_END()
};

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

	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;
	}

1280
	if (!nr_counters)
1281 1282
		nr_counters = 1;

1283 1284 1285 1286 1287 1288
	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;
	if (symbol__init(&symbol_conf) < 0)
		return -1;
1289

1290 1291 1292
	if (delay_secs < 1)
		delay_secs = 1;

1293
	parse_source(sym_filter_entry);
1294

1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306
	/*
	 * 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);
	}

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

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

	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;

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

1330 1331
	return __cmd_top();
}