aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-kvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-kvm.c')
-rw-r--r--tools/perf/builtin-kvm.c113
1 files changed, 49 insertions, 64 deletions
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 43367eb00510..b65eb0507b38 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -376,7 +376,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
376 struct perf_sample *sample) 376 struct perf_sample *sample)
377{ 377{
378 /* Only kvm_entry records vcpu id. */ 378 /* Only kvm_entry records vcpu id. */
379 if (!thread->priv && kvm_entry_event(evsel)) { 379 if (!thread__priv(thread) && kvm_entry_event(evsel)) {
380 struct vcpu_event_record *vcpu_record; 380 struct vcpu_event_record *vcpu_record;
381 381
382 vcpu_record = zalloc(sizeof(*vcpu_record)); 382 vcpu_record = zalloc(sizeof(*vcpu_record));
@@ -386,10 +386,10 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
386 } 386 }
387 387
388 vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, VCPU_ID); 388 vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, VCPU_ID);
389 thread->priv = vcpu_record; 389 thread__set_priv(thread, vcpu_record);
390 } 390 }
391 391
392 return thread->priv; 392 return thread__priv(thread);
393} 393}
394 394
395static bool handle_kvm_event(struct perf_kvm_stat *kvm, 395static bool handle_kvm_event(struct perf_kvm_stat *kvm,
@@ -543,14 +543,12 @@ static void print_vcpu_info(struct perf_kvm_stat *kvm)
543 543
544 pr_info("Analyze events for "); 544 pr_info("Analyze events for ");
545 545
546 if (kvm->live) { 546 if (kvm->opts.target.system_wide)
547 if (kvm->opts.target.system_wide) 547 pr_info("all VMs, ");
548 pr_info("all VMs, "); 548 else if (kvm->opts.target.pid)
549 else if (kvm->opts.target.pid) 549 pr_info("pid(s) %s, ", kvm->opts.target.pid);
550 pr_info("pid(s) %s, ", kvm->opts.target.pid); 550 else
551 else 551 pr_info("dazed and confused on what is monitored, ");
552 pr_info("dazed and confused on what is monitored, ");
553 }
554 552
555 if (vcpu == -1) 553 if (vcpu == -1)
556 pr_info("all VCPUs:\n\n"); 554 pr_info("all VCPUs:\n\n");
@@ -592,8 +590,8 @@ static void print_result(struct perf_kvm_stat *kvm)
592 pr_info("%9s ", "Samples%"); 590 pr_info("%9s ", "Samples%");
593 591
594 pr_info("%9s ", "Time%"); 592 pr_info("%9s ", "Time%");
595 pr_info("%10s ", "Min Time"); 593 pr_info("%11s ", "Min Time");
596 pr_info("%10s ", "Max Time"); 594 pr_info("%11s ", "Max Time");
597 pr_info("%16s ", "Avg time"); 595 pr_info("%16s ", "Avg time");
598 pr_info("\n\n"); 596 pr_info("\n\n");
599 597
@@ -610,8 +608,8 @@ static void print_result(struct perf_kvm_stat *kvm)
610 pr_info("%10llu ", (unsigned long long)ecount); 608 pr_info("%10llu ", (unsigned long long)ecount);
611 pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100); 609 pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100);
612 pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100); 610 pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100);
613 pr_info("%8" PRIu64 "us ", min / 1000); 611 pr_info("%9.2fus ", (double)min / 1e3);
614 pr_info("%8" PRIu64 "us ", max / 1000); 612 pr_info("%9.2fus ", (double)max / 1e3);
615 pr_info("%9.2fus ( +-%7.2f%% )", (double)etime / ecount/1e3, 613 pr_info("%9.2fus ( +-%7.2f%% )", (double)etime / ecount/1e3,
616 kvm_event_rel_stddev(vcpu, event)); 614 kvm_event_rel_stddev(vcpu, event));
617 pr_info("\n"); 615 pr_info("\n");
@@ -732,7 +730,7 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
732 return -1; 730 return -1;
733 } 731 }
734 732
735 err = perf_session_queue_event(kvm->session, event, &sample, 0); 733 err = perf_session_queue_event(kvm->session, event, &kvm->tool, &sample, 0);
736 /* 734 /*
737 * FIXME: Here we can't consume the event, as perf_session_queue_event will 735 * FIXME: Here we can't consume the event, as perf_session_queue_event will
738 * point to it, and it'll get possibly overwritten by the kernel. 736 * point to it, and it'll get possibly overwritten by the kernel.
@@ -785,7 +783,7 @@ static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm)
785 783
786 /* flush queue after each round in which we processed events */ 784 /* flush queue after each round in which we processed events */
787 if (ntotal) { 785 if (ntotal) {
788 kvm->session->ordered_samples.next_flush = flush_time; 786 kvm->session->ordered_events.next_flush = flush_time;
789 err = kvm->tool.finished_round(&kvm->tool, NULL, kvm->session); 787 err = kvm->tool.finished_round(&kvm->tool, NULL, kvm->session);
790 if (err) { 788 if (err) {
791 if (kvm->lost_events) 789 if (kvm->lost_events)
@@ -885,15 +883,11 @@ static int fd_set_nonblock(int fd)
885 return 0; 883 return 0;
886} 884}
887 885
888static 886static int perf_kvm__handle_stdin(void)
889int perf_kvm__handle_stdin(struct termios *tc_now, struct termios *tc_save)
890{ 887{
891 int c; 888 int c;
892 889
893 tcsetattr(0, TCSANOW, tc_now);
894 c = getc(stdin); 890 c = getc(stdin);
895 tcsetattr(0, TCSAFLUSH, tc_save);
896
897 if (c == 'q') 891 if (c == 'q')
898 return 1; 892 return 1;
899 893
@@ -902,9 +896,8 @@ int perf_kvm__handle_stdin(struct termios *tc_now, struct termios *tc_save)
902 896
903static int kvm_events_live_report(struct perf_kvm_stat *kvm) 897static int kvm_events_live_report(struct perf_kvm_stat *kvm)
904{ 898{
905 struct pollfd *pollfds = NULL; 899 int nr_stdin, ret, err = -EINVAL;
906 int nr_fds, nr_stdin, ret, err = -EINVAL; 900 struct termios save;
907 struct termios tc, save;
908 901
909 /* live flag must be set first */ 902 /* live flag must be set first */
910 kvm->live = true; 903 kvm->live = true;
@@ -919,41 +912,25 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
919 goto out; 912 goto out;
920 } 913 }
921 914
915 set_term_quiet_input(&save);
922 init_kvm_event_record(kvm); 916 init_kvm_event_record(kvm);
923 917
924 tcgetattr(0, &save);
925 tc = save;
926 tc.c_lflag &= ~(ICANON | ECHO);
927 tc.c_cc[VMIN] = 0;
928 tc.c_cc[VTIME] = 0;
929
930 signal(SIGINT, sig_handler); 918 signal(SIGINT, sig_handler);
931 signal(SIGTERM, sig_handler); 919 signal(SIGTERM, sig_handler);
932 920
933 /* copy pollfds -- need to add timerfd and stdin */
934 nr_fds = kvm->evlist->nr_fds;
935 pollfds = zalloc(sizeof(struct pollfd) * (nr_fds + 2));
936 if (!pollfds) {
937 err = -ENOMEM;
938 goto out;
939 }
940 memcpy(pollfds, kvm->evlist->pollfd,
941 sizeof(struct pollfd) * kvm->evlist->nr_fds);
942
943 /* add timer fd */ 921 /* add timer fd */
944 if (perf_kvm__timerfd_create(kvm) < 0) { 922 if (perf_kvm__timerfd_create(kvm) < 0) {
945 err = -1; 923 err = -1;
946 goto out; 924 goto out;
947 } 925 }
948 926
949 pollfds[nr_fds].fd = kvm->timerfd; 927 if (perf_evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0)
950 pollfds[nr_fds].events = POLLIN; 928 goto out;
951 nr_fds++; 929
930 nr_stdin = perf_evlist__add_pollfd(kvm->evlist, fileno(stdin));
931 if (nr_stdin < 0)
932 goto out;
952 933
953 pollfds[nr_fds].fd = fileno(stdin);
954 pollfds[nr_fds].events = POLLIN;
955 nr_stdin = nr_fds;
956 nr_fds++;
957 if (fd_set_nonblock(fileno(stdin)) != 0) 934 if (fd_set_nonblock(fileno(stdin)) != 0)
958 goto out; 935 goto out;
959 936
@@ -961,6 +938,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
961 perf_evlist__enable(kvm->evlist); 938 perf_evlist__enable(kvm->evlist);
962 939
963 while (!done) { 940 while (!done) {
941 struct fdarray *fda = &kvm->evlist->pollfd;
964 int rc; 942 int rc;
965 943
966 rc = perf_kvm__mmap_read(kvm); 944 rc = perf_kvm__mmap_read(kvm);
@@ -971,11 +949,11 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
971 if (err) 949 if (err)
972 goto out; 950 goto out;
973 951
974 if (pollfds[nr_stdin].revents & POLLIN) 952 if (fda->entries[nr_stdin].revents & POLLIN)
975 done = perf_kvm__handle_stdin(&tc, &save); 953 done = perf_kvm__handle_stdin();
976 954
977 if (!rc && !done) 955 if (!rc && !done)
978 err = poll(pollfds, nr_fds, 100); 956 err = fdarray__poll(fda, 100);
979 } 957 }
980 958
981 perf_evlist__disable(kvm->evlist); 959 perf_evlist__disable(kvm->evlist);
@@ -989,7 +967,7 @@ out:
989 if (kvm->timerfd >= 0) 967 if (kvm->timerfd >= 0)
990 close(kvm->timerfd); 968 close(kvm->timerfd);
991 969
992 free(pollfds); 970 tcsetattr(0, TCSAFLUSH, &save);
993 return err; 971 return err;
994} 972}
995 973
@@ -998,6 +976,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
998 int err, rc = -1; 976 int err, rc = -1;
999 struct perf_evsel *pos; 977 struct perf_evsel *pos;
1000 struct perf_evlist *evlist = kvm->evlist; 978 struct perf_evlist *evlist = kvm->evlist;
979 char sbuf[STRERR_BUFSIZE];
1001 980
1002 perf_evlist__config(evlist, &kvm->opts); 981 perf_evlist__config(evlist, &kvm->opts);
1003 982
@@ -1034,12 +1013,14 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
1034 1013
1035 err = perf_evlist__open(evlist); 1014 err = perf_evlist__open(evlist);
1036 if (err < 0) { 1015 if (err < 0) {
1037 printf("Couldn't create the events: %s\n", strerror(errno)); 1016 printf("Couldn't create the events: %s\n",
1017 strerror_r(errno, sbuf, sizeof(sbuf)));
1038 goto out; 1018 goto out;
1039 } 1019 }
1040 1020
1041 if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) { 1021 if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) {
1042 ui__error("Failed to mmap the events: %s\n", strerror(errno)); 1022 ui__error("Failed to mmap the events: %s\n",
1023 strerror_r(errno, sbuf, sizeof(sbuf)));
1043 perf_evlist__close(evlist); 1024 perf_evlist__close(evlist);
1044 goto out; 1025 goto out;
1045 } 1026 }
@@ -1058,7 +1039,7 @@ static int read_events(struct perf_kvm_stat *kvm)
1058 struct perf_tool eops = { 1039 struct perf_tool eops = {
1059 .sample = process_sample_event, 1040 .sample = process_sample_event,
1060 .comm = perf_event__process_comm, 1041 .comm = perf_event__process_comm,
1061 .ordered_samples = true, 1042 .ordered_events = true,
1062 }; 1043 };
1063 struct perf_data_file file = { 1044 struct perf_data_file file = {
1064 .path = kvm->file_name, 1045 .path = kvm->file_name,
@@ -1069,9 +1050,11 @@ static int read_events(struct perf_kvm_stat *kvm)
1069 kvm->session = perf_session__new(&file, false, &kvm->tool); 1050 kvm->session = perf_session__new(&file, false, &kvm->tool);
1070 if (!kvm->session) { 1051 if (!kvm->session) {
1071 pr_err("Initializing perf session failed\n"); 1052 pr_err("Initializing perf session failed\n");
1072 return -EINVAL; 1053 return -1;
1073 } 1054 }
1074 1055
1056 symbol__init(&kvm->session->header.env);
1057
1075 if (!perf_session__has_traces(kvm->session, "kvm record")) 1058 if (!perf_session__has_traces(kvm->session, "kvm record"))
1076 return -EINVAL; 1059 return -EINVAL;
1077 1060
@@ -1088,8 +1071,8 @@ static int read_events(struct perf_kvm_stat *kvm)
1088 1071
1089static int parse_target_str(struct perf_kvm_stat *kvm) 1072static int parse_target_str(struct perf_kvm_stat *kvm)
1090{ 1073{
1091 if (kvm->pid_str) { 1074 if (kvm->opts.target.pid) {
1092 kvm->pid_list = intlist__new(kvm->pid_str); 1075 kvm->pid_list = intlist__new(kvm->opts.target.pid);
1093 if (kvm->pid_list == NULL) { 1076 if (kvm->pid_list == NULL) {
1094 pr_err("Error parsing process id string\n"); 1077 pr_err("Error parsing process id string\n");
1095 return -EINVAL; 1078 return -EINVAL;
@@ -1191,7 +1174,7 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
1191 OPT_STRING('k', "key", &kvm->sort_key, "sort-key", 1174 OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
1192 "key for sorting: sample(sort by samples number)" 1175 "key for sorting: sample(sort by samples number)"
1193 " time (sort by avg time)"), 1176 " time (sort by avg time)"),
1194 OPT_STRING('p', "pid", &kvm->pid_str, "pid", 1177 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
1195 "analyze events only for given process id(s)"), 1178 "analyze events only for given process id(s)"),
1196 OPT_END() 1179 OPT_END()
1197 }; 1180 };
@@ -1201,8 +1184,6 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
1201 NULL 1184 NULL
1202 }; 1185 };
1203 1186
1204 symbol__init();
1205
1206 if (argc) { 1187 if (argc) {
1207 argc = parse_options(argc, argv, 1188 argc = parse_options(argc, argv,
1208 kvm_events_report_options, 1189 kvm_events_report_options,
@@ -1212,6 +1193,9 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
1212 kvm_events_report_options); 1193 kvm_events_report_options);
1213 } 1194 }
1214 1195
1196 if (!kvm->opts.target.pid)
1197 kvm->opts.target.system_wide = true;
1198
1215 return kvm_events_report_vcpu(kvm); 1199 return kvm_events_report_vcpu(kvm);
1216} 1200}
1217 1201
@@ -1311,7 +1295,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1311 kvm->tool.exit = perf_event__process_exit; 1295 kvm->tool.exit = perf_event__process_exit;
1312 kvm->tool.fork = perf_event__process_fork; 1296 kvm->tool.fork = perf_event__process_fork;
1313 kvm->tool.lost = process_lost_event; 1297 kvm->tool.lost = process_lost_event;
1314 kvm->tool.ordered_samples = true; 1298 kvm->tool.ordered_events = true;
1315 perf_tool__fill_defaults(&kvm->tool); 1299 perf_tool__fill_defaults(&kvm->tool);
1316 1300
1317 /* set defaults */ 1301 /* set defaults */
@@ -1322,7 +1306,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1322 kvm->opts.target.uid_str = NULL; 1306 kvm->opts.target.uid_str = NULL;
1323 kvm->opts.target.uid = UINT_MAX; 1307 kvm->opts.target.uid = UINT_MAX;
1324 1308
1325 symbol__init(); 1309 symbol__init(NULL);
1326 disable_buildid_cache(); 1310 disable_buildid_cache();
1327 1311
1328 use_browser = 0; 1312 use_browser = 0;
@@ -1369,11 +1353,12 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1369 */ 1353 */
1370 kvm->session = perf_session__new(&file, false, &kvm->tool); 1354 kvm->session = perf_session__new(&file, false, &kvm->tool);
1371 if (kvm->session == NULL) { 1355 if (kvm->session == NULL) {
1372 err = -ENOMEM; 1356 err = -1;
1373 goto out; 1357 goto out;
1374 } 1358 }
1375 kvm->session->evlist = kvm->evlist; 1359 kvm->session->evlist = kvm->evlist;
1376 perf_session__set_id_hdr_size(kvm->session); 1360 perf_session__set_id_hdr_size(kvm->session);
1361 ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true);
1377 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, 1362 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target,
1378 kvm->evlist->threads, false); 1363 kvm->evlist->threads, false);
1379 err = kvm_live_open_events(kvm); 1364 err = kvm_live_open_events(kvm);