^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include "builtin.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include "perf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include "util/build-id.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "util/evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "util/evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "util/mmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "util/term.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "util/symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "util/thread.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "util/header.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "util/session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "util/intlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <subcmd/pager.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <subcmd/parse-options.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "util/trace-event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "util/debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "util/tool.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "util/stat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "util/synthetic-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "util/top.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "util/data.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "util/ordered-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "util/kvm-stat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "ui/ui.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <sys/prctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #ifdef HAVE_TIMERFD_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <sys/timerfd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <sys/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/time64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <termios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <semaphore.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <math.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <perf/mmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static const char *get_filename_for_perf_kvm(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) const char *filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (perf_host && !perf_guest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) filename = strdup("perf.data.host");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) else if (!perf_host && perf_guest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) filename = strdup("perf.data.guest");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) filename = strdup("perf.data.kvm");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #ifdef HAVE_KVM_STAT_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) void exit_event_get_key(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct event_key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) key->info = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) key->key = evsel__intval(evsel, sample, kvm_exit_reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) bool kvm_exit_event(struct evsel *evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return !strcmp(evsel->name, kvm_exit_trace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) bool exit_event_begin(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct perf_sample *sample, struct event_key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (kvm_exit_event(evsel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) exit_event_get_key(evsel, sample, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) bool kvm_entry_event(struct evsel *evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return !strcmp(evsel->name, kvm_entry_trace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) bool exit_event_end(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct perf_sample *sample __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct event_key *key __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return kvm_entry_event(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static const char *get_exit_reason(struct perf_kvm_stat *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct exit_reasons_table *tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u64 exit_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) while (tbl->reason != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (tbl->exit_code == exit_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return tbl->reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) tbl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) pr_err("unknown kvm exit code:%lld on %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) (unsigned long long)exit_code, kvm->exit_reasons_isa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return "UNKNOWN";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) void exit_event_decode_key(struct perf_kvm_stat *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct event_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) char *decode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) const char *exit_reason = get_exit_reason(kvm, key->exit_reasons,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) key->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) scnprintf(decode, decode_str_len, "%s", exit_reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct kvm_reg_events_ops *events_ops = kvm_reg_events_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) for (events_ops = kvm_reg_events_ops; events_ops->name; events_ops++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (!strcmp(events_ops->name, kvm->report_event)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) kvm->events_ops = events_ops->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct vcpu_event_record {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int vcpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u64 start_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct kvm_event *last_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static void init_kvm_event_record(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) for (i = 0; i < EVENTS_CACHE_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) INIT_LIST_HEAD(&kvm->kvm_events_cache[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #ifdef HAVE_TIMERFD_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static void clear_events_cache_stats(struct list_head *kvm_events_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct list_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct kvm_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) for (i = 0; i < EVENTS_CACHE_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) head = &kvm_events_cache[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) list_for_each_entry(event, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* reset stats for event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) event->total.time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) init_stats(&event->total.stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) for (j = 0; j < event->max_vcpu; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) event->vcpu[j].time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) init_stats(&event->vcpu[j].stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int kvm_events_hash_fn(u64 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return key & (EVENTS_CACHE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int old_max_vcpu = event->max_vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) void *prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (vcpu_id < event->max_vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) while (event->max_vcpu <= vcpu_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) event->max_vcpu += DEFAULT_VCPU_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) prev = event->vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) event->vcpu = realloc(event->vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) event->max_vcpu * sizeof(*event->vcpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (!event->vcpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) free(prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) pr_err("Not enough memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) memset(event->vcpu + old_max_vcpu, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) (event->max_vcpu - old_max_vcpu) * sizeof(*event->vcpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static struct kvm_event *kvm_alloc_init_event(struct event_key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct kvm_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) event = zalloc(sizeof(*event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (!event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) pr_err("Not enough memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) event->key = *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) init_stats(&event->total.stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct event_key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct kvm_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct list_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) BUG_ON(key->key == INVALID_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) head = &kvm->kvm_events_cache[kvm_events_hash_fn(key->key)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) list_for_each_entry(event, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (event->key.key == key->key && event->key.info == key->info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) event = kvm_alloc_init_event(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) list_add(&event->hash_entry, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static bool handle_begin_event(struct perf_kvm_stat *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct vcpu_event_record *vcpu_record,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct event_key *key, u64 timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct kvm_event *event = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (key->key != INVALID_KEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) event = find_create_kvm_event(kvm, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) vcpu_record->last_event = event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) vcpu_record->start_time = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) kvm_update_event_stats(struct kvm_event_stats *kvm_stats, u64 time_diff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) kvm_stats->time += time_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) update_stats(&kvm_stats->stats, time_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static double kvm_event_rel_stddev(int vcpu_id, struct kvm_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct kvm_event_stats *kvm_stats = &event->total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (vcpu_id != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) kvm_stats = &event->vcpu[vcpu_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return rel_stddev_stats(stddev_stats(&kvm_stats->stats),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) avg_stats(&kvm_stats->stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) u64 time_diff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (vcpu_id == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) kvm_update_event_stats(&event->total, time_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!kvm_event_expand(event, vcpu_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) kvm_update_event_stats(&event->vcpu[vcpu_id], time_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static bool is_child_event(struct perf_kvm_stat *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct event_key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct child_event_ops *child_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) child_ops = kvm->events_ops->child_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (!child_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) for (; child_ops->name; child_ops++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (!strcmp(evsel->name, child_ops->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) child_ops->get_key(evsel, sample, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static bool handle_child_event(struct perf_kvm_stat *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct vcpu_event_record *vcpu_record,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct event_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct perf_sample *sample __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct kvm_event *event = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (key->key != INVALID_KEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) event = find_create_kvm_event(kvm, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) vcpu_record->last_event = event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static bool skip_event(const char *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) const char * const *skip_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) for (skip_events = kvm_skip_events; *skip_events; skip_events++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (!strcmp(event, *skip_events))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static bool handle_end_event(struct perf_kvm_stat *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct vcpu_event_record *vcpu_record,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct event_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct kvm_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) u64 time_begin, time_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (kvm->trace_vcpu == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) vcpu = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) vcpu = vcpu_record->vcpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) event = vcpu_record->last_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) time_begin = vcpu_record->start_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* The begin event is not caught. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!time_begin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * In some case, the 'begin event' only records the start timestamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * the actual event is recognized in the 'end event' (e.g. mmio-event).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* Both begin and end events did not get the key. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (!event && key->key == INVALID_KEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) event = find_create_kvm_event(kvm, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) vcpu_record->last_event = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) vcpu_record->start_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* seems to happen once in a while during live mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (sample->time < time_begin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) pr_debug("End time before begin time; skipping event.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) time_diff = sample->time - time_begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (kvm->duration && time_diff > kvm->duration) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) char decode[decode_str_len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) kvm->events_ops->decode_key(kvm, &event->key, decode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (!skip_event(decode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) pr_info("%" PRIu64 " VM %d, vcpu %d: %s event took %" PRIu64 "usec\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) sample->time, sample->pid, vcpu_record->vcpu_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) decode, time_diff / NSEC_PER_USEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return update_kvm_event(event, vcpu, time_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct vcpu_event_record *per_vcpu_record(struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* Only kvm_entry records vcpu id. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (!thread__priv(thread) && kvm_entry_event(evsel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct vcpu_event_record *vcpu_record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) vcpu_record = zalloc(sizeof(*vcpu_record));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (!vcpu_record) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) pr_err("%s: Not enough memory\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) vcpu_record->vcpu_id = evsel__intval(evsel, sample, vcpu_id_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) thread__set_priv(thread, vcpu_record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return thread__priv(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static bool handle_kvm_event(struct perf_kvm_stat *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct thread *thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct vcpu_event_record *vcpu_record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct event_key key = { .key = INVALID_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .exit_reasons = kvm->exit_reasons };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) vcpu_record = per_vcpu_record(thread, evsel, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (!vcpu_record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* only process events for vcpus user cares about */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if ((kvm->trace_vcpu != -1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) (kvm->trace_vcpu != vcpu_record->vcpu_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (kvm->events_ops->is_begin_event(evsel, sample, &key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return handle_begin_event(kvm, vcpu_record, &key, sample->time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (is_child_event(kvm, evsel, sample, &key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return handle_child_event(kvm, vcpu_record, &key, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (kvm->events_ops->is_end_event(evsel, sample, &key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return handle_end_event(kvm, vcpu_record, &key, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) #define GET_EVENT_KEY(func, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static u64 get_event_ ##func(struct kvm_event *event, int vcpu) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (vcpu == -1) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return event->total.field; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (vcpu >= event->max_vcpu) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return event->vcpu[vcpu].field; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) #define COMPARE_EVENT_KEY(func, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) GET_EVENT_KEY(func, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static int compare_kvm_event_ ## func(struct kvm_event *one, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct kvm_event *two, int vcpu)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return get_event_ ##func(one, vcpu) > \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) get_event_ ##func(two, vcpu); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) GET_EVENT_KEY(time, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) COMPARE_EVENT_KEY(count, stats.n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) COMPARE_EVENT_KEY(mean, stats.mean);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) GET_EVENT_KEY(max, stats.max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) GET_EVENT_KEY(min, stats.min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #define DEF_SORT_NAME_KEY(name, compare_key) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) { #name, compare_kvm_event_ ## compare_key }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static struct kvm_event_key keys[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) DEF_SORT_NAME_KEY(sample, count),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) DEF_SORT_NAME_KEY(time, mean),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) { NULL, NULL }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static bool select_key(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) for (i = 0; keys[i].name; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (!strcmp(keys[i].name, kvm->sort_key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) kvm->compare = keys[i].key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) pr_err("Unknown compare key:%s\n", kvm->sort_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static void insert_to_result(struct rb_root *result, struct kvm_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) key_cmp_fun bigger, int vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct rb_node **rb = &result->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct rb_node *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct kvm_event *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) while (*rb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) p = container_of(*rb, struct kvm_event, rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) parent = *rb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (bigger(event, p, vcpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) rb = &(*rb)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) rb = &(*rb)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) rb_link_node(&event->rb, parent, rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) rb_insert_color(&event->rb, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) update_total_count(struct perf_kvm_stat *kvm, struct kvm_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int vcpu = kvm->trace_vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) kvm->total_count += get_event_count(event, vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) kvm->total_time += get_event_time(event, vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static bool event_is_valid(struct kvm_event *event, int vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return !!get_event_count(event, vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static void sort_result(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int vcpu = kvm->trace_vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct kvm_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) for (i = 0; i < EVENTS_CACHE_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (event_is_valid(event, vcpu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) update_total_count(kvm, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) insert_to_result(&kvm->result, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) kvm->compare, vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* returns left most element of result, and erase it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static struct kvm_event *pop_from_result(struct rb_root *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct rb_node *node = rb_first(result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) rb_erase(node, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return container_of(node, struct kvm_event, rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static void print_vcpu_info(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int vcpu = kvm->trace_vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) pr_info("Analyze events for ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (kvm->opts.target.system_wide)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) pr_info("all VMs, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) else if (kvm->opts.target.pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) pr_info("pid(s) %s, ", kvm->opts.target.pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) pr_info("dazed and confused on what is monitored, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (vcpu == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) pr_info("all VCPUs:\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) pr_info("VCPU %d:\n\n", vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static void show_timeofday(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) char date[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct timeval tv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct tm ltime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) gettimeofday(&tv, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (localtime_r(&tv.tv_sec, <ime)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) strftime(date, sizeof(date), "%H:%M:%S", <ime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) pr_info("%s.%06ld", date, tv.tv_usec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) pr_info("00:00:00.000000");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static void print_result(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) char decode[decode_str_len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct kvm_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) int vcpu = kvm->trace_vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (kvm->live) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) puts(CONSOLE_CLEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) show_timeofday();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) pr_info("\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) print_vcpu_info(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) pr_info("%*s ", decode_str_len, kvm->events_ops->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) pr_info("%10s ", "Samples");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) pr_info("%9s ", "Samples%");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) pr_info("%9s ", "Time%");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) pr_info("%11s ", "Min Time");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) pr_info("%11s ", "Max Time");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) pr_info("%16s ", "Avg time");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) pr_info("\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) while ((event = pop_from_result(&kvm->result))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) u64 ecount, etime, max, min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ecount = get_event_count(event, vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) etime = get_event_time(event, vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) max = get_event_max(event, vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) min = get_event_min(event, vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) kvm->events_ops->decode_key(kvm, &event->key, decode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) pr_info("%*s ", decode_str_len, decode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) pr_info("%10llu ", (unsigned long long)ecount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) pr_info("%9.2fus ", (double)min / NSEC_PER_USEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) pr_info("%9.2fus ", (double)max / NSEC_PER_USEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) pr_info("%9.2fus ( +-%7.2f%% )", (double)etime / ecount / NSEC_PER_USEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) kvm_event_rel_stddev(vcpu, event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) pr_info("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) pr_info("\nTotal Samples:%" PRIu64 ", Total events handled time:%.2fus.\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) kvm->total_count, kvm->total_time / (double)NSEC_PER_USEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (kvm->lost_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) #ifdef HAVE_TIMERFD_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static int process_lost_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) union perf_event *event __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct perf_sample *sample __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct machine *machine __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) kvm->lost_events++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static bool skip_sample(struct perf_kvm_stat *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (kvm->pid_list && intlist__find(kvm->pid_list, sample->pid) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int process_sample_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct thread *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (skip_sample(kvm, sample))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) thread = machine__findnew_thread(machine, sample->pid, sample->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (thread == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) pr_debug("problem processing %d event, skipping it.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) event->header.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (!handle_kvm_event(kvm, thread, evsel, sample))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) thread__put(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static int cpu_isa_config(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) char buf[128], *cpuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (kvm->live) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) err = get_cpuid(buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (err != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) pr_err("Failed to look up CPU type: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) str_error_r(err, buf, sizeof(buf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return -err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) cpuid = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) cpuid = kvm->session->header.env.cpuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (!cpuid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) pr_err("Failed to look up CPU type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) err = cpu_isa_init(kvm, cpuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (err == -ENOTSUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) pr_err("CPU %s is not supported.\n", cpuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static bool verify_vcpu(int vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (vcpu != -1 && vcpu < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) pr_err("Invalid vcpu:%d.\n", vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) #ifdef HAVE_TIMERFD_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /* keeping the max events to a modest level to keep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * the processing of samples per mmap smooth.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) #define PERF_KVM__MAX_EVENTS_PER_MMAP 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) u64 *mmap_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct evlist *evlist = kvm->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) union perf_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct mmap *md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) u64 timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) s64 n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) *mmap_time = ULLONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) md = &evlist->mmap[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) err = perf_mmap__read_init(&md->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return (err == -EAGAIN) ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) while ((event = perf_mmap__read_event(&md->core)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) err = perf_evlist__parse_sample_timestamp(evlist, event, ×tamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) perf_mmap__consume(&md->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) pr_err("Failed to parse sample\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) err = perf_session__queue_event(kvm->session, event, timestamp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * FIXME: Here we can't consume the event, as perf_session__queue_event will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * point to it, and it'll get possibly overwritten by the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) perf_mmap__consume(&md->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) pr_err("Failed to enqueue sample: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /* save time stamp of our first sample for this mmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (n == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) *mmap_time = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /* limit events per mmap handled all at once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (n == PERF_KVM__MAX_EVENTS_PER_MMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) perf_mmap__read_done(&md->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) int i, err, throttled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) s64 n, ntotal = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) u64 flush_time = ULLONG_MAX, mmap_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) for (i = 0; i < kvm->evlist->core.nr_mmaps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) n = perf_kvm__mmap_read_idx(kvm, i, &mmap_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /* flush time is going to be the minimum of all the individual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * mmap times. Essentially, we flush all the samples queued up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * from the last pass under our minimal start time -- that leaves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * a very small race for samples to come in with a lower timestamp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * The ioctl to return the perf_clock timestamp should close the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * race entirely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (mmap_time < flush_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) flush_time = mmap_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) ntotal += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (n == PERF_KVM__MAX_EVENTS_PER_MMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) throttled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) /* flush queue after each round in which we processed events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (ntotal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct ordered_events *oe = &kvm->session->ordered_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) oe->next_flush = flush_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) err = ordered_events__flush(oe, OE_FLUSH__ROUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (kvm->lost_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) pr_info("\nLost events: %" PRIu64 "\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) kvm->lost_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return throttled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static volatile int done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static void sig_handler(int sig __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct itimerspec new_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) int rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) kvm->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (kvm->timerfd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) pr_err("timerfd_create failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) new_value.it_value.tv_sec = kvm->display_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) new_value.it_value.tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) new_value.it_interval.tv_sec = kvm->display_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) new_value.it_interval.tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (timerfd_settime(kvm->timerfd, 0, &new_value, NULL) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) pr_err("timerfd_settime failed: %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) close(kvm->timerfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) static int perf_kvm__handle_timerfd(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) uint64_t c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) rc = read(kvm->timerfd, &c, sizeof(uint64_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (errno == EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) pr_err("Failed to read timer fd: %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (rc != sizeof(uint64_t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) pr_err("Error reading timer fd - invalid size returned\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (c != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) pr_debug("Missed timer beats: %" PRIu64 "\n", c-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /* update display */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) sort_result(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) print_result(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) /* reset counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) clear_events_cache_stats(kvm->kvm_events_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) kvm->total_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) kvm->total_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) kvm->lost_events = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) static int fd_set_nonblock(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) long arg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) arg = fcntl(fd, F_GETFL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (arg < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) pr_err("Failed to get current flags for fd %d\n", fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (fcntl(fd, F_SETFL, arg | O_NONBLOCK) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) pr_err("Failed to set non-block option on fd %d\n", fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) static int perf_kvm__handle_stdin(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) c = getc(stdin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (c == 'q')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) static int kvm_events_live_report(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) int nr_stdin, ret, err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) struct termios save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /* live flag must be set first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) kvm->live = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) ret = cpu_isa_config(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (!verify_vcpu(kvm->trace_vcpu) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) !select_key(kvm) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) !register_kvm_events_ops(kvm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) set_term_quiet_input(&save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) init_kvm_event_record(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) signal(SIGINT, sig_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) signal(SIGTERM, sig_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /* add timer fd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (perf_kvm__timerfd_create(kvm) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) nr_stdin = evlist__add_pollfd(kvm->evlist, fileno(stdin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (nr_stdin < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (fd_set_nonblock(fileno(stdin)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) /* everything is good - enable the events and process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) evlist__enable(kvm->evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) while (!done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct fdarray *fda = &kvm->evlist->core.pollfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) rc = perf_kvm__mmap_read(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) err = perf_kvm__handle_timerfd(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (fda->entries[nr_stdin].revents & POLLIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) done = perf_kvm__handle_stdin();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (!rc && !done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) err = evlist__poll(kvm->evlist, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) evlist__disable(kvm->evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) sort_result(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) print_result(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (kvm->timerfd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) close(kvm->timerfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) tcsetattr(0, TCSAFLUSH, &save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) static int kvm_live_open_events(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) int err, rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct evsel *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) struct evlist *evlist = kvm->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) char sbuf[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) perf_evlist__config(evlist, &kvm->opts, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * Note: exclude_{guest,host} do not apply here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) * This command processes KVM tracepoints from host only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) evlist__for_each_entry(evlist, pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) struct perf_event_attr *attr = &pos->core.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /* make sure these *are* set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) evsel__set_sample_bit(pos, TID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) evsel__set_sample_bit(pos, TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) evsel__set_sample_bit(pos, CPU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) evsel__set_sample_bit(pos, RAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /* make sure these are *not*; want as small a sample as possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) evsel__reset_sample_bit(pos, PERIOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) evsel__reset_sample_bit(pos, IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) evsel__reset_sample_bit(pos, CALLCHAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) evsel__reset_sample_bit(pos, ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) evsel__reset_sample_bit(pos, READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) attr->mmap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) attr->comm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) attr->task = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) attr->sample_period = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) attr->watermark = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) attr->wakeup_events = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) /* will enable all once we are ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) attr->disabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) err = evlist__open(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) printf("Couldn't create the events: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) str_error_r(errno, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) ui__error("Failed to mmap the events: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) str_error_r(errno, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) evlist__close(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) static int read_events(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) struct perf_tool eops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .sample = process_sample_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) .comm = perf_event__process_comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) .namespaces = perf_event__process_namespaces,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) .ordered_events = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct perf_data file = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) .path = kvm->file_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) .mode = PERF_DATA_MODE_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) .force = kvm->force,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) kvm->tool = eops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) kvm->session = perf_session__new(&file, false, &kvm->tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (IS_ERR(kvm->session)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) pr_err("Initializing perf session failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return PTR_ERR(kvm->session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) symbol__init(&kvm->session->header.env);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (!perf_session__has_traces(kvm->session, "kvm record")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) * Do not use 'isa' recorded in kvm_exit tracepoint since it is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * traced in the old kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ret = cpu_isa_config(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) goto out_delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) ret = perf_session__process_events(kvm->session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) out_delete:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) perf_session__delete(kvm->session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) static int parse_target_str(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (kvm->opts.target.pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) kvm->pid_list = intlist__new(kvm->opts.target.pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (kvm->pid_list == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) pr_err("Error parsing process id string\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) int vcpu = kvm->trace_vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (parse_target_str(kvm) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (!verify_vcpu(vcpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (!select_key(kvm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (!register_kvm_events_ops(kvm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) init_kvm_event_record(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) setup_pager();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) ret = read_events(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) sort_result(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) print_result(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) #define STRDUP_FAIL_EXIT(s) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) ({ char *_p; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) _p = strdup(s); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (!_p) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return -ENOMEM; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) _p; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) int __weak setup_kvm_events_tp(struct perf_kvm_stat *kvm __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) unsigned int rec_argc, i, j, events_tp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) const char **rec_argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) const char * const record_args[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) "record",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) "-R",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) "-m", "1024",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) "-c", "1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) const char * const kvm_stat_record_usage[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) "perf kvm stat record [<options>]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) const char * const *events_tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) events_tp_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) ret = setup_kvm_events_tp(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) pr_err("Unable to setup the kvm tracepoints\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) for (events_tp = kvm_events_tp; *events_tp; events_tp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) events_tp_size++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) rec_argc = ARRAY_SIZE(record_args) + argc + 2 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 2 * events_tp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) rec_argv = calloc(rec_argc + 1, sizeof(char *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (rec_argv == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) for (i = 0; i < ARRAY_SIZE(record_args); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) rec_argv[i] = STRDUP_FAIL_EXIT(record_args[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) for (j = 0; j < events_tp_size; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) rec_argv[i++] = "-e";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) rec_argv[i++] = STRDUP_FAIL_EXIT("-o");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) rec_argv[i++] = STRDUP_FAIL_EXIT(kvm->file_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) for (j = 1; j < (unsigned int)argc; j++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) rec_argv[i] = argv[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) set_option_flag(record_options, 'e', "event", PARSE_OPT_HIDDEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) set_option_flag(record_options, 0, "filter", PARSE_OPT_HIDDEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) set_option_flag(record_options, 'R', "raw-samples", PARSE_OPT_HIDDEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) set_option_flag(record_options, 'F', "freq", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) set_option_flag(record_options, 0, "group", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) set_option_flag(record_options, 'g', NULL, PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) set_option_flag(record_options, 0, "call-graph", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) set_option_flag(record_options, 'd', "data", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) set_option_flag(record_options, 'T', "timestamp", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) set_option_flag(record_options, 'P', "period", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) set_option_flag(record_options, 'n', "no-samples", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) set_option_flag(record_options, 'N', "no-buildid-cache", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) set_option_flag(record_options, 'B', "no-buildid", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) set_option_flag(record_options, 'G', "cgroup", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) set_option_flag(record_options, 'b', "branch-any", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) set_option_flag(record_options, 'j', "branch-filter", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) set_option_flag(record_options, 'W', "weight", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) set_option_flag(record_options, 0, "transaction", PARSE_OPT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) record_usage = kvm_stat_record_usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) return cmd_record(i, rec_argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) const struct option kvm_events_report_options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) OPT_STRING(0, "event", &kvm->report_event, "report event",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) "event for reporting: vmexit, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) "mmio (x86 only), ioport (x86 only)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) "vcpu id to report"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) "key for sorting: sample(sort by samples number)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) " time (sort by avg time)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) "analyze events only for given process id(s)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) OPT_BOOLEAN('f', "force", &kvm->force, "don't complain, do it"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) const char * const kvm_events_report_usage[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) "perf kvm stat report [<options>]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (argc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) argc = parse_options(argc, argv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) kvm_events_report_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) kvm_events_report_usage, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (argc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) usage_with_options(kvm_events_report_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) kvm_events_report_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (!kvm->opts.target.pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) kvm->opts.target.system_wide = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) return kvm_events_report_vcpu(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) #ifdef HAVE_TIMERFD_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) static struct evlist *kvm_live_event_list(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) struct evlist *evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) char *tp, *name, *sys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) int err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) const char * const *events_tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) evlist = evlist__new();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (evlist == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) for (events_tp = kvm_events_tp; *events_tp; events_tp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) tp = strdup(*events_tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) if (tp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) /* split tracepoint into subsystem and name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) sys = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) name = strchr(tp, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) pr_err("Error parsing %s tracepoint: subsystem delimiter not found\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) *events_tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) free(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) *name = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) name++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (evlist__add_newtp(evlist, sys, name, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) pr_err("Failed to add %s tracepoint to the list\n", *events_tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) free(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) free(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) evlist__delete(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) evlist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) static int kvm_events_live(struct perf_kvm_stat *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) char errbuf[BUFSIZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) const struct option live_options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) "record events on existing process id"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) OPT_CALLBACK('m', "mmap-pages", &kvm->opts.mmap_pages, "pages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) "number of mmap data pages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) perf_evlist__parse_mmap_pages),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) OPT_INCR('v', "verbose", &verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) "be more verbose (show counter open errors, etc)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) "system-wide collection from all CPUs"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) OPT_UINTEGER('d', "display", &kvm->display_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) "time in seconds between display updates"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) OPT_STRING(0, "event", &kvm->report_event, "report event",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) "event for reporting: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) "vmexit, mmio (x86 only), ioport (x86 only)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) "vcpu id to report"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) "key for sorting: sample(sort by samples number)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) " time (sort by avg time)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) OPT_U64(0, "duration", &kvm->duration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) "show events other than"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) " HLT (x86 only) or Wait state (s390 only)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) " that take longer than duration usecs"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) OPT_UINTEGER(0, "proc-map-timeout", &proc_map_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) "per thread proc mmap processing timeout in ms"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) const char * const live_usage[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) "perf kvm stat live [<options>]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) struct perf_data data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) .mode = PERF_DATA_MODE_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) /* event handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) kvm->tool.sample = process_sample_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) kvm->tool.comm = perf_event__process_comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) kvm->tool.exit = perf_event__process_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) kvm->tool.fork = perf_event__process_fork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) kvm->tool.lost = process_lost_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) kvm->tool.namespaces = perf_event__process_namespaces;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) kvm->tool.ordered_events = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) perf_tool__fill_defaults(&kvm->tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) /* set defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) kvm->display_time = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) kvm->opts.user_interval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) kvm->opts.mmap_pages = 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) kvm->opts.target.uses_mmap = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) kvm->opts.target.uid_str = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) kvm->opts.target.uid = UINT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) symbol__init(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) disable_buildid_cache();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) use_browser = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) if (argc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) argc = parse_options(argc, argv, live_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) live_usage, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) if (argc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) usage_with_options(live_usage, live_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) kvm->duration *= NSEC_PER_USEC; /* convert usec to nsec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) * target related setups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) err = target__validate(&kvm->opts.target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) ui__warning("%s", errbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) if (target__none(&kvm->opts.target))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) kvm->opts.target.system_wide = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) * generate the event list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) err = setup_kvm_events_tp(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) pr_err("Unable to setup the kvm tracepoints\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) kvm->evlist = kvm_live_event_list();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (kvm->evlist == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (perf_evlist__create_maps(kvm->evlist, &kvm->opts.target) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) usage_with_options(live_usage, live_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) * perf session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) kvm->session = perf_session__new(&data, false, &kvm->tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (IS_ERR(kvm->session)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) err = PTR_ERR(kvm->session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) kvm->session->evlist = kvm->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) perf_session__set_id_hdr_size(kvm->session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) kvm->evlist->core.threads, false, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) err = kvm_live_open_events(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) err = kvm_events_live_report(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) perf_session__delete(kvm->session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) kvm->session = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) evlist__delete(kvm->evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static void print_kvm_stat_usage(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) printf("Usage: perf kvm stat <command>\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) printf("# Available commands:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) printf("\trecord: record kvm events\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) printf("\treport: report statistical data of kvm events\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) printf("\tlive: live reporting of statistical data of kvm events\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) printf("\nOtherwise, it is the alias of 'perf stat':\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) struct perf_kvm_stat kvm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) .file_name = file_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) .trace_vcpu = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) .report_event = "vmexit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) .sort_key = "sample",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (argc == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) print_kvm_stat_usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) goto perf_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (!strncmp(argv[1], "rec", 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) return kvm_events_record(&kvm, argc - 1, argv + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (!strncmp(argv[1], "rep", 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) return kvm_events_report(&kvm, argc - 1 , argv + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) #ifdef HAVE_TIMERFD_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) if (!strncmp(argv[1], "live", 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) return kvm_events_live(&kvm, argc - 1 , argv + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) perf_stat:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) return cmd_stat(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) #endif /* HAVE_KVM_STAT_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) int __weak kvm_add_default_arch_event(int *argc __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) const char **argv __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) static int __cmd_record(const char *file_name, int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) int rec_argc, i = 0, j, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) const char **rec_argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) ret = kvm_add_default_arch_event(&argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) rec_argc = argc + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) rec_argv = calloc(rec_argc + 1, sizeof(char *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) rec_argv[i++] = strdup("record");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) rec_argv[i++] = strdup("-o");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) rec_argv[i++] = strdup(file_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) for (j = 1; j < argc; j++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) rec_argv[i] = argv[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) BUG_ON(i != rec_argc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) return cmd_record(i, rec_argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) static int __cmd_report(const char *file_name, int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) int rec_argc, i = 0, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) const char **rec_argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) rec_argc = argc + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) rec_argv = calloc(rec_argc + 1, sizeof(char *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) rec_argv[i++] = strdup("report");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) rec_argv[i++] = strdup("-i");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) rec_argv[i++] = strdup(file_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) for (j = 1; j < argc; j++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) rec_argv[i] = argv[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) BUG_ON(i != rec_argc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) return cmd_report(i, rec_argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) __cmd_buildid_list(const char *file_name, int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) int rec_argc, i = 0, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) const char **rec_argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) rec_argc = argc + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) rec_argv = calloc(rec_argc + 1, sizeof(char *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) rec_argv[i++] = strdup("buildid-list");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) rec_argv[i++] = strdup("-i");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) rec_argv[i++] = strdup(file_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) for (j = 1; j < argc; j++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) rec_argv[i] = argv[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) BUG_ON(i != rec_argc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return cmd_buildid_list(i, rec_argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) int cmd_kvm(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) const char *file_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) const struct option kvm_options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) OPT_STRING('i', "input", &file_name, "file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) "Input file name"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) OPT_STRING('o', "output", &file_name, "file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) "Output file name"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) OPT_BOOLEAN(0, "guest", &perf_guest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) "Collect guest os data"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) OPT_BOOLEAN(0, "host", &perf_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) "Collect host os data"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) "guest mount directory under which every guest os"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) " instance has a subdir"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) "file", "file saving guest os vmlinux"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) "file", "file saving guest os /proc/kallsyms"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) "file", "file saving guest os /proc/modules"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) OPT_INCR('v', "verbose", &verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) "be more verbose (show counter open errors, etc)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) const char *const kvm_subcommands[] = { "top", "record", "report", "diff",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) "buildid-list", "stat", NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) const char *kvm_usage[] = { NULL, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) perf_host = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) perf_guest = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) argc = parse_options_subcommand(argc, argv, kvm_options, kvm_subcommands, kvm_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) PARSE_OPT_STOP_AT_NON_OPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) if (!argc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) usage_with_options(kvm_usage, kvm_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (!perf_host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) perf_guest = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (!file_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) file_name = get_filename_for_perf_kvm();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (!file_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) pr_err("Failed to allocate memory for filename\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (!strncmp(argv[0], "rec", 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) return __cmd_record(file_name, argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) else if (!strncmp(argv[0], "rep", 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) return __cmd_report(file_name, argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) else if (!strncmp(argv[0], "diff", 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) return cmd_diff(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) else if (!strncmp(argv[0], "top", 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) return cmd_top(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) else if (!strncmp(argv[0], "buildid-list", 12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) return __cmd_buildid_list(file_name, argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) #ifdef HAVE_KVM_STAT_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) else if (!strncmp(argv[0], "stat", 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) return kvm_cmd_stat(file_name, argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) usage_with_options(kvm_usage, kvm_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }