1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __PERF_KVM_STAT_H |
3 | #define __PERF_KVM_STAT_H |
4 | |
5 | #ifdef HAVE_KVM_STAT_SUPPORT |
6 | |
7 | #include "tool.h" |
8 | #include "sort.h" |
9 | #include "stat.h" |
10 | #include "symbol.h" |
11 | #include "record.h" |
12 | |
13 | #include <stdlib.h> |
14 | #include <linux/zalloc.h> |
15 | |
16 | #define KVM_EVENT_NAME_LEN 40 |
17 | |
18 | struct evsel; |
19 | struct evlist; |
20 | struct perf_session; |
21 | |
22 | struct event_key { |
23 | #define INVALID_KEY (~0ULL) |
24 | u64 key; |
25 | int info; |
26 | struct exit_reasons_table *exit_reasons; |
27 | }; |
28 | |
29 | struct kvm_info { |
30 | char name[KVM_EVENT_NAME_LEN]; |
31 | refcount_t refcnt; |
32 | }; |
33 | |
34 | struct kvm_event_stats { |
35 | u64 time; |
36 | struct stats stats; |
37 | }; |
38 | |
39 | struct perf_kvm_stat; |
40 | |
41 | struct kvm_event { |
42 | struct list_head hash_entry; |
43 | |
44 | struct perf_kvm_stat *perf_kvm; |
45 | struct event_key key; |
46 | |
47 | struct kvm_event_stats total; |
48 | |
49 | #define DEFAULT_VCPU_NUM 8 |
50 | int max_vcpu; |
51 | struct kvm_event_stats *vcpu; |
52 | |
53 | struct hist_entry he; |
54 | }; |
55 | |
56 | struct child_event_ops { |
57 | void (*get_key)(struct evsel *evsel, |
58 | struct perf_sample *sample, |
59 | struct event_key *key); |
60 | const char *name; |
61 | }; |
62 | |
63 | struct kvm_events_ops { |
64 | bool (*is_begin_event)(struct evsel *evsel, |
65 | struct perf_sample *sample, |
66 | struct event_key *key); |
67 | bool (*is_end_event)(struct evsel *evsel, |
68 | struct perf_sample *sample, struct event_key *key); |
69 | struct child_event_ops *child_ops; |
70 | void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key, |
71 | char *decode); |
72 | const char *name; |
73 | }; |
74 | |
75 | struct exit_reasons_table { |
76 | unsigned long exit_code; |
77 | const char *reason; |
78 | }; |
79 | |
80 | struct perf_kvm_stat { |
81 | struct perf_tool tool; |
82 | struct record_opts opts; |
83 | struct evlist *evlist; |
84 | struct perf_session *session; |
85 | |
86 | const char *file_name; |
87 | const char *report_event; |
88 | const char *sort_key; |
89 | int trace_vcpu; |
90 | |
91 | /* Used when process events */ |
92 | struct addr_location al; |
93 | |
94 | struct exit_reasons_table *exit_reasons; |
95 | const char *exit_reasons_isa; |
96 | |
97 | struct kvm_events_ops *events_ops; |
98 | |
99 | u64 total_time; |
100 | u64 total_count; |
101 | u64 lost_events; |
102 | u64 duration; |
103 | |
104 | struct intlist *pid_list; |
105 | |
106 | int timerfd; |
107 | unsigned int display_time; |
108 | bool live; |
109 | bool force; |
110 | bool use_stdio; |
111 | }; |
112 | |
113 | struct kvm_reg_events_ops { |
114 | const char *name; |
115 | struct kvm_events_ops *ops; |
116 | }; |
117 | |
118 | void exit_event_get_key(struct evsel *evsel, |
119 | struct perf_sample *sample, |
120 | struct event_key *key); |
121 | bool exit_event_begin(struct evsel *evsel, |
122 | struct perf_sample *sample, |
123 | struct event_key *key); |
124 | bool exit_event_end(struct evsel *evsel, |
125 | struct perf_sample *sample, |
126 | struct event_key *key); |
127 | void exit_event_decode_key(struct perf_kvm_stat *kvm, |
128 | struct event_key *key, |
129 | char *decode); |
130 | |
131 | bool kvm_exit_event(struct evsel *evsel); |
132 | bool kvm_entry_event(struct evsel *evsel); |
133 | int setup_kvm_events_tp(struct perf_kvm_stat *kvm); |
134 | |
135 | #define define_exit_reasons_table(name, symbols) \ |
136 | static struct exit_reasons_table name[] = { \ |
137 | symbols, { -1, NULL } \ |
138 | } |
139 | |
140 | /* |
141 | * arch specific callbacks and data structures |
142 | */ |
143 | int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid); |
144 | |
145 | extern const char *kvm_events_tp[]; |
146 | extern struct kvm_reg_events_ops kvm_reg_events_ops[]; |
147 | extern const char * const kvm_skip_events[]; |
148 | extern const char *vcpu_id_str; |
149 | extern const char *kvm_exit_reason; |
150 | extern const char *kvm_entry_trace; |
151 | extern const char *kvm_exit_trace; |
152 | |
153 | static inline struct kvm_info *kvm_info__get(struct kvm_info *ki) |
154 | { |
155 | if (ki) |
156 | refcount_inc(&ki->refcnt); |
157 | return ki; |
158 | } |
159 | |
160 | static inline void kvm_info__put(struct kvm_info *ki) |
161 | { |
162 | if (ki && refcount_dec_and_test(&ki->refcnt)) |
163 | free(ki); |
164 | } |
165 | |
166 | static inline void __kvm_info__zput(struct kvm_info **ki) |
167 | { |
168 | kvm_info__put(*ki); |
169 | *ki = NULL; |
170 | } |
171 | |
172 | #define kvm_info__zput(ki) __kvm_info__zput(&ki) |
173 | |
174 | static inline struct kvm_info *kvm_info__new(void) |
175 | { |
176 | struct kvm_info *ki; |
177 | |
178 | ki = zalloc(sizeof(*ki)); |
179 | if (ki) |
180 | refcount_set(&ki->refcnt, 1); |
181 | |
182 | return ki; |
183 | } |
184 | |
185 | #else /* HAVE_KVM_STAT_SUPPORT */ |
186 | // We use this unconditionally in hists__findnew_entry() and hist_entry__delete() |
187 | #define kvm_info__zput(ki) do { } while (0) |
188 | #endif /* HAVE_KVM_STAT_SUPPORT */ |
189 | |
190 | extern int kvm_add_default_arch_event(int *argc, const char **argv); |
191 | #endif /* __PERF_KVM_STAT_H */ |
192 | |