builtin-top.c 31.0 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
static char			*sym_filter			=   NULL;
struct sym_entry		*sym_filter_entry		=   NULL;
97
struct sym_entry		*sym_filter_entry_sched		=   NULL;
98 99 100
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__rip_2objdump(map, sym->start),
		map__rip_2objdump(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

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

	if (!found) {
671
		fprintf(stderr, "Sorry, %s is not active.\n", buf);
672 673 674 675 676 677 678 679 680
		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 700 701
	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");
702 703 704 705

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

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

	return 0;
739 740 741 742
}

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

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

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

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

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

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

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

	handle_keypress(c);
	goto repeat;
868 869 870 871

	return NULL;
}

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

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

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

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

908
	syme = symbol__priv(sym);
909
	syme->map = map;
910
	syme->src = NULL;
911 912 913 914 915 916

	if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) {
		/* schedule initial sym_filter_entry setup */
		sym_filter_entry_sched = syme;
		sym_filter = NULL;
	}
917

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

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

928 929 930
	return 0;
}

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

939 940
	++samples;

941
	switch (origin) {
942
	case PERF_RECORD_MISC_USER:
943
		++userspace_samples;
944 945
		if (hide_user_symbols)
			return;
946
		break;
947
	case PERF_RECORD_MISC_KERNEL:
948 949
		if (hide_kernel_symbols)
			return;
950 951 952 953 954
		break;
	default:
		return;
	}

955
	if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 ||
956
	    al.filtered)
957
		return;
958

959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
	if (al.sym == NULL) {
		/*
		 * 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 ;-)
		 */
		if (al.map == session->vmlinux_maps[MAP__FUNCTION] &&
		    RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
			pr_err("The %s file can't be used\n",
			       symbol_conf.vmlinux_name);
			exit(1);
		}

		return;
	}

981 982 983 984 985 986 987
	/* let's see, whether we need to install initial sym_filter_entry */
	if (sym_filter_entry_sched) {
		sym_filter_entry = sym_filter_entry_sched;
		sym_filter_entry_sched = NULL;
		parse_source(sym_filter_entry);
	}

988
	syme = symbol__priv(al.sym);
989 990
	if (!syme->skip) {
		syme->count[counter]++;
991
		syme->origin = origin;
992 993 994 995 996 997
		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);
	}
998 999
}

1000
static int event__process(event_t *event, struct perf_session *session)
1001 1002 1003
{
	switch (event->header.type) {
	case PERF_RECORD_COMM:
1004
		event__process_comm(event, session);
1005 1006
		break;
	case PERF_RECORD_MMAP:
1007
		event__process_mmap(event, session);
1008
		break;
1009 1010 1011 1012
	case PERF_RECORD_FORK:
	case PERF_RECORD_EXIT:
		event__process_task(event, session);
		break;
1013 1014
	default:
		break;
1015 1016
	}

1017
	return 0;
1018 1019 1020
}

struct mmap_data {
1021 1022
	int			counter;
	void			*base;
1023
	int			mask;
1024
	unsigned int		prev;
1025 1026 1027 1028
};

static unsigned int mmap_read_head(struct mmap_data *md)
{
1029
	struct perf_event_mmap_page *pc = md->base;
1030 1031 1032 1033 1034 1035 1036 1037
	int head;

	head = pc->data_head;
	rmb();

	return head;
}

1038 1039
static void perf_session__mmap_read_counter(struct perf_session *self,
					    struct mmap_data *md)
1040 1041 1042 1043 1044 1045 1046 1047
{
	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
1048
	 * the writer will bite our tail and mess up the samples under us.
1049 1050 1051 1052 1053 1054 1055
	 *
	 * 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) {
1056
		fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068

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

1069
		size_t size = event->header.size;
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090

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

1091
		if (event->header.type == PERF_RECORD_SAMPLE)
1092
			event__process_sample(event, self, md->counter);
1093
		else
1094
			event__process(event, self);
1095 1096 1097 1098 1099 1100
		old += size;
	}

	md->prev = old;
}

M
Mike Galbraith 已提交
1101 1102 1103
static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS];
static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS];

1104
static void perf_session__mmap_read(struct perf_session *self)
1105 1106 1107 1108 1109
{
	int i, counter;

	for (i = 0; i < nr_cpus; i++) {
		for (counter = 0; counter < nr_counters; counter++)
1110
			perf_session__mmap_read_counter(self, &mmap_array[i][counter]);
1111 1112 1113
	}
}

1114 1115 1116 1117
int nr_poll;
int group_fd;

