diff options
-rw-r--r-- | arch/x86/include/uapi/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/x86/include/uapi/asm/kvm_perf.h | 16 | ||||
-rw-r--r-- | tools/perf/MANIFEST | 1 | ||||
-rw-r--r-- | tools/perf/builtin-kvm.c | 34 |
4 files changed, 34 insertions, 18 deletions
diff --git a/arch/x86/include/uapi/asm/Kbuild b/arch/x86/include/uapi/asm/Kbuild index 09409c44f9a5..3dec769cadf7 100644 --- a/arch/x86/include/uapi/asm/Kbuild +++ b/arch/x86/include/uapi/asm/Kbuild | |||
@@ -22,6 +22,7 @@ header-y += ipcbuf.h | |||
22 | header-y += ist.h | 22 | header-y += ist.h |
23 | header-y += kvm.h | 23 | header-y += kvm.h |
24 | header-y += kvm_para.h | 24 | header-y += kvm_para.h |
25 | header-y += kvm_perf.h | ||
25 | header-y += ldt.h | 26 | header-y += ldt.h |
26 | header-y += mce.h | 27 | header-y += mce.h |
27 | header-y += mman.h | 28 | header-y += mman.h |
diff --git a/arch/x86/include/uapi/asm/kvm_perf.h b/arch/x86/include/uapi/asm/kvm_perf.h new file mode 100644 index 000000000000..3bb964f88aa1 --- /dev/null +++ b/arch/x86/include/uapi/asm/kvm_perf.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef _ASM_X86_KVM_PERF_H | ||
2 | #define _ASM_X86_KVM_PERF_H | ||
3 | |||
4 | #include <asm/svm.h> | ||
5 | #include <asm/vmx.h> | ||
6 | #include <asm/kvm.h> | ||
7 | |||
8 | #define DECODE_STR_LEN 20 | ||
9 | |||
10 | #define VCPU_ID "vcpu_id" | ||
11 | |||
12 | #define KVM_ENTRY_TRACE "kvm:kvm_entry" | ||
13 | #define KVM_EXIT_TRACE "kvm:kvm_exit" | ||
14 | #define KVM_EXIT_REASON "exit_reason" | ||
15 | |||
16 | #endif /* _ASM_X86_KVM_PERF_H */ | ||
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 45da209b6ed3..02b485d619cd 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
@@ -37,3 +37,4 @@ arch/x86/include/asm/kvm_host.h | |||
37 | arch/x86/include/uapi/asm/svm.h | 37 | arch/x86/include/uapi/asm/svm.h |
38 | arch/x86/include/uapi/asm/vmx.h | 38 | arch/x86/include/uapi/asm/vmx.h |
39 | arch/x86/include/uapi/asm/kvm.h | 39 | arch/x86/include/uapi/asm/kvm.h |
40 | arch/x86/include/uapi/asm/kvm_perf.h | ||
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 41dbeaf8cc11..6d73346ef2a6 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
@@ -30,9 +30,7 @@ | |||
30 | #include <math.h> | 30 | #include <math.h> |
31 | 31 | ||
32 | #ifdef HAVE_KVM_STAT_SUPPORT | 32 | #ifdef HAVE_KVM_STAT_SUPPORT |
33 | #include <asm/svm.h> | 33 | #include <asm/kvm_perf.h> |
34 | #include <asm/vmx.h> | ||
35 | #include <asm/kvm.h> | ||
36 | 34 | ||
37 | struct event_key { | 35 | struct event_key { |
38 | #define INVALID_KEY (~0ULL) | 36 | #define INVALID_KEY (~0ULL) |
@@ -75,7 +73,7 @@ struct kvm_events_ops { | |||
75 | bool (*is_end_event)(struct perf_evsel *evsel, | 73 | bool (*is_end_event)(struct perf_evsel *evsel, |
76 | struct perf_sample *sample, struct event_key *key); | 74 | struct perf_sample *sample, struct event_key *key); |
77 | void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key, | 75 | void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key, |
78 | char decode[20]); | 76 | char *decode); |
79 | const char *name; | 77 | const char *name; |
80 | }; | 78 | }; |
81 | 79 | ||
@@ -126,12 +124,12 @@ static void exit_event_get_key(struct perf_evsel *evsel, | |||
126 | struct event_key *key) | 124 | struct event_key *key) |
127 | { | 125 | { |
128 | key->info = 0; | 126 | key->info = 0; |
129 | key->key = perf_evsel__intval(evsel, sample, "exit_reason"); | 127 | key->key = perf_evsel__intval(evsel, sample, KVM_EXIT_REASON); |
130 | } | 128 | } |
131 | 129 | ||
132 | static bool kvm_exit_event(struct perf_evsel *evsel) | 130 | static bool kvm_exit_event(struct perf_evsel *evsel) |
133 | { | 131 | { |
134 | return !strcmp(evsel->name, "kvm:kvm_exit"); | 132 | return !strcmp(evsel->name, KVM_EXIT_TRACE); |
135 | } | 133 | } |
136 | 134 | ||
137 | static bool exit_event_begin(struct perf_evsel *evsel, | 135 | static bool exit_event_begin(struct perf_evsel *evsel, |
@@ -147,7 +145,7 @@ static bool exit_event_begin(struct perf_evsel *evsel, | |||
147 | 145 | ||
148 | static bool kvm_entry_event(struct perf_evsel *evsel) | 146 | static bool kvm_entry_event(struct perf_evsel *evsel) |
149 | { | 147 | { |
150 | return !strcmp(evsel->name, "kvm:kvm_entry"); | 148 | return !strcmp(evsel->name, KVM_ENTRY_TRACE); |
151 | } | 149 | } |
152 | 150 | ||
153 | static bool exit_event_end(struct perf_evsel *evsel, | 151 | static bool exit_event_end(struct perf_evsel *evsel, |
@@ -182,12 +180,12 @@ static const char *get_exit_reason(struct perf_kvm_stat *kvm, | |||
182 | 180 | ||
183 | static void exit_event_decode_key(struct perf_kvm_stat *kvm, | 181 | static void exit_event_decode_key(struct perf_kvm_stat *kvm, |
184 | struct event_key *key, | 182 | struct event_key *key, |
185 | char decode[20]) | 183 | char *decode) |
186 | { | 184 | { |
187 | const char *exit_reason = get_exit_reason(kvm, kvm->exit_reasons, | 185 | const char *exit_reason = get_exit_reason(kvm, kvm->exit_reasons, |
188 | key->key); | 186 | key->key); |
189 | 187 | ||
190 | scnprintf(decode, 20, "%s", exit_reason); | 188 | scnprintf(decode, DECODE_STR_LEN, "%s", exit_reason); |
191 | } | 189 | } |
192 | 190 | ||
193 | static struct kvm_events_ops exit_events = { | 191 | static struct kvm_events_ops exit_events = { |
@@ -249,9 +247,9 @@ static bool mmio_event_end(struct perf_evsel *evsel, struct perf_sample *sample, | |||
249 | 247 | ||
250 | static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, | 248 | static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, |
251 | struct event_key *key, | 249 | struct event_key *key, |
252 | char decode[20]) | 250 | char *decode) |
253 | { | 251 | { |
254 | scnprintf(decode, 20, "%#lx:%s", (unsigned long)key->key, | 252 | scnprintf(decode, DECODE_STR_LEN, "%#lx:%s", (unsigned long)key->key, |
255 | key->info == KVM_TRACE_MMIO_WRITE ? "W" : "R"); | 253 | key->info == KVM_TRACE_MMIO_WRITE ? "W" : "R"); |
256 | } | 254 | } |
257 | 255 | ||
@@ -292,9 +290,9 @@ static bool ioport_event_end(struct perf_evsel *evsel, | |||
292 | 290 | ||
293 | static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, | 291 | static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, |
294 | struct event_key *key, | 292 | struct event_key *key, |
295 | char decode[20]) | 293 | char *decode) |
296 | { | 294 | { |
297 | scnprintf(decode, 20, "%#llx:%s", (unsigned long long)key->key, | 295 | scnprintf(decode, DECODE_STR_LEN, "%#llx:%s", (unsigned long long)key->key, |
298 | key->info ? "POUT" : "PIN"); | 296 | key->info ? "POUT" : "PIN"); |
299 | } | 297 | } |
300 | 298 | ||
@@ -524,7 +522,7 @@ static bool handle_end_event(struct perf_kvm_stat *kvm, | |||
524 | time_diff = sample->time - time_begin; | 522 | time_diff = sample->time - time_begin; |
525 | 523 | ||
526 | if (kvm->duration && time_diff > kvm->duration) { | 524 | if (kvm->duration && time_diff > kvm->duration) { |
527 | char decode[32]; | 525 | char decode[DECODE_STR_LEN]; |
528 | 526 | ||
529 | kvm->events_ops->decode_key(kvm, &event->key, decode); | 527 | kvm->events_ops->decode_key(kvm, &event->key, decode); |
530 | if (strcmp(decode, "HLT")) { | 528 | if (strcmp(decode, "HLT")) { |
@@ -552,7 +550,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread, | |||
552 | return NULL; | 550 | return NULL; |
553 | } | 551 | } |
554 | 552 | ||
555 | vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, "vcpu_id"); | 553 | vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, VCPU_ID); |
556 | thread->priv = vcpu_record; | 554 | thread->priv = vcpu_record; |
557 | } | 555 | } |
558 | 556 | ||
@@ -739,7 +737,7 @@ static void show_timeofday(void) | |||
739 | 737 | ||
740 | static void print_result(struct perf_kvm_stat *kvm) | 738 | static void print_result(struct perf_kvm_stat *kvm) |
741 | { | 739 | { |
742 | char decode[20]; | 740 | char decode[DECODE_STR_LEN]; |
743 | struct kvm_event *event; | 741 | struct kvm_event *event; |
744 | int vcpu = kvm->trace_vcpu; | 742 | int vcpu = kvm->trace_vcpu; |
745 | 743 | ||
@@ -750,7 +748,7 @@ static void print_result(struct perf_kvm_stat *kvm) | |||
750 | 748 | ||
751 | pr_info("\n\n"); | 749 | pr_info("\n\n"); |
752 | print_vcpu_info(kvm); | 750 | print_vcpu_info(kvm); |
753 | pr_info("%20s ", kvm->events_ops->name); | 751 | pr_info("%*s ", DECODE_STR_LEN, kvm->events_ops->name); |
754 | pr_info("%10s ", "Samples"); | 752 | pr_info("%10s ", "Samples"); |
755 | pr_info("%9s ", "Samples%"); | 753 | pr_info("%9s ", "Samples%"); |
756 | 754 | ||
@@ -769,7 +767,7 @@ static void print_result(struct perf_kvm_stat *kvm) | |||
769 | min = get_event_min(event, vcpu); | 767 | min = get_event_min(event, vcpu); |
770 | 768 | ||
771 | kvm->events_ops->decode_key(kvm, &event->key, decode); | 769 | kvm->events_ops->decode_key(kvm, &event->key, decode); |
772 | pr_info("%20s ", decode); | 770 | pr_info("%*s ", DECODE_STR_LEN, decode); |
773 | pr_info("%10llu ", (unsigned long long)ecount); | 771 | pr_info("%10llu ", (unsigned long long)ecount); |
774 | pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100); | 772 | pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100); |
775 | pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100); | 773 | pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100); |