^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) #ifndef __PERF_KVM_STAT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __PERF_KVM_STAT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #ifdef HAVE_KVM_STAT_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "tool.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "stat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "record.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) struct evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) struct evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct perf_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct event_key {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define INVALID_KEY (~0ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) u64 key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) int info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct exit_reasons_table *exit_reasons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct kvm_event_stats {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) u64 time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct stats stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct kvm_event {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct list_head hash_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct rb_node rb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct event_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct kvm_event_stats total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define DEFAULT_VCPU_NUM 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int max_vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct kvm_event_stats *vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) typedef int (*key_cmp_fun)(struct kvm_event*, struct kvm_event*, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct kvm_event_key {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) key_cmp_fun key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct perf_kvm_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct child_event_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void (*get_key)(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct event_key *key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct kvm_events_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) bool (*is_begin_event)(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct event_key *key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) bool (*is_end_event)(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct perf_sample *sample, struct event_key *key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct child_event_ops *child_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) char *decode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct exit_reasons_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned long exit_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) const char *reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define EVENTS_BITS 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define EVENTS_CACHE_SIZE (1UL << EVENTS_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct perf_kvm_stat {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct perf_tool tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct record_opts opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct evlist *evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct perf_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) const char *file_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) const char *report_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const char *sort_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int trace_vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct exit_reasons_table *exit_reasons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) const char *exit_reasons_isa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct kvm_events_ops *events_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) key_cmp_fun compare;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct list_head kvm_events_cache[EVENTS_CACHE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) u64 total_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u64 total_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) u64 lost_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) u64 duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct intlist *pid_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct rb_root result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int timerfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) unsigned int display_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) bool live;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) bool force;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct kvm_reg_events_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct kvm_events_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) void exit_event_get_key(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct event_key *key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) bool exit_event_begin(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct event_key *key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) bool exit_event_end(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct event_key *key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) void exit_event_decode_key(struct perf_kvm_stat *kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct event_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) char *decode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) bool kvm_exit_event(struct evsel *evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) bool kvm_entry_event(struct evsel *evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int setup_kvm_events_tp(struct perf_kvm_stat *kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define define_exit_reasons_table(name, symbols) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static struct exit_reasons_table name[] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) symbols, { -1, NULL } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * arch specific callbacks and data structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) extern const char *kvm_events_tp[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) extern struct kvm_reg_events_ops kvm_reg_events_ops[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) extern const char * const kvm_skip_events[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) extern const char *vcpu_id_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) extern const int decode_str_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) extern const char *kvm_exit_reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) extern const char *kvm_entry_trace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) extern const char *kvm_exit_trace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #endif /* HAVE_KVM_STAT_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) extern int kvm_add_default_arch_event(int *argc, const char **argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #endif /* __PERF_KVM_STAT_H */