Lines Matching defs:kvm
25 #include "util/kvm-stat.h"
60 filename = strdup("perf.data.kvm");
103 static const char *get_exit_reason(struct perf_kvm_stat *kvm,
113 pr_err("unknown kvm exit code:%lld on %s\n",
114 (unsigned long long)exit_code, kvm->exit_reasons_isa);
118 void exit_event_decode_key(struct perf_kvm_stat *kvm,
122 const char *exit_reason = get_exit_reason(kvm, key->exit_reasons,
128 static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
133 if (!strcmp(events_ops->name, kvm->report_event)) {
134 kvm->events_ops = events_ops->ops;
149 static void init_kvm_event_record(struct perf_kvm_stat *kvm)
154 INIT_LIST_HEAD(&kvm->kvm_events_cache[i]);
226 static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm,
234 head = &kvm->kvm_events_cache[kvm_events_hash_fn(key->key)];
248 static bool handle_begin_event(struct perf_kvm_stat *kvm,
255 event = find_create_kvm_event(kvm, key);
295 static bool is_child_event(struct perf_kvm_stat *kvm,
302 child_ops = kvm->events_ops->child_ops;
317 static bool handle_child_event(struct perf_kvm_stat *kvm,
325 event = find_create_kvm_event(kvm, key);
343 static bool handle_end_event(struct perf_kvm_stat *kvm,
352 if (kvm->trace_vcpu == -1)
374 event = find_create_kvm_event(kvm, key);
390 if (kvm->duration && time_diff > kvm->duration) {
393 kvm->events_ops->decode_key(kvm, &event->key, decode);
426 static bool handle_kvm_event(struct perf_kvm_stat *kvm,
433 .exit_reasons = kvm->exit_reasons };
440 if ((kvm->trace_vcpu != -1) &&
441 (kvm->trace_vcpu != vcpu_record->vcpu_id))
444 if (kvm->events_ops->is_begin_event(evsel, sample, &key))
445 return handle_begin_event(kvm, vcpu_record, &key, sample->time);
447 if (is_child_event(kvm, evsel, sample, &key))
448 return handle_child_event(kvm, vcpu_record, &key, sample);
450 if (kvm->events_ops->is_end_event(evsel, sample, &key))
451 return handle_end_event(kvm, vcpu_record, &key, sample);
492 static bool select_key(struct perf_kvm_stat *kvm)
497 if (!strcmp(keys[i].name, kvm->sort_key)) {
498 kvm->compare = keys[i].key;
503 pr_err("Unknown compare key:%s\n", kvm->sort_key);
529 update_total_count(struct perf_kvm_stat *kvm, struct kvm_event *event)
531 int vcpu = kvm->trace_vcpu;
533 kvm->total_count += get_event_count(event, vcpu);
534 kvm->total_time += get_event_time(event, vcpu);
542 static void sort_result(struct perf_kvm_stat *kvm)
545 int vcpu = kvm->trace_vcpu;
549 list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry) {
551 update_total_count(kvm, event);
552 insert_to_result(&kvm->result, event,
553 kvm->compare, vcpu);
571 static void print_vcpu_info(struct perf_kvm_stat *kvm)
573 int vcpu = kvm->trace_vcpu;
577 if (kvm->opts.target.system_wide)
579 else if (kvm->opts.target.pid)
580 pr_info("pid(s) %s, ", kvm->opts.target.pid);
606 static void print_result(struct perf_kvm_stat *kvm)
610 int vcpu = kvm->trace_vcpu;
612 if (kvm->live) {
618 print_vcpu_info(kvm);
619 pr_info("%*s ", decode_str_len, kvm->events_ops->name);
629 while ((event = pop_from_result(&kvm->result))) {
637 kvm->events_ops->decode_key(kvm, &event->key, decode);
640 pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100);
641 pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100);
650 kvm->total_count, kvm->total_time / (double)NSEC_PER_USEC);
652 if (kvm->lost_events)
653 pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events);
662 struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, tool);
664 kvm->lost_events++;
669 static bool skip_sample(struct perf_kvm_stat *kvm,
672 if (kvm->pid_list && intlist__find(kvm->pid_list, sample->pid) == NULL)
686 struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat,
689 if (skip_sample(kvm, sample))
699 if (!handle_kvm_event(kvm, thread, evsel, sample))
706 static int cpu_isa_config(struct perf_kvm_stat *kvm)
711 if (kvm->live) {
720 cpuid = kvm->session->header.env.cpuid;
727 err = cpu_isa_init(kvm, cpuid);
750 static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
753 struct evlist *evlist = kvm->evlist;
774 err = perf_session__queue_event(kvm->session, event, timestamp, 0);
800 static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm)
806 for (i = 0; i < kvm->evlist->core.nr_mmaps; i++) {
807 n = perf_kvm__mmap_read_idx(kvm, i, &mmap_time);
828 struct ordered_events *oe = &kvm->session->ordered_events;
833 if (kvm->lost_events)
835 kvm->lost_events);
850 static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm)
855 kvm->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
856 if (kvm->timerfd < 0) {
861 new_value.it_value.tv_sec = kvm->display_time;
863 new_value.it_interval.tv_sec = kvm->display_time;
866 if (timerfd_settime(kvm->timerfd, 0, &new_value, NULL) != 0) {
868 close(kvm->timerfd);
877 static int perf_kvm__handle_timerfd(struct perf_kvm_stat *kvm)
882 rc = read(kvm->timerfd, &c, sizeof(uint64_t));
900 sort_result(kvm);
901 print_result(kvm);
904 clear_events_cache_stats(kvm->kvm_events_cache);
905 kvm->total_count = 0;
906 kvm->total_time = 0;
907 kvm->lost_events = 0;
941 static int kvm_events_live_report(struct perf_kvm_stat *kvm)
947 kvm->live = true;
949 ret = cpu_isa_config(kvm);
953 if (!verify_vcpu(kvm->trace_vcpu) ||
954 !select_key(kvm) ||
955 !register_kvm_events_ops(kvm)) {
960 init_kvm_event_record(kvm);
966 if (perf_kvm__timerfd_create(kvm) < 0) {
971 if (evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0)
974 nr_stdin = evlist__add_pollfd(kvm->evlist, fileno(stdin));
982 evlist__enable(kvm->evlist);
985 struct fdarray *fda = &kvm->evlist->core.pollfd;
988 rc = perf_kvm__mmap_read(kvm);
992 err = perf_kvm__handle_timerfd(kvm);
1000 err = evlist__poll(kvm->evlist, 100);
1003 evlist__disable(kvm->evlist);
1006 sort_result(kvm);
1007 print_result(kvm);
1011 if (kvm->timerfd >= 0)
1012 close(kvm->timerfd);
1018 static int kvm_live_open_events(struct perf_kvm_stat *kvm)
1022 struct evlist *evlist = kvm->evlist;
1025 perf_evlist__config(evlist, &kvm->opts, NULL);
1065 if (evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) {
1079 static int read_events(struct perf_kvm_stat *kvm)
1090 .path = kvm->file_name,
1092 .force = kvm->force,
1095 kvm->tool = eops;
1096 kvm->session = perf_session__new(&file, false, &kvm->tool);
1097 if (IS_ERR(kvm->session)) {
1099 return PTR_ERR(kvm->session);
1102 symbol__init(&kvm->session->header.env);
1104 if (!perf_session__has_traces(kvm->session, "kvm record")) {
1113 ret = cpu_isa_config(kvm);
1117 ret = perf_session__process_events(kvm->session);
1120 perf_session__delete(kvm->session);
1124 static int parse_target_str(struct perf_kvm_stat *kvm)
1126 if (kvm->opts.target.pid) {
1127 kvm->pid_list = intlist__new(kvm->opts.target.pid);
1128 if (kvm->pid_list == NULL) {
1137 static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
1140 int vcpu = kvm->trace_vcpu;
1142 if (parse_target_str(kvm) != 0)
1148 if (!select_key(kvm))
1151 if (!register_kvm_events_ops(kvm))
1154 init_kvm_event_record(kvm);
1157 ret = read_events(kvm);
1161 sort_result(kvm);
1162 print_result(kvm);
1176 int __weak setup_kvm_events_tp(struct perf_kvm_stat *kvm __maybe_unused)
1182 kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
1193 "perf kvm stat record [<options>]",
1200 ret = setup_kvm_events_tp(kvm);
1202 pr_err("Unable to setup the kvm tracepoints\n");
1225 rec_argv[i++] = STRDUP_FAIL_EXIT(kvm->file_name);
1255 kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
1258 OPT_STRING(0, "event", &kvm->report_event, "report event",
1261 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu,
1263 OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
1266 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
1268 OPT_BOOLEAN('f', "force", &kvm->force, "don't complain, do it"),
1273 "perf kvm stat report [<options>]",
1286 if (!kvm->opts.target.pid)
1287 kvm->opts.target.system_wide = true;
1289 return kvm_events_report_vcpu(kvm);
1342 static int kvm_events_live(struct perf_kvm_stat *kvm,
1349 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
1351 OPT_CALLBACK('m', "mmap-pages", &kvm->opts.mmap_pages, "pages",
1356 OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide,
1358 OPT_UINTEGER('d', "display", &kvm->display_time,
1360 OPT_STRING(0, "event", &kvm->report_event, "report event",
1363 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu,
1365 OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
1368 OPT_U64(0, "duration", &kvm->duration,
1377 "perf kvm stat live [<options>]",
1386 kvm->tool.sample = process_sample_event;
1387 kvm->tool.comm = perf_event__process_comm;
1388 kvm->tool.exit = perf_event__process_exit;
1389 kvm->tool.fork = perf_event__process_fork;
1390 kvm->tool.lost = process_lost_event;
1391 kvm->tool.namespaces = perf_event__process_namespaces;
1392 kvm->tool.ordered_events = true;
1393 perf_tool__fill_defaults(&kvm->tool);
1396 kvm->display_time = 1;
1397 kvm->opts.user_interval = 1;
1398 kvm->opts.mmap_pages = 512;
1399 kvm->opts.target.uses_mmap = false;
1400 kvm->opts.target.uid_str = NULL;
1401 kvm->opts.target.uid = UINT_MAX;
1415 kvm->duration *= NSEC_PER_USEC; /* convert usec to nsec */
1420 err = target__validate(&kvm->opts.target);
1422 target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ);
1426 if (target__none(&kvm->opts.target))
1427 kvm->opts.target.system_wide = true;
1433 err = setup_kvm_events_tp(kvm);
1435 pr_err("Unable to setup the kvm tracepoints\n");
1439 kvm->evlist = kvm_live_event_list();
1440 if (kvm->evlist == NULL) {
1445 if (perf_evlist__create_maps(kvm->evlist, &kvm->opts.target) < 0)
1451 kvm->session = perf_session__new(&data, false, &kvm->tool);
1452 if (IS_ERR(kvm->session)) {
1453 err = PTR_ERR(kvm->session);
1456 kvm->session->evlist = kvm->evlist;
1457 perf_session__set_id_hdr_size(kvm->session);
1458 ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true);
1459 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target,
1460 kvm->evlist->core.threads, false, 1);
1461 err = kvm_live_open_events(kvm);
1465 err = kvm_events_live_report(kvm);
1468 perf_session__delete(kvm->session);
1469 kvm->session = NULL;
1470 evlist__delete(kvm->evlist);
1478 printf("Usage: perf kvm stat <command>\n\n");
1481 printf("\trecord: record kvm events\n");
1482 printf("\treport: report statistical data of kvm events\n");
1483 printf("\tlive: live reporting of statistical data of kvm events\n");
1490 struct perf_kvm_stat kvm = {
1505 return kvm_events_record(&kvm, argc - 1, argv + 1);
1508 return kvm_events_report(&kvm, argc - 1 , argv + 1);
1512 return kvm_events_live(&kvm, argc - 1 , argv + 1);