static void start_counter(int i, int counter)
1118
{
1119
	struct perf_event_attr *attr;
1120
	int cpu;
1121 1122 1123 1124 1125 1126 1127 1128

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

	attr = attrs + counter;

	attr->sample_type	= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
1129 1130 1131 1132 1133 1134 1135

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

1136
	attr->inherit		= (cpu < 0) && inherit;
1137
	attr->mmap		= 1;
1138 1139

try_again:
1140
	fd[i][counter] = sys_perf_event_open(attr, target_pid, cpu, group_fd, 0);
1141 1142 1143 1144

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

P
Pekka Enberg 已提交
1145
		if (err == EPERM || err == EACCES)
1146
			die("No permission - are you root?\n");
1147 1148 1149 1150 1151 1152
		/*
		 * 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
1153
			&& attr->config == PERF_COUNT_HW_CPU_CYCLES) {
1154

1155 1156 1157
			if (verbose)
				warning(" ... trying to fall back to cpu-clock-ticks\n");

1158
			attr->type = PERF_TYPE_SOFTWARE;
1159
			attr->config = PERF_COUNT_SW_CPU_CLOCK;
1160 1161
			goto try_again;
		}
1162 1163 1164
		printf("\n");
		error("perfcounter syscall returned with %d (%s)\n",
			fd[i][counter], strerror(err));
1165
		die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
		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;
1194
	int ret;
1195
	/*
1196 1197
	 * 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.
1198
	 */
1199
	struct perf_session *session = perf_session__new(NULL, O_WRONLY, false);
1200 1201
	if (session == NULL)
		return -ENOMEM;
1202

1203
	if (target_pid != -1)
1204
		event__synthesize_thread(target_pid, event__process, session);
1205
	else
1206
		event__synthesize_threads(event__process, session);
1207

1208 1209
	for (i = 0; i < nr_cpus; i++) {
		group_fd = -1;
1210 1211
		for (counter = 0; counter < nr_counters; counter++)
			start_counter(i, counter);
1212 1213
	}

1214 1215 1216
	/* Wait for a minimal set of events before starting the snapshot */
	poll(event_array, nr_poll, 100);

1217
	perf_session__mmap_read(session);
1218

1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234
	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) {
1235
		int hits = samples;
1236

1237
		perf_session__mmap_read(session);
1238

1239
		if (hits == samples)
1240 1241 1242 1243 1244
			ret = poll(event_array, nr_poll, 100);
	}

	return 0;
}
1245 1246 1247 1248 1249 1250 1251 1252

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

static const struct option options[] = {
	OPT_CALLBACK('e', "event", NULL, "event",
1253 1254
		     "event selector. use 'perf list' to list available events",
		     parse_events),
1255 1256 1257 1258 1259 1260 1261 1262
	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"),
1263 1264
	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
		   "file", "vmlinux pathname"),
1265 1266
	OPT_BOOLEAN('K', "hide_kernel_symbols", &hide_kernel_symbols,
		    "hide kernel symbols"),
1267 1268 1269 1270
	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 已提交
1271
	OPT_INTEGER('d', "delay", &delay_secs,
1272 1273 1274
		    "number of seconds to delay between refreshes"),
	OPT_BOOLEAN('D', "dump-symtab", &dump_symtab,
			    "dump the symbol table used for profiling"),
1275
	OPT_INTEGER('f', "count-filter", &count_filter,
1276 1277 1278
		    "only display functions with more events than this"),
	OPT_BOOLEAN('g', "group", &group,
			    "put the counters into a counter group"),
1279 1280
	OPT_BOOLEAN('i', "inherit", &inherit,
		    "child tasks inherit counters"),
1281
	OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name",
1282
		    "symbol to annotate"),
A
Anton Blanchard 已提交
1283
	OPT_BOOLEAN('z', "zero", &zero,
1284
		    "zero history across updates"),
1285
	OPT_INTEGER('F', "freq", &freq,
1286
		    "profile at this frequency"),
1287 1288
	OPT_INTEGER('E', "entries", &print_entries,
		    "display this many functions"),
1289 1290
	OPT_BOOLEAN('U', "hide_user_symbols", &hide_user_symbols,
		    "hide user symbols"),
1291 1292
	OPT_BOOLEAN('v', "verbose", &verbose,
		    "be more verbose (show counter open errors, etc)"),
1293 1294 1295
	OPT_END()
};

1296
int cmd_top(int argc, const char **argv, const char *prefix __used)
1297
{
1298
	int counter;
1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312

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

1313
	if (!nr_counters)
1314 1315
		nr_counters = 1;

1316 1317
	symbol_conf.priv_size = (sizeof(struct sym_entry) +
				 (nr_counters + 1) * sizeof(unsigned long));
1318 1319

	symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
1320
	if (symbol__init() < 0)
1321
		return -1;
1322

1323 1324 1325
	if (delay_secs < 1)
		delay_secs = 1;

1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
	/*
	 * 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);
	}

1338 1339 1340
	/*
	 * Fill in the ones not specifically initialized via -c:
	 */
1341
	for (counter = 0; counter < nr_counters; counter++) {
1342
		if (attrs[counter].sample_period)
1343 1344
			continue;

1345
		attrs[counter].sample_period = default_interval;
1346 1347 1348 1349 1350 1351 1352 1353 1354
	}

	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;

1355
	get_term_dimensions(&winsize);
1356
	if (print_entries == 0) {
1357
		update_print_entries(&winsize);
1358 1359 1360
		signal(SIGWINCH, sig_winch_handler);
	}

1361 1362
	return __cmd_top();
}