Lines Matching refs:kvm
32 #include <asm/kvm.h>
74 void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key,
132 return !strcmp(evsel->name, "kvm:kvm_exit");
148 return !strcmp(evsel->name, "kvm:kvm_entry");
166 static const char *get_exit_reason(struct perf_kvm_stat *kvm, u64 exit_code)
168 int i = kvm->exit_reasons_size;
169 struct exit_reasons_table *tbl = kvm->exit_reasons;
177 pr_err("unknown kvm exit code:%lld on %s\n",
178 (unsigned long long)exit_code, kvm->exit_reasons_isa);
182 static void exit_event_decode_key(struct perf_kvm_stat *kvm,
186 const char *exit_reason = get_exit_reason(kvm, key->key);
222 if (!strcmp(evsel->name, "kvm:kvm_mmio") &&
239 if (!strcmp(evsel->name, "kvm:kvm_mmio") &&
248 static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
276 if (!strcmp(evsel->name, "kvm:kvm_pio")) {
291 static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
306 static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
310 if (!strcmp(kvm->report_event, "vmexit"))
311 kvm->events_ops = &exit_events;
312 else if (!strcmp(kvm->report_event, "mmio"))
313 kvm->events_ops = &mmio_events;
314 else if (!strcmp(kvm->report_event, "ioport"))
315 kvm->events_ops = &ioport_events;
317 pr_err("Unknown report event:%s\n", kvm->report_event);
331 static void init_kvm_event_record(struct perf_kvm_stat *kvm)
336 INIT_LIST_HEAD(&kvm->kvm_events_cache[i]);
405 static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm,
413 head = &kvm->kvm_events_cache[kvm_events_hash_fn(key->key)];
427 static bool handle_begin_event(struct perf_kvm_stat *kvm,
434 event = find_create_kvm_event(kvm, key);
474 static bool handle_end_event(struct perf_kvm_stat *kvm,
483 if (kvm->trace_vcpu == -1)
505 event = find_create_kvm_event(kvm, key);
521 if (kvm->duration && time_diff > kvm->duration) {
524 kvm->events_ops->decode_key(kvm, &event->key, decode);
557 static bool handle_kvm_event(struct perf_kvm_stat *kvm,
570 if ((kvm->trace_vcpu != -1) &&
571 (kvm->trace_vcpu != vcpu_record->vcpu_id))
574 if (kvm->events_ops->is_begin_event(evsel, sample, &key))
575 return handle_begin_event(kvm, vcpu_record, &key, sample->time);
577 if (kvm->events_ops->is_end_event(evsel, sample, &key))
578 return handle_end_event(kvm, vcpu_record, &key, sample);
619 static bool select_key(struct perf_kvm_stat *kvm)
624 if (!strcmp(keys[i].name, kvm->sort_key)) {
625 kvm->compare = keys[i].key;
630 pr_err("Unknown compare key:%s\n", kvm->sort_key);
656 update_total_count(struct perf_kvm_stat *kvm, struct kvm_event *event)
658 int vcpu = kvm->trace_vcpu;
660 kvm->total_count += get_event_count(event, vcpu);
661 kvm->total_time += get_event_time(event, vcpu);
669 static void sort_result(struct perf_kvm_stat *kvm)
672 int vcpu = kvm->trace_vcpu;
676 list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry) {
678 update_total_count(kvm, event);
679 insert_to_result(&kvm->result, event,
680 kvm->compare, vcpu);
698 static void print_vcpu_info(struct perf_kvm_stat *kvm)
700 int vcpu = kvm->trace_vcpu;
704 if (kvm
705 if (kvm->opts.target.system_wide)
707 else if (kvm->opts.target.pid)
708 pr_info("pid(s) %s, ", kvm->opts.target.pid);
735 static void print_result(struct perf_kvm_stat *kvm)
739 int vcpu = kvm->trace_vcpu;
741 if (kvm->live) {
747 print_vcpu_info(kvm);
748 pr_info("%20s ", kvm->events_ops->name);
758 while ((event = pop_from_result(&kvm->result))) {
766 kvm->events_ops->decode_key(kvm, &event->key, decode);
769 pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100);
770 pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100);
779 kvm->total_count, kvm->total_time / 1e3);
781 if (kvm->lost_events)
782 pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events);
790 struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, tool);
792 kvm->lost_events++;
796 static bool skip_sample(struct perf_kvm_stat *kvm,
799 if (kvm->pid_list && intlist__find(kvm->pid_list, sample->pid) == NULL)
812 struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat,
815 if (skip_sample(kvm, sample))
825 if (!handle_kvm_event(kvm, thread, evsel, sample))
831 static int cpu_isa_config(struct perf_kvm_stat *kvm)
836 if (kvm->live) {
844 cpuid = kvm->session->header.env.cpuid;
856 kvm->exit_reasons = vmx_exit_reasons;
857 kvm->exit_reasons_size = ARRAY_SIZE(vmx_exit_reasons);
858 kvm->exit_reasons_isa = "VMX";
879 static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
888 while ((event = perf_evlist__mmap_read(kvm->evlist, idx)) != NULL) {
889 err = perf_evlist__parse_sample(kvm->evlist, event, &sample);
891 perf_evlist__mmap_consume(kvm->evlist, idx);
896 err = perf_session_queue_event(kvm->session, event, &sample, 0);
901 perf_evlist__mmap_consume(kvm->evlist, idx);
921 static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm)
927 for (i = 0; i < kvm->evlist->nr_mmaps; i++) {
928 n = perf_kvm__mmap_read_idx(kvm, i, &mmap_time);
949 kvm->session->ordered_samples.next_flush = flush_time;
950 err = kvm->tool.finished_round(&kvm->tool, NULL, kvm->session);
952 if (kvm->lost_events)
954 kvm->lost_events);
969 static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm)
974 kvm->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
975 if (kvm->timerfd < 0) {
980 new_value.it_value.tv_sec = kvm->display_time;
982 new_value.it_interval.tv_sec = kvm->display_time;
985 if (timerfd_settime(kvm->timerfd, 0, &new_value, NULL) != 0) {
987 close(kvm->timerfd);
996 static int perf_kvm__handle_timerfd(struct perf_kvm_stat *kvm)
1001 rc = read(kvm->timerfd, &c, sizeof(uint64_t));
1019 sort_result(kvm);
1020 print_result(kvm);
1023 clear_events_cache_stats(kvm->kvm_events_cache);
1024 kvm->total_count = 0;
1025 kvm->total_time = 0;
1026 kvm->lost_events = 0;
1064 static int kvm_events_live_report(struct perf_kvm_stat *kvm)
1071 kvm->live = true;
1073 ret = cpu_isa_config(kvm);
1077 if (!verify_vcpu(kvm->trace_vcpu) ||
1078 !select_key(kvm) ||
1079 !register_kvm_events_ops(kvm)) {
1083 init_kvm_event_record(kvm);
1095 nr_fds = kvm->evlist->nr_fds;
1101 memcpy(pollfds, kvm->evlist->pollfd,
1102 sizeof(struct pollfd) * kvm->evlist->nr_fds);
1105 if (perf_kvm__timerfd_create(kvm) < 0) {
1110 pollfds[nr_fds].fd = kvm->timerfd;
1122 perf_evlist__enable(kvm->evlist);
1127 rc = perf_kvm__mmap_read(kvm);
1131 err = perf_kvm__handle_timerfd(kvm);
1142 perf_evlist__disable(kvm->evlist);
1145 sort_result(kvm);
1146 print_result(kvm);
1150 if (kvm->timerfd >= 0)
1151 close(kvm->timerfd);
1159 static int kvm_live_open_events(struct perf_kvm_stat *kvm)
1163 struct perf_evlist *evlist = kvm->evlist;
1165 perf_evlist__config(evlist, &kvm->opts);
1169 * This command processes KVM tracepoints from host only
1204 if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) {
1216 static int read_events(struct perf_kvm_stat *kvm)
1226 kvm->tool = eops;
1227 kvm->session = perf_session__new(kvm->file_name, O_RDONLY, 0, false,
1228 &kvm->tool);
1229 if (!kvm->session) {
1234 if (!perf_session__has_traces(kvm->session, "kvm record"))
1241 ret = cpu_isa_config(kvm);
1245 return perf_session__process_events(kvm->session, &kvm->tool);
1248 static int parse_target_str(struct perf_kvm_stat *kvm)
1250 if (kvm->pid_str) {
1251 kvm->pid_list = intlist__new(kvm->pid_str);
1252 if (kvm->pid_list == NULL) {
1261 static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
1264 int vcpu = kvm->trace_vcpu;
1266 if (parse_target_str(kvm) != 0)
1272 if (!select_key(kvm))
1275 if (!register_kvm_events_ops(kvm))
1278 init_kvm_event_record(kvm);
1281 ret = read_events(kvm);
1285 sort_result(kvm);
1286 print_result(kvm);
1293 "kvm:kvm_entry",
1294 "kvm:kvm_exit",
1295 "kvm:kvm_mmio",
1296 "kvm:kvm_pio",
1308 kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
1335 rec_argv[i++] = STRDUP_FAIL_EXIT(kvm->file_name);
1344 kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
1347 OPT_STRING(0, "event", &kvm->report_event, "report event",
1349 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu,
1351 OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
1354 OPT_STRING('p', "pid", &kvm->pid_str, "pid",
1360 "perf kvm stat report [<options>]",
1375 return kvm_events_report_vcpu(kvm);
1427 static int kvm_events_live(struct perf_kvm_stat *kvm,
1434 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
1436 OPT_UINTEGER('m', "mmap-pages", &kvm->opts.mmap_pages,
1440 OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide,
1442 OPT_UINTEGER('d', "display", &kvm->display_time,
1444 OPT_STRING(0, "event", &kvm->report_event, "report event",
1446 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu,
1448 OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
1451 OPT_U64(0, "duration", &kvm->duration,
1456 "perf kvm stat live [<options>]",
1462 kvm->tool.sample = process_sample_event;
1463 kvm->tool.comm = perf_event__process_comm;
1464 kvm->tool.exit = perf_event__process_exit;
1465 kvm->tool.fork = perf_event__process_fork;
1466 kvm->tool.lost = process_lost_event;
1467 kvm->tool.ordered_samples = true;
1468 perf_tool__fill_defaults(&kvm->tool);
1471 kvm->display_time = 1;
1472 kvm->opts.user_interval = 1;
1473 kvm->opts.mmap_pages = 512;
1474 kvm->opts.target.uses_mmap = false;
1475 kvm->opts.target.uid_str = NULL;
1476 kvm->opts.target.uid = UINT_MAX;
1491 kvm->duration *= NSEC_PER_USEC; /* convert usec to nsec */
1496 err = perf_target__validate(&kvm->opts.target);
1498 perf_target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ);
1502 if (perf_target__none(&kvm->opts.target))
1503 kvm->opts.target.system_wide = true;
1509 kvm->evlist = kvm_live_event_list();
1510 if (kvm->evlist == NULL) {
1515 symbol_conf.nr_events = kvm->evlist->nr_entries;
1517 if (perf_evlist__create_maps(kvm->evlist, &kvm->opts.target) < 0)
1523 kvm->session = perf_session__new(NULL, O_WRONLY, false, false, &kvm->tool);
1524 if (kvm->session == NULL) {
1528 kvm->session->evlist = kvm->evlist;
1529 perf_session__set_id_hdr_size(kvm->session);
1532 if (perf_target__has_task(&kvm->opts.target))
1533 perf_event__synthesize_thread_map(&kvm->tool,
1534 kvm->evlist->threads,
1536 &kvm->session->machines.host);
1538 perf_event__synthesize_threads(&kvm->tool, perf_event__process,
1539 &kvm->session->machines.host);
1542 err = kvm_live_open_events(kvm);
1546 err = kvm_events_live_report(kvm);
1551 if (kvm->session)
1552 perf_session__delete(kvm->session);
1553 kvm->session = NULL;
1554 if (kvm->evlist) {
1555 perf_evlist__delete_maps(kvm->evlist);
1556 perf_evlist__delete(kvm->evlist);
1564 printf("Usage: perf kvm stat <command>\n\n");
1567 printf("\trecord: record kvm events\n");
1568 printf("\treport: report statistical data of kvm events\n");
1569 printf("\tlive: live reporting of statistical data of kvm events\n");
1576 struct perf_kvm_stat kvm = {
1594 return kvm_events_record(&kvm, argc - 1, argv + 1);
1597 return kvm_events_report(&kvm, argc - 1 , argv + 1);
1600 return kvm_events_live(&kvm, argc - 1 , argv + 1);
1688 "perf kvm [<options>] {top|record|report|diff|buildid-list|stat}",
1709 file_name = strdup("perf.data.kvm");