aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-top.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r--tools/perf/builtin-top.c75
1 files changed, 61 insertions, 14 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 40f24dd46ef..dfd7ea7dabd 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -420,8 +420,9 @@ static double sym_weight(const struct sym_entry *sym)
420} 420}
421 421
422static long samples; 422static long samples;
423static long userspace_samples; 423static long kernel_samples, us_samples;
424static long exact_samples; 424static long exact_samples;
425static long guest_us_samples, guest_kernel_samples;
425static const char CONSOLE_CLEAR[] = ""; 426static const char CONSOLE_CLEAR[] = "";
426 427
427static void __list_insert_active_sym(struct sym_entry *syme) 428static void __list_insert_active_sym(struct sym_entry *syme)
@@ -461,7 +462,10 @@ static void print_sym_table(void)
461 int printed = 0, j; 462 int printed = 0, j;
462 int counter, snap = !display_weighted ? sym_counter : 0; 463 int counter, snap = !display_weighted ? sym_counter : 0;
463 float samples_per_sec = samples/delay_secs; 464 float samples_per_sec = samples/delay_secs;
464 float ksamples_per_sec = (samples-userspace_samples)/delay_secs; 465 float ksamples_per_sec = kernel_samples/delay_secs;
466 float us_samples_per_sec = (us_samples)/delay_secs;
467 float guest_kernel_samples_per_sec = (guest_kernel_samples)/delay_secs;
468 float guest_us_samples_per_sec = (guest_us_samples)/delay_secs;
465 float esamples_percent = (100.0*exact_samples)/samples; 469 float esamples_percent = (100.0*exact_samples)/samples;
466 float sum_ksamples = 0.0; 470 float sum_ksamples = 0.0;
467 struct sym_entry *syme, *n; 471 struct sym_entry *syme, *n;
@@ -470,7 +474,8 @@ static void print_sym_table(void)
470 int sym_width = 0, dso_width = 0, dso_short_width = 0; 474 int sym_width = 0, dso_width = 0, dso_short_width = 0;
471 const int win_width = winsize.ws_col - 1; 475 const int win_width = winsize.ws_col - 1;
472 476
473 samples = userspace_samples = exact_samples = 0; 477 samples = us_samples = kernel_samples = exact_samples = 0;
478 guest_kernel_samples = guest_us_samples = 0;
474 479
475 /* Sort the active symbols */ 480 /* Sort the active symbols */
476 pthread_mutex_lock(&active_symbols_lock); 481 pthread_mutex_lock(&active_symbols_lock);
@@ -501,10 +506,30 @@ static void print_sym_table(void)
501 puts(CONSOLE_CLEAR); 506 puts(CONSOLE_CLEAR);
502 507
503 printf("%-*.*s\n", win_width, win_width, graph_dotted_line); 508 printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
504 printf( " PerfTop:%8.0f irqs/sec kernel:%4.1f%% exact: %4.1f%% [", 509 if (!perf_guest) {
505 samples_per_sec, 510 printf(" PerfTop:%8.0f irqs/sec kernel:%4.1f%%"
506 100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec)), 511 " exact: %4.1f%% [",
507 esamples_percent); 512 samples_per_sec,
513 100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) /
514 samples_per_sec)),
515 esamples_percent);
516 } else {
517 printf(" PerfTop:%8.0f irqs/sec kernel:%4.1f%% us:%4.1f%%"
518 " guest kernel:%4.1f%% guest us:%4.1f%%"
519 " exact: %4.1f%% [",
520 samples_per_sec,
521 100.0 - (100.0 * ((samples_per_sec-ksamples_per_sec) /
522 samples_per_sec)),
523 100.0 - (100.0 * ((samples_per_sec-us_samples_per_sec) /
524 samples_per_sec)),
525 100.0 - (100.0 * ((samples_per_sec -
526 guest_kernel_samples_per_sec) /
527 samples_per_sec)),
528 100.0 - (100.0 * ((samples_per_sec -
529 guest_us_samples_per_sec) /
530 samples_per_sec)),
531 esamples_percent);
532 }
508 533
509 if (nr_counters == 1 || !display_weighted) { 534 if (nr_counters == 1 || !display_weighted) {
510 printf("%Ld", (u64)attrs[0].sample_period); 535 printf("%Ld", (u64)attrs[0].sample_period);
@@ -597,7 +622,6 @@ static void print_sym_table(void)
597 622
598 syme = rb_entry(nd, struct sym_entry, rb_node); 623 syme = rb_entry(nd, struct sym_entry, rb_node);
599 sym = sym_entry__symbol(syme); 624 sym = sym_entry__symbol(syme);
600
601 if (++printed > print_entries || (int)syme->snap_count < count_filter) 625 if (++printed > print_entries || (int)syme->snap_count < count_filter)
602 continue; 626 continue;
603 627
@@ -761,7 +785,7 @@ static int key_mapped(int c)
761 return 0; 785 return 0;
762} 786}
763 787
764static void handle_keypress(int c) 788static void handle_keypress(struct perf_session *session, int c)
765{ 789{
766 if (!key_mapped(c)) { 790 if (!key_mapped(c)) {
767 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 791 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
@@ -830,7 +854,7 @@ static void handle_keypress(int c)
830 case 'Q': 854 case 'Q':
831 printf("exiting.\n"); 855 printf("exiting.\n");
832 if (dump_symtab) 856 if (dump_symtab)
833 dsos__fprintf(stderr); 857 dsos__fprintf(&session->kerninfo_root, stderr);
834 exit(0); 858 exit(0);
835 case 's': 859 case 's':
836 prompt_symbol(&sym_filter_entry, "Enter details symbol"); 860 prompt_symbol(&sym_filter_entry, "Enter details symbol");
@@ -866,6 +890,7 @@ static void *display_thread(void *arg __used)
866 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 890 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
867 struct termios tc, save; 891 struct termios tc, save;
868 int delay_msecs, c; 892 int delay_msecs, c;
893 struct perf_session *session = (struct perf_session *) arg;
869 894
870 tcgetattr(0, &save); 895 tcgetattr(0, &save);
871 tc = save; 896 tc = save;
@@ -886,7 +911,7 @@ repeat:
886 c = getc(stdin); 911 c = getc(stdin);
887 tcsetattr(0, TCSAFLUSH, &save); 912 tcsetattr(0, TCSAFLUSH, &save);
888 913
889 handle_keypress(c); 914 handle_keypress(session, c);
890 goto repeat; 915 goto repeat;
891 916
892 return NULL; 917 return NULL;
@@ -957,24 +982,46 @@ static void event__process_sample(const event_t *self,
957 u64 ip = self->ip.ip; 982 u64 ip = self->ip.ip;
958 struct sym_entry *syme; 983 struct sym_entry *syme;
959 struct addr_location al; 984 struct addr_location al;
985 struct kernel_info *kerninfo;
960 u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 986 u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
961 987
962 ++samples; 988 ++samples;
963 989
964 switch (origin) { 990 switch (origin) {
965 case PERF_RECORD_MISC_USER: 991 case PERF_RECORD_MISC_USER:
966 ++userspace_samples; 992 ++us_samples;
967 if (hide_user_symbols) 993 if (hide_user_symbols)
968 return; 994 return;
995 kerninfo = kerninfo__findhost(&session->kerninfo_root);
969 break; 996 break;
970 case PERF_RECORD_MISC_KERNEL: 997 case PERF_RECORD_MISC_KERNEL:
998 ++kernel_samples;
971 if (hide_kernel_symbols) 999 if (hide_kernel_symbols)
972 return; 1000 return;
1001 kerninfo = kerninfo__findhost(&session->kerninfo_root);
973 break; 1002 break;
1003 case PERF_RECORD_MISC_GUEST_KERNEL:
1004 ++guest_kernel_samples;
1005 kerninfo = kerninfo__find(&session->kerninfo_root,
1006 self->ip.pid);
1007 break;
1008 case PERF_RECORD_MISC_GUEST_USER:
1009 ++guest_us_samples;
1010 /*
1011 * TODO: we don't process guest user from host side
1012 * except simple counting.
1013 */
1014 return;
974 default: 1015 default:
975 return; 1016 return;
976 } 1017 }
977 1018
1019 if (!kerninfo && perf_guest) {
1020 pr_err("Can't find guest [%d]'s kernel information\n",
1021 self->ip.pid);
1022 return;
1023 }
1024
978 if (self->header.misc & PERF_RECORD_MISC_EXACT) 1025 if (self->header.misc & PERF_RECORD_MISC_EXACT)
979 exact_samples++; 1026 exact_samples++;
980 1027
@@ -994,7 +1041,7 @@ static void event__process_sample(const event_t *self,
994 * --hide-kernel-symbols, even if the user specifies an 1041 * --hide-kernel-symbols, even if the user specifies an
995 * invalid --vmlinux ;-) 1042 * invalid --vmlinux ;-)
996 */ 1043 */
997 if (al.map == session->vmlinux_maps[MAP__FUNCTION] && 1044 if (al.map == kerninfo->vmlinux_maps[MAP__FUNCTION] &&
998 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { 1045 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
999 pr_err("The %s file can't be used\n", 1046 pr_err("The %s file can't be used\n",
1000 symbol_conf.vmlinux_name); 1047 symbol_conf.vmlinux_name);
@@ -1261,7 +1308,7 @@ static int __cmd_top(void)
1261 1308
1262 perf_session__mmap_read(session); 1309 perf_session__mmap_read(session);
1263 1310
1264 if (pthread_create(&thread, NULL, display_thread, NULL)) { 1311 if (pthread_create(&thread, NULL, display_thread, session)) {
1265 printf("Could not create display thread.\n"); 1312 printf("Could not create display thread.\n");
1266 exit(-1); 1313 exit(-1);
1267 } 1314 }