KVM: perf: a smart tool to analyse kvm events
Subsystems (5)
RFC PATCH 1/1 KVM: perf: a smart tool to analyse kvm events
This tool is very like xenoprof(if i remember correctly), and traces kvm events smartly. currently, it supports vmexit/mmio/ioport events.
Usage:
- to trace kvm events:
# ./perf kvm-events record
- show the result
# ./perf kvm-events report
Some output are as follow:
# ./perf kvm-events report Warning: Error: expected type 5 but read 4 Warning: Error: expected type 5 but read 0 Warning: unknown op '}'
Analyze events for all VCPUs:
VM-EXIT Samples Samples% Time% Avg time
APIC_ACCESS 438107 44.89% 6.20% 17.91us
EXTERNAL_INTERRUPT 219226 22.46% 8.01% 46.20us
IO_INSTRUCTION 122651 12.57% 1.88% 19.44us
EPT_VIOLATION 83110 8.52% 1.36% 20.75us
PENDING_INTERRUPT 37055 3.80% 0.16% 5.38us
CPUID 32718 3.35% 0.08% 3.15us
EXCEPTION_NMI 23601 2.42% 0.17% 8.87us
HLT 15424 1.58% 82.12% 6735.06us
CR_ACCESS 4089 0.42% 0.02% 6.08usTotal Samples:975981, Total events handled time:126502464.88us.
The default event to be analysed is vmexit, we can use --event to specify it, for example, if we want to trace mmio event:
# ./perf kvm-events report --event mmio Warning: Error: expected type 5 but read 4 Warning: Error: expected type 5 but read 0 Warning: unknown op '}'
Analyze events for all VCPUs:
MMIO Access Samples Samples% Time% Avg time
0xfee00380:W 196589 64.95% 70.01% 3.83us
0xfee00310:W 35356 11.68% 6.48% 1.97us
0xfee00300:W 35356 11.68% 16.37% 4.97us
0xfee00300:R 35356 11.68% 7.14% 2.17usTotal Samples:302657, Total events handled time:1074746.01us.
We can use --vcpu to specify which vcpu is traced:
root@localhost perf]# ./perf kvm-events report --event mmio --vcpu 1
Warning: Error: expected type 5 but read 4
Warning: Error: expected type 5 but read 0
Warning: unknown op '}'
Analyze events for VCPU 1:
MMIO Access Samples Samples% Time% Avg time
0xfee00380:W 58041 71.20% 74.90% 3.70us
0xfee00310:W 7826 9.60% 5.28% 1.93us
0xfee00300:W 7826 9.60% 13.82% 5.06us
0xfee00300:R 7826 9.60% 6.01% 2.20usTotal Samples:81519, Total events handled time:286577.81us.
And, '--key' is used to sort the result, the possible value sample (default, the result is sorted by samples number), time(the result is sorted by time%):
# ./perf kvm-events report --key time Warning: Error: expected type 5 but read 4 Warning: Error: expected type 5 but read 0 Warning: unknown op '}'
Analyze events for all VCPUs:
VM-EXIT Samples Samples% Time% Avg time
HLT 15424 1.58% 82.12% 6735.06us
EXTERNAL_INTERRUPT 219226 22.46% 8.01% 46.20us
APIC_ACCESS 438107 44.89% 6.20% 17.91us
IO_INSTRUCTION 122651 12.57% 1.88% 19.44us
EPT_VIOLATION 83110 8.52% 1.36% 20.75us
EXCEPTION_NMI 23601 2.42% 0.17% 8.87us
PENDING_INTERRUPT 37055 3.80% 0.16% 5.38us
CPUID 32718 3.35% 0.08% 3.15us
CR_ACCESS 4089 0.42% 0.02% 6.08usTotal Samples:975981, Total events handled time:126502464.88us.
I hope guys will like it and any comments are welcome! :)
PATCH 1/3 KVM: trace mmio read event properly
In current code, we use KVM_TRACE_MMIO_READ to trace mmio read event which only can be completed immediately, instead of it, we trace the time when read event occur, then cooperate with then later patch, we can know the time of mmio read emulation
--- arch/x86/kvm/x86.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-)
arch/x86/kvm/x86.c +2 -4
@@ -3432,7 +3432,6 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v) !kvm_iodevice_read(&vcpu->arch.apic->dev, addr, n, v)) && kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, addr, n, v))break ; -trace_kvm_mmio (KVM_TRACE_MMIO_READ , n, addr, *(u64 *)v); handled += n; addr += n; len -= n;
@@ -3658,8 +3657,6 @@ static int read_prepare(struct kvm_vcpu *vcpu, void *val, int bytes) {if (vcpu->mmio_read_completed) {memcpy (val, vcpu->mmio_data, bytes); -trace_kvm_mmio (KVM_TRACE_MMIO_READ , bytes, - vcpu->mmio_phys_addr, *(u64 *)val); vcpu->mmio_read_completed =0 ;return 1 ; }
@@ -3681,7 +3678,6 @@ static int write_emulate(struct kvm_vcpu *vcpu, gpa_t gpa,static int write_mmio (struct kvm_vcpu *vcpu,gpa_t gpa,int bytes,void *val) { -trace_kvm_mmio (KVM_TRACE_MMIO_WRITE , bytes, gpa, *(u64 *)val);return vcpu_mmio_write (vcpu, gpa, bytes, val); }
@@ -3744,6 +3740,8 @@ mmio:/* * Is this MMIO handled locally? */ +trace_kvm_mmio (write ?KVM_TRACE_MMIO_WRITE :KVM_TRACE_MMIO_READ , + bytes, gpa, *(u64 *)val); handled = ops->read_write_mmio (vcpu, gpa, bytes, val);if (handled == bytes)return X86EMUL_CONTINUE ;
Signature · 1 line
1.7.7.5
Re: [PATCH 1/3] KVM: trace mmio read event properly
arch/x86/kvm/x86.c mmio: · line 3743
Quoted 10 lines · Xiao Guangrong
In current code, we use
KVM_TRACE_MMIO_READto trace mmio read event which only can be completed immediately, instead of it, we trace the time when read event occur, then cooperate with then later patch, we can know the time of mmio read emulationarch/x86/kvm/x86.c +1
-0@@ -3744,6 +3740,8 @@ mmio:/* * Is this MMIO handled locally? */ + trace_kvm_mmio(write ? KVM_TRACE_MMIO_WRITE : KVM_TRACE_MMIO_READ,
It's better to push the conditional to the trace event itself, so it's only evaluated if tracing is enabled.
arch/x86/kvm/x86.c mmio: · line 3744
Quoted 1 line
arch/x86/kvm/x86.c +1
-0+ bytes, gpa, *(u64 *)val);
We get the wrong value for reads here, no?
Can't we leave the code as is, and infer the start of the event from the last kvm_exit trace?
Quoted 3 lines
arch/x86/kvm/x86.c +0
-0handled = ops->read_write_mmio (vcpu, gpa, bytes, val);if (handled == bytes)return X86EMUL_CONTINUE ;
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [PATCH 1/3] KVM: trace mmio read event properly
Quoted 6 lines · Avi Kivity
Quoted 5 lines · Xiao Guangrong
In current code, we use
KVM_TRACE_MMIO_READto trace mmio read event which only can be completed immediately, instead of it, we trace the time when read event occur, then cooperate with then later patch, we can know the time of mmio read emulation
Quoted 9 lines
arch/x86/kvm/x86.c mmio: · line 3743
Quoted 5 lines
arch/x86/kvm/x86.c +1
-0@@ -3744,6 +3740,8 @@ mmio:/* * Is this MMIO handled locally? */ + trace_kvm_mmio(write ? KVM_TRACE_MMIO_WRITE : KVM_TRACE_MMIO_READ,It's better to push the conditional to the trace event itself, so it's only evaluated if tracing is enabled.
Yes.
Quoted 4 lines
arch/x86/kvm/x86.c mmio: · line 3744
Quoted 1 line
arch/x86/kvm/x86.c +1
-0+ bytes, gpa, *(u64 *)val);We get the wrong value for reads here, no?
Yes, the value is meaningless in this point.
Quoted 2 lines
Can't we leave the code as is, and infer the start of the event from the last
kvm_exittrace?
Yes, we can do it, but the same problems is we need trace vcpu id to get its vmexit, i will do it in the next version if you like this way :)
PATCH 2/3 KVM: improve trace events of vmexit/mmio/ioport
In reply to Xiao Guangrong- trace vcpu_id for these events
- add kvm_mmio_done to trace the time when mmio/ioport emulation is completed
--- arch/x86/kvm/trace.h | 33 ++++++++++++++++++++++++++------- arch/x86/kvm/x86.c | 19 +++++++++++++------ include/trace/events/kvm.h | 32 +++++++++++++++++++++++++------- 3 files changed, 64 insertions(+), 20 deletions(-)
arch/x86/kvm/trace.h +26 -7
@@ -91,11 +91,12 @@ TRACE_EVENT(kvm_hv_hypercall,* Tracepoint for PIO. */ TRACE_EVENT(kvm_pio, - TP_PROTO(unsigned int rw, unsigned int port, unsigned int size, - unsigned int count), - TP_ARGS(rw, port, size, count), + TP_PROTO(unsigned int vcpu_id, unsigned int rw, unsigned int port, + unsigned int size, unsigned int count), + TP_ARGS(vcpu_id, rw, port, size, count), TP_STRUCT__entry( + __field( unsigned int, vcpu_id ) __field( unsigned int, rw ) __field( unsigned int, port ) __field( unsigned int, size )
@@ -103,17 +104,33 @@ TRACE_EVENT(kvm_pio, ), TP_fast_assign( + __entry->vcpu_id = vcpu_id; __entry->rw = rw; __entry->port = port; __entry->size = size; __entry->count = count; ), -TP_printk ("pio_%s at 0x%x size %d count %d" , - __entry->rw ?"write" :"read" , +TP_printk ("vcpu %u pio_%s at 0x%x size %d count %d" , + __entry->vcpu_id, __entry->rw ?"write" :"read" , __entry->port, __entry->size, __entry->count) ); +TRACE_EVENT (kvm_pio_done, + TP_PROTO(unsigned int vcpu_id), +TP_ARGS (vcpu_id), + +TP_STRUCT__entry ( + __field( unsigned int, vcpu_id ) + ), + +TP_fast_assign ( + __entry->vcpu_id = vcpu_id; + ), + +TP_printk ("vcpu %u" , __entry->vcpu_id) +); +/* * Tracepoint for cpuid. */
@@ -280,6 +297,7 @@ TRACE_EVENT(kvm_exit,TP_ARGS (exit_reason, vcpu, isa),TP_STRUCT__entry ( + __field( unsigned int, vcpu_id ) __field( unsigned int, exit_reason ) __field( unsigned long, guest_rip ) __field( u32, isa )
@@ -288,6 +306,7 @@ TRACE_EVENT(kvm_exit, ), TP_fast_assign( + __entry->vcpu_id = vcpu->vcpu_id; __entry->exit_reason = exit_reason; __entry->guest_rip =kvm_rip_read (vcpu); __entry->isa = isa;
@@ -295,8 +314,8 @@ TRACE_EVENT(kvm_exit, &__entry->info2); ), -TP_printk ("reason %s rip 0x%lx info %llx %llx" , - (__entry->isa ==KVM_ISA_VMX ) ? +TP_printk ("vcpu %u reason %s rip 0x%lx info %llx %llx" , + __entry->vcpu_id, (__entry->isa ==KVM_ISA_VMX ) ?__print_symbolic (__entry->exit_reason,VMX_EXIT_REASONS ) :__print_symbolic (__entry->exit_reason,SVM_EXIT_REASONS ), __entry->guest_rip, __entry->info1, __entry->info2)
arch/x86/kvm/x86.c +13 -6
@@ -3684,7 +3684,8 @@ static int write_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes, void *val)static int read_exit_mmio (struct kvm_vcpu *vcpu,gpa_t gpa,void *val,int bytes) { -trace_kvm_mmio (KVM_TRACE_MMIO_READ_UNSATISFIED , bytes, gpa,0 ); +trace_kvm_mmio (vcpu->vcpu_id,KVM_TRACE_MMIO_READ_UNSATISFIED , + bytes, gpa,0 );return X86EMUL_IO_NEEDED ; }
@@ -3740,11 +3741,14 @@ mmio:/* * Is this MMIO handled locally? */ -trace_kvm_mmio (write ?KVM_TRACE_MMIO_WRITE :KVM_TRACE_MMIO_READ , - bytes, gpa, *(u64 *)val); +trace_kvm_mmio (vcpu->vcpu_id, + write ?KVM_TRACE_MMIO_WRITE :KVM_TRACE_MMIO_READ , + bytes, gpa, *(u64 *)val); handled = ops->read_write_mmio (vcpu, gpa, bytes, val); -if (handled == bytes) +if (handled == bytes) { +trace_kvm_mmio_done (vcpu->vcpu_id);return X86EMUL_CONTINUE ; + } gpa += handled; bytes -= handled;
@@ -3902,7 +3906,7 @@ static int emulator_pio_in_out(struct kvm_vcpu *vcpu, int size, unsigned short port, void *val, unsigned int count, bool in) { - trace_kvm_pio(!in, port, size, count); + trace_kvm_pio(vcpu->vcpu_id, !in, port, size, count); vcpu->arch.pio.port = port; vcpu->arch.pio.in = in;
@@ -3910,6 +3914,7 @@ static int emulator_pio_in_out(struct kvm_vcpu *vcpu, int size, vcpu->arch.pio.size = size;if (!kernel_pio (vcpu, vcpu->arch.pio_data)) { +trace_kvm_mmio_done (vcpu->vcpu_id); vcpu->arch.pio.count =0 ;return 1 ; }
@@ -5399,7 +5404,7 @@ static int complete_mmio(struct kvm_vcpu *vcpu)return 0 ; }if (vcpu->mmio_is_write) -return 1 ; + goto exit; vcpu->mmio_read_completed =1 ; } vcpu->srcu_idx =srcu_read_lock (&vcpu->kvm->srcu);
@@ -5407,6 +5412,8 @@ static int complete_mmio(struct kvm_vcpu *vcpu)srcu_read_unlock (&vcpu->kvm->srcu, vcpu->srcu_idx);if (r !=EMULATE_DONE )return 0 ; +exit: +trace_kvm_mmio_done (vcpu->vcpu_id);return 1 ; }
include/trace/events/kvm.h +25 -7
@@ -152,28 +152,46 @@ TRACE_EVENT(kvm_ack_irq, { KVM_TRACE_MMIO_WRITE, "write" }TRACE_EVENT (kvm_mmio, - TP_PROTO(int type, int len, u64 gpa, u64 val), -TP_ARGS (type, len, gpa, val), + TP_PROTO(unsigned int vcpu_id, int type, int len, u64 gpa, u64 val), +TP_ARGS (vcpu_id, type, len, gpa, val),TP_STRUCT__entry ( - __field( u32, type ) - __field( u32, len ) - __field( u64, gpa ) -__field ( u64, val ) + __field( unsigned int, vcpu_id ) + __field( u32, type ) + __field( u32, len ) + __field( u64, gpa ) +__field ( u64, val ) ),TP_fast_assign ( + __entry->vcpu_id = vcpu_id; __entry->type = type; __entry->len = len; __entry->gpa = gpa; __entry->val = val; ), -TP_printk ("mmio %s len %u gpa 0x%llx val 0x%llx" , +TP_printk ("vcpu %u mmio %s len %u gpa 0x%llx val 0x%llx" , + __entry->vcpu_id,__print_symbolic (__entry->type, kvm_trace_symbol_mmio), __entry->len, __entry->gpa, __entry->val) ); +TRACE_EVENT (kvm_mmio_done, + TP_PROTO(unsigned int vcpu_id), +TP_ARGS (vcpu_id), + +TP_STRUCT__entry ( + __field( unsigned int, vcpu_id ) + ), + +TP_fast_assign ( + __entry->vcpu_id = vcpu_id; + ), + +TP_printk ("vcpu %u" , __entry->vcpu_id) +); +#define kvm_fpu_load_symbol \ {0, "unload"}, \ {1, "load"}
Signature · 1 line
1.7.7.5
Re: [PATCH 2/3] KVM: improve trace events of vmexit/mmio/ioport
Quoted 1 line · Xiao Guangrong
- trace
vcpu_idfor these events
We can infer the vcpu id from the kvm_entry tracepoints, no?
Quoted 1 line
- add
kvm_mmio_doneto trace the time when mmio/ioport emulation is completed
ditto?
Relying on the existing tracepoints will make the tool work on older kernels.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [PATCH 2/3] KVM: improve trace events of vmexit/mmio/ioport
Quoted 5 lines · Avi Kivity
Quoted 1 line · Xiao Guangrong
- trace
vcpu_idfor these eventsWe can infer the vcpu id from the
kvm_entrytracepoints, no?
Thanks for your review, Avi!
Hmm. i think it is hard to do since the vcpu thread can be scheduled anytime, one example is as follow:
CPU 0
kvm_entry vcpu 0
......kvm_entry vcpu 1
......
event1 occurs
......
event2 occurs
It is hard to know the event belong to which kvm_entry?
Quoted 4 lines
Quoted 1 line
- add
kvm_mmio_doneto trace the time when mmio/ioport emulation is completedditto?
I think is ok to get the event end time by using kvm_entry.
Quoted 4 lines
Relying on the existing tracepoints will make the tool work on older kernels.
We can drop all new events, but unfortunately, the information of the origin tracepoints is not enough, at least vcpu_id need be traced in theses events to match its events. Yes?
Re: [PATCH 2/3] KVM: improve trace events of vmexit/mmio/ioport
Quoted 35 lines · Xiao Guangrong
Quoted 5 lines · Avi Kivity
Quoted 1 line · Xiao Guangrong
- trace
vcpu_idfor these eventsWe can infer the vcpu id from the
kvm_entrytracepoints, no?Thanks for your review, Avi!
Hmm. i think it is hard to do since the vcpu thread can be scheduled anytime, one example is as follow:
CPU 0
kvm_entryvcpu 0
......kvm_entryvcpu 1
......
event1 occurs
......
event2 occursIt is hard to know the event belong to which
kvm_entry?Quoted 4 lines
Quoted 1 line
- add
kvm_mmio_doneto trace the time when mmio/ioport emulation is completedditto?
I think is ok to get the event end time by using
kvm_entry.Quoted 1 line
Quoted 8 lines
Quoted 3 lines
Relying on the existing tracepoints will make the tool work on older kernels.
We can drop all new events, but unfortunately, the information of the origin tracepoints is not enough, at least
vcpu_idneed be traced in theses events to match its events. Yes?
Yes, and if you don't add completed events, you'll have to use kvm_entry whose collection adds a lot of overhead.
Re: [PATCH 2/3] KVM: improve trace events of vmexit/mmio/ioport
Quoted 41 lines · Marcelo Tosatti
Quoted 40 lines · Xiao Guangrong
Quoted 5 lines · Avi Kivity
Quoted 1 line · Xiao Guangrong
- trace
vcpu_idfor these eventsWe can infer the vcpu id from the
kvm_entrytracepoints, no?Thanks for your review, Avi!
Hmm. i think it is hard to do since the vcpu thread can be scheduled anytime, one example is as follow:
CPU 0
kvm_entryvcpu 0
......kvm_entryvcpu 1
......
event1 occurs
......
event2 occursIt is hard to know the event belong to which
kvm_entry?Quoted 4 lines
Quoted 1 line
- add
kvm_mmio_doneto trace the time when mmio/ioport emulation is completedditto?
I think is ok to get the event end time by using
kvm_entry.Quoted 4 lines
Relying on the existing tracepoints will make the tool work on older kernels.
Quoted 6 lines
Quoted 3 lines
We can drop all new events, but unfortunately, the information of the origin tracepoints is not enough, at least
vcpu_idneed be traced in theses events to match its events. Yes?Yes, and if you don't add completed events, you'll have to use
kvm_entrywhose collection adds a lot of overhead.
vcpus run as threads and hence have their own tid which is available in the perf samples.
There is an ongoing 'discussion' about modifying existing tracepoints which your proposed patch violates. This is the start of it:
https://lkml.org/lkml/2012/1/16/41
David
Re: [PATCH 2/3] KVM: improve trace events of vmexit/mmio/ioport
Quoted 10 lines · David Ahern
Quoted 10 lines
Quoted 9 lines
Quoted 4 lines
Relying on the existing tracepoints will make the tool work on older kernels.
We can drop all new events, but unfortunately, the information of the origin tracepoints is not enough, at least
vcpu_idneed be traced in theses events to match its events. Yes?
Quoted 7 lines
Quoted 2 lines
Yes, and if you don't add completed events, you'll have to use
kvm_entrywhose collection adds a lot of overhead.vcpus run as threads and hence have their own tid which is available in the perf samples.
Nice, thanks for your information, David!
Quoted 3 lines
There is an ongoing 'discussion' about modifying existing tracepoints which your proposed patch violates. This is the start of it:
Hmm, i think we can still add completed tracepoints in the new version kernel, if old version kernel is used, we can fall back to use kvm_entry instead?
And there is a exception for mmio read, in current code, the mmio read event is actually used to trace the time when then read emulation is completed, i think we can add a tracepoint like mmio_read_begin to trace the start time of mmio read. So:
- for the new kernel, we use mmio_read_begion and kvm_mmio(READ...) to calculate start time and end time.
- for the old kernel, we use kvm_exit and kvm_mmio(READ...) to calculate start time and end time.
Your idea?
Re: [PATCH 2/3] KVM: improve trace events of vmexit/mmio/ioport
Quoted 7 lines · Xiao Guangrong
Quoted 3 lines
There is an ongoing 'discussion' about modifying existing tracepoints which your proposed patch violates. This is the start of it:
Hmm, i think we can still add completed tracepoints in the new version kernel, if old version kernel is used, we can fall back to use
kvm_entryinstead?
Yes, new ones are ok. I was referring to the tracepoints like kvm_pio where you added the vcpu_id. And it is not really necessary: with kvm_entry tracepoints it is easy to correlate vcpu to tid and even without you still get thread base samples so events happening on a thread are all the sample vcpu (even if you don't know whether that is vcpu 0, 1, 2, etc).
Quoted 10 lines
And there is a exception for mmio read, in current code, the mmio read event is actually used to trace the time when then read emulation is completed, i think we can add a tracepoint like
mmio_read_beginto trace the start time of mmio read. So:
- for the new kernel, we usemmio_read_begionandkvm_mmio(READ...)to calculate start time and end time.
- for the old kernel, we usekvm_exitandkvm_mmio(READ...)to calculate start time and end time.
Quoted 2 lines
Your idea?
I did play around with it a bit more today.
My concern would be adding more events may make things more precise, but it adds more overhead and I am not sure the precision is worth it. For example on my laptop (Penryn Core 2; a lab server with a xeon E5560 processor is much faster):
0.000002 kvm_exit reason IO_INSTRUCTION rip 0x806d0e30 info 710048 0
0.000003 kvm_emulate_insn 0:806d0e30: e4 71
0.000001 kvm_pio pio_read at 0x71 size 1 count 1
0.000001 kvm_userspace_exit reason KVM_EXIT_IO (2)
0.000003 kvm_set_irq gsi 8 level 0 source 0
0.000001 kvm_pic_set_irq chip 1 pin 0 (edge|masked)
0.000001 kvm_ioapic_set_irq pin 8 dst 1 vec=209 (Fixed|logical|edge)
total exit time: 0.000016The first column is the delta-time between successive events for a vcpu. Most of those events are in the rounded up microsecond range. Moving on to the subsequent kvm_entry shows a total VMENTRY run time of 5 usecs:
ie., 16 usecs on a VMEXIT with 7 tracepoints and 5 usecs spent in a VMENTRY.
What I am getting at is that the cost of the tracepoints becomes a significant overhead. If it costs 500nsec or 1usec to generate an event and the time in a VMENTRY is only 5 usecs the tracepoint is a large part of the time.
David
Re: [PATCH 2/3] KVM: improve trace events of vmexit/mmio/ioport
In reply to Xiao GuangrongQuoted 24 lines · Xiao Guangrong
Quoted 5 lines · Avi Kivity
Quoted 1 line · Xiao Guangrong
- trace
vcpu_idfor these eventsWe can infer the vcpu id from the
kvm_entrytracepoints, no?Thanks for your review, Avi!
Hmm. i think it is hard to do since the vcpu thread can be scheduled anytime, one example is as follow:
CPU 0
kvm_entryvcpu 0
......kvm_entryvcpu 1
......
event1 occurs
......
event2 occurs
Quoted 2 lines
It is hard to know the event belong to which
kvm_entry?
Why is it hard? Correlate the task IDs.
Signature · 1 line
error compiling committee.c: too many arguments to function
PATCH 3/3 KVM: perf: kvm events analysis tool
In reply to Xiao GuangrongAdd 'perf kvm-events' support to analyze kvm vmexit/mmio/ioport smartly
Usage:
perf kvm-events record
perf kvm-events report
--- tools/perf/Documentation/perf-kvm-events.txt | 54 ++ tools/perf/Makefile | 1 + tools/perf/builtin-kvm-events.c | 860 ++++++++++++++++++++++++++ tools/perf/builtin.h | 1 + tools/perf/perf.c | 1 + 5 files changed, 917 insertions(+), 0 deletions(-) create mode 100644 tools/perf/Documentation/perf-kvm-events.txt create mode 100644 tools/perf/builtin-kvm-events.c
tools/perf/Documentation/perf-kvm-events.txt new file +54 -0
@@ -0,0 +1,54 @@ +perf-kvm-events(1) +============ + +NAME +---- +perf-kvm-events - Analyze kvm events + +SYNOPSIS +-------- +[verse] +'perf kvm-events' {record|report} + +DESCRIPTION +----------- +You can analyze some crucial events and statistics with this +'perf kvm-events' command. + + 'perf kvm-events record <command>' records kvm events + between start and end <command>. And this command + produces the file "perf.data" which contains tracing + results of kvm events. + + 'perf kvm-events report' reports statistical data. + +COMMON OPTIONS +-------------- + +-i:: +--input=<file>:: + Input file name. (default: perf.data unless stdin is a fifo) + +-v:: +--verbose:: + Be more verbose (show symbol address, etc). + +-D:: +--dump-raw-trace:: + Dump raw trace in ASCII. + +REPORT OPTIONS +-------------- +--vcpu=<value>:: + analyze events which occures on this vcpu + +--events=<value>:: + events to be analyzed. Possible values: vmexit, mmio, ioport. +-k:: +--key=<value>:: + Sorting key. Possible values: sample(default, sort by samples number), +time(sort by time%). + +SEE ALSO +-------- +linkperf:perf[1]
tools/perf/Makefile +1 -0
@@ -382,6 +382,7 @@ BUILTIN_OBJS += $(OUTPUT)builtin-probe.o BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o BUILTIN_OBJS += $(OUTPUT)builtin-lock.o BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o +BUILTIN_OBJS += $(OUTPUT)builtin-kvm-events.o BUILTIN_OBJS += $(OUTPUT)builtin-test.o BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
tools/perf/builtin-kvm-events.c new file +860 -0
860 lines not on this page · raw message
tools/perf/builtin.h +1 -0
@@ -33,6 +33,7 @@ extern int cmd_probe(int argc, const char **argv, const char *prefix);extern int cmd_kmem (int argc,const char **argv,const char *prefix);extern int cmd_lock (int argc,const char **argv,const char *prefix);extern int cmd_kvm (int argc,const char **argv,const char *prefix); +extern int cmd_kvm_events (int argc,const char **argv,const char *prefix);extern int cmd_test (int argc,const char **argv,const char *prefix);extern int cmd_inject (int argc,const char **argv,const char *prefix);
tools/perf/perf.c +1 -0
@@ -317,6 +317,7 @@ static void handle_internal_command(int argc, const char **argv) { "kmem", cmd_kmem, 0 }, { "lock", cmd_lock, 0 }, { "kvm", cmd_kvm, 0 }, + { "kvm-events", cmd_kvm_events, 0}, { "test", cmd_test, 0 }, { "inject", cmd_inject, 0 }, };
Signature · 1 line
1.7.7.5
Re: [PATCH 3/3] KVM: perf: kvm events analysis tool
Quoted 4 lines · Xiao Guangrong
Add 'perf kvm-events' support to analyze kvm vmexit/mmio/ioport smartly
Usage:
perf kvm-events record
Why not 'perf record -e kvm'?
Quoted 8 lines
perf kvm-events report
tools/perf/builtin-kvm-events.c new file +4
-0+static const char *get_exit_reason (long isa,u64 exit_code) +{ +int table_size =ARRAY_SIZE (svm_exit_reasons); +struct exit_reasons_table *table = svm_exit_reasons;
tools/perf/builtin-kvm-events.c line 266
Quoted 10 lines
tools/perf/builtin-kvm-events.c new file +10
-0+ + +if (isa ==1 ) { + table = vmx_exit_reasons; + table_size =ARRAY_SIZE (vmx_exit_reasons); + } + +while (table_size--) { +if (table->exit_code == exit_code) +return table->reason;
... table[exit_code] ...
tools/perf/builtin-kvm-events.c line 271
Quoted 5 lines
tools/perf/builtin-kvm-events.c new file +5
-0+ table++; + } + +die ("unkonw kvm exit code:%ld on %s\n" , exit_code, isa ==1 ? +"VMX" :"SVM" );
"unknown"
tools/perf/builtin-kvm-events.c line 280
Quoted 3 lines
tools/perf/builtin-kvm-events.c new file +3
-0+ +struct kvm_events_ops { +bool (*is_begain_event)(struct event *event,void *data);
begin
tools/perf/builtin-kvm-events.c line 302
Quoted 13 lines
tools/perf/builtin-kvm-events.c new file +13
-0+bool (*is_end_event)(struct event *event); +struct event_key (*get_key)(struct event *event,void *data); +void (*decode_key)(struct event_key *key,char decode[20 ]); +const char *name; +}; + + +static struct event_key exit_event_get_key (struct event *event,void *data) +{ +struct event_key key; + + key.key =raw_field_value (event,"exit_reason" , data); + key.info =raw_field_value (event,"isa" , data);
"isa" is not available on all kernel versions; need to fall back to /proc/cpuid detection.
Quoted 3 lines
(quoted diff) +2
-0+ return key; +}
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [PATCH 3/3] KVM: perf: kvm events analysis tool
Quoted 7 lines · Avi Kivity
Quoted 4 lines · Xiao Guangrong
Add 'perf kvm-events' support to analyze kvm vmexit/mmio/ioport smartly
Usage:
perf kvm-events recordWhy not 'perf record -e kvm'?
It works, many perf tools have this style, like:
perf lock record,
perf sched record,
perf kmem record,
I think the reason is that only enable the tracepoints we need to avoid unnecessary overload so that the result is more exacter.
Quoted 5 lines
Quoted 2 lines
perf kvm-events report
Quoted 17 lines
Quoted 4 lines
tools/perf/builtin-kvm-events.c new file +4
-0+static const char *get_exit_reason (long isa,u64 exit_code) +{ +int table_size =ARRAY_SIZE (svm_exit_reasons); +struct exit_reasons_table *table = svm_exit_reasons;tools/perf/builtin-kvm-events.c line 266
Quoted 10 lines
tools/perf/builtin-kvm-events.c new file +10
-0+ + +if (isa ==1 ) { + table = vmx_exit_reasons; + table_size =ARRAY_SIZE (vmx_exit_reasons); + } + +while (table_size--) { +if (table->exit_code == exit_code) +return table->reason;... table[exit_code] ...
Actually, this array is not indexed by exit_code, it means:
table[exit_code].exit_code != exit_code.
Quoted 8 lines
tools/perf/builtin-kvm-events.c line 271
Quoted 5 lines
tools/perf/builtin-kvm-events.c new file +5
-0+ table++; + } + +die ("unkonw kvm exit code:%ld on %s\n" , exit_code, isa ==1 ? +"VMX" :"SVM" );"unknown"
......
Quoted 6 lines
tools/perf/builtin-kvm-events.c line 280
Quoted 3 lines
tools/perf/builtin-kvm-events.c new file +3
-0+ +struct kvm_events_ops { +bool (*is_begain_event)(struct event *event,void *data);begin
Sorry for my careless.
Quoted 8 lines
Quoted 8 lines
tools/perf/builtin-kvm-events.c new file +8
-0+bool (*is_end_event)(struct event *event); +struct event_key (*get_key)(struct event *event,void *data); +void (*decode_key)(struct event_key *key,char decode[20 ]); +const char *name; +}; + + +static struct event_key exit_event_get_key (struct event *event,void *data)
Quoted 9 lines
tools/perf/builtin-kvm-events.c line 302
Quoted 5 lines
tools/perf/builtin-kvm-events.c new file +5
-0+{ +struct event_key key; + + key.key =raw_field_value (event,"exit_reason" , data); + key.info =raw_field_value (event,"isa" , data);"isa" is not available on all kernel versions; need to fall back to
/proc/cpuiddetection.
Got it, will do it in the next version. Thanks Avi!
Re: [PATCH 3/3] KVM: perf: kvm events analysis tool
Quoted 11 lines · Xiao Guangrong
Quoted 7 lines · Avi Kivity
Quoted 4 lines · Xiao Guangrong
Add 'perf kvm-events' support to analyze kvm vmexit/mmio/ioport smartly
Usage:
perf kvm-events recordWhy not 'perf record -e kvm'?
Quoted 7 lines
It works, many perf tools have this style, like:
perf lock record,
perf sched record,
perf kmem record,I think the reason is that only enable the tracepoints we need to avoid unnecessary overload so that the result is more exacter.
Maybe a virtual event list:
perf record -e kvm-pio
This allows us to combine the event list with other events:
perf record -e kvm-pio -e timer
Quoted 11 lines
Quoted 7 lines
tools/perf/builtin-kvm-events.c line 266
Quoted 4 lines
tools/perf/builtin-kvm-events.c new file +4
-0+ +while (table_size--) { +if (table->exit_code == exit_code) +return table->reason;... table[exit_code] ...
Actually, this array is not indexed by
exit_code, it means:
table[exit_code].exit_code !=exit_code.
So make it indexed by exit code.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [PATCH 3/3] KVM: perf: kvm events analysis tool
In reply to Xiao Guangrongtools/perf/Documentation/perf-kvm-events.txt line 16
Quoted 4 lines · Xiao Guangrong
tools/perf/Documentation/perf-kvm-events.txt new file +4
-0+DESCRIPTION +----------- +You can analyze some crucial events and statistics with this +'perf kvm-events' command.
This line is very general and does not explain which events/statistics can be collected or how you can use that information. I suggest making this description more specific. Explain that this subcommand observers kvm.ko tracepoints and annotates/decodes them with additional information (this is why I would use this command and not raw perf record -e kvm:\*).
Quoted 4 lines
+ {
SVM_EXIT_MONITOR, "monitor" }, \
+ {SVM_EXIT_MWAIT, "mwait" }, \
+ {SVM_EXIT_XSETBV, "xsetbv" }, \
+ {SVM_EXIT_NPF, "npf" }
All this copy-paste could be avoided by sharing this stuff with the arch/x86/kvm/ code.
tools/perf/builtin-kvm-events.c line 311
Quoted 6 lines
tools/perf/builtin-kvm-events.c new file +6
-0+static void exit_event_decode_key (struct event_key *key,char decode[20 ]) +{ + const char *exit_reason = get_exit_reason(key->info, key->key); + + memset(decode, 0, 20); + strncpy(decode, exit_reason, 20);
This is a bad pattern to follow when using strncpy(3) because if there was a strlen(exit_reason) == 20 string then decode[] would not be NUL-terminated. Right now it's safe but it's better to just use strlcpy() and drop the memset(3).
Quoted 35 lines
tools/perf/builtin-kvm-events.c new file +35
-0+} + +static struct kvm_events_ops exit_events = { + .is_begain_event = exit_event_begain, + .is_end_event = exit_event_end, + .get_key = exit_event_get_key, + .decode_key = exit_event_decode_key, + .name = "VM-EXIT" +}; + +#define KVM_TRACE_MMIO_READ_UNSATISFIED 0 +#define KVM_TRACE_MMIO_READ 1 +#define KVM_TRACE_MMIO_WRITE 2 +static bool mmio_event_begain (struct event *event,void *data) +{ + if (!strcmp(event->name, "kvm_mmio")) { + long type = raw_field_value(event, "type", data); + + if (type != KVM_TRACE_MMIO_READ_UNSATISFIED) + return true; + }; + + return false; +} + +static bool mmio_event_end (struct event *event) +{ + return !strcmp(event->name, "kvm_mmio_done"); +} + +static struct event_key mmio_event_get_key (struct event *event,void *data) +{ + struct event_key key; + + key.key = raw_field_value(event, "gpa", data);
tools/perf/builtin-kvm-events.c line 356
Quoted 10 lines
tools/perf/builtin-kvm-events.c new file +10
-0+ key.info = raw_field_value(event, "type", data); + + return key; +} + +static void mmio_event_decode_key (struct event_key *key,char decode[20 ]) +{ + memset(decode, 0, 20); + sprintf(decode, "%#lx:%s", key->key, + key->info == KVM_TRACE_MMIO_READ ? "R" : "W");
Please drop the memset and use snprintf(3) instead of sprintf(3). It places the NUL-terminator and ensures you don't exceed the buffer size.
Same pattern below.
Re: [PATCH 3/3] KVM: perf: kvm events analysis tool
Quoted 14 lines · Stefan Hajnoczi
tools/perf/Documentation/perf-kvm-events.txt line 16
Quoted 4 lines · Xiao Guangrong
tools/perf/Documentation/perf-kvm-events.txt new file +4
-0+DESCRIPTION +----------- +You can analyze some crucial events and statistics with this +'perf kvm-events' command.This line is very general and does not explain which events/statistics can be collected or how you can use that information. I suggest making this description more specific. Explain that this subcommand observers kvm.ko tracepoints and annotates/decodes them with additional information (this is why I would use this command and not raw perf record -e kvm:\*).
Okay.
Quoted 8 lines
Quoted 4 lines
+ � � � {
SVM_EXIT_MONITOR, � � � � � � � � � � "monitor" }, \
+ � � � {SVM_EXIT_MWAIT, � � � � � � � � � � � "mwait" }, \
+ � � � {SVM_EXIT_XSETBV, � � � � � � � � � � �"xsetbv" }, \
+ � � � {SVM_EXIT_NPF, � � � � � � � � � � � � "npf" }All this copy-paste could be avoided by sharing this stuff with the
arch/x86/kvm/code.
I will try to combine them in the next version.
Quoted 12 lines
tools/perf/builtin-kvm-events.c
Quoted 6 lines
tools/perf/builtin-kvm-events.c new file +6
-0+static void exit_event_decode_key (struct event_key *key,char decode[20 ]) +{ + � � � const char *exit_reason = get_exit_reason(key->info, key->key); + + � � � memset(decode, 0, 20); + � � � strncpy(decode, exit_reason, 20);This is a bad pattern to follow when using strncpy(3) because if there was a
strlen(exit_reason)== 20 string then decode[] would not be NUL-terminated. Right now it's safe but it's better to just usestrlcpy()and drop the memset(3).
Good point.
Quoted 10 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+static void mmio_event_decode_key(struct event_key *key, char decode[20]) +{ + � � � memset(decode, 0, 20); + � � � sprintf(decode, "%#lx:%s", key->key, + � � � � � � � key->info == KVM_TRACE_MMIO_READ ? "R" : "W");Please drop the memset and use snprintf(3) instead of sprintf(3). It places the NUL-terminator and ensures you don't exceed the buffer size.
Quoted 2 lines
Same pattern below.
Will do, thanks Stefan! :)
Re: [PATCH 3/3] KVM: perf: kvm events analysis tool
In reply to Stefan HajnocziQuoted 14 lines · Stefan Hajnoczi
tools/perf/Documentation/perf-kvm-events.txt line 16
Quoted 4 lines · Xiao Guangrong
tools/perf/Documentation/perf-kvm-events.txt new file +4
-0+DESCRIPTION +----------- +You can analyze some crucial events and statistics with this +'perf kvm-events' command.This line is very general and does not explain which events/statistics can be collected or how you can use that information. I suggest making this description more specific. Explain that this subcommand observers kvm.ko tracepoints and annotates/decodes them with additional information (this is why I would use this command and not raw perf record -e kvm:\*).
Quoted 7 lines
Quoted 4 lines
+ {
SVM_EXIT_MONITOR, "monitor" }, \
+ {SVM_EXIT_MWAIT, "mwait" }, \
+ {SVM_EXIT_XSETBV, "xsetbv" }, \
+ {SVM_EXIT_NPF, "npf" }All this copy-paste could be avoided by sharing this stuff with the
arch/x86/kvm/code.
Yes, same for KVM_MAX_VCPUS.
Re: [PATCH 3/3] KVM: perf: kvm events analysis tool
Quoted 7 lines · Marcelo Tosatti
Quoted 3 lines
All this copy-paste could be avoided by sharing this stuff with the
arch/x86/kvm/code.Yes, same for
KVM_MAX_VCPUS.
This is an internal define. perf kvm should work with different kernel versions, so it needs to query the value dynamically.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 31 lines · Xiao Guangrong
This tool is very like xenoprof(if i remember correctly), and traces kvm events smartly. currently, it supports vmexit/mmio/ioport events.
Usage:
- to trace kvm events:# ./perf kvm-events record- show the result
# ./perf kvm-events reportSome output are as follow:
# ./perf kvm-events report Warning: Error: expected type 5 but read 4 Warning: Error: expected type 5 but read 0 Warning: unknown op '}'Analyze events for all VCPUs:
VM-EXIT Samples Samples% Time% Avg time
APIC_ACCESS438107 44.89% 6.20% 17.91usEXTERNAL_INTERRUPT 219226 22.46% 8.01% 46.20us IO_INSTRUCTION 122651 12.57% 1.88% 19.44us EPT_VIOLATION 83110 8.52% 1.36% 20.75us PENDING_INTERRUPT 37055 3.80% 0.16% 5.38us CPUID 32718 3.35% 0.08% 3.15us EXCEPTION_NMI 23601 2.42% 0.17% 8.87us HLT 15424 1.58% 82.12% 6735.06us CR_ACCESS 4089 0.42% 0.02% 6.08us
Quoted 1 line
Total Samples:975981, Total events handled time:126502464.88us.
Nice! If we can have a live version as well, this can replace kvm_stat.
The average numbers are really high. Like a factor of 3x-4x off. Would be good to print the standard deviation and see why. Maybe it's due to the tracing overhead.
Quoted 8 lines
The default event to be analysed is vmexit, we can use --event to specify it, for example, if we want to trace mmio event:
# ./perf kvm-events report --event mmio Warning: Error: expected type 5 but read 4 Warning: Error: expected type 5 but read 0 Warning: unknown op '}'
Quoted 8 lines
Analyze events for all VCPUs:
MMIO Access Samples Samples% Time% Avg time 0xfee00380:W 196589 64.95% 70.01% 3.83us 0xfee00310:W 35356 11.68% 6.48% 1.97us 0xfee00300:W 35356 11.68% 16.37% 4.97us 0xfee00300:R 35356 11.68% 7.14% 2.17us
These are more reasonable (though still high - 5us for an ICR write?)
Quoted 43 lines
Total Samples:302657, Total events handled time:1074746.01us.
We can use --vcpu to specify which vcpu is traced:
root@localhost perf]# ./perf kvm-events report --event mmio --vcpu 1
Warning: Error: expected type 5 but read 4
Warning: Error: expected type 5 but read 0
Warning: unknown op '}'Analyze events for VCPU 1:
MMIO Access Samples Samples% Time% Avg time 0xfee00380:W 58041 71.20% 74.90% 3.70us 0xfee00310:W 7826 9.60% 5.28% 1.93us 0xfee00300:W 7826 9.60% 13.82% 5.06us 0xfee00300:R 7826 9.60% 6.01% 2.20usTotal Samples:81519, Total events handled time:286577.81us.
And, '--key' is used to sort the result, the possible value sample (default, the result is sorted by samples number), time(the result is sorted by time%):
# ./perf kvm-events report --key time Warning: Error: expected type 5 but read 4 Warning: Error: expected type 5 but read 0 Warning: unknown op '}'Analyze events for all VCPUs:
VM-EXIT Samples Samples% Time% Avg time
HLT 15424 1.58% 82.12% 6735.06us
EXTERNAL_INTERRUPT 219226 22.46% 8.01% 46.20us APIC_ACCESS 438107 44.89% 6.20% 17.91us IO_INSTRUCTION 122651 12.57% 1.88% 19.44us EPT_VIOLATION 83110 8.52% 1.36% 20.75us EXCEPTION_NMI 23601 2.42% 0.17% 8.87us PENDING_INTERRUPT 37055 3.80% 0.16% 5.38us CPUID 32718 3.35% 0.08% 3.15us CR_ACCESS 4089 0.42% 0.02% 6.08us
Quoted 3 lines
Total Samples:975981, Total events handled time:126502464.88us.
I hope guys will like it and any comments are welcome! :)
I think it's great! A live version would be a nice addition too.
Please copy the perf userspace maintainers to get more detailed review in the next version.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 8 lines · Avi Kivity
Quoted 1 line
Total Samples:975981, Total events handled time:126502464.88us.
Nice! If we can have a live version as well, this can replace
kvm_stat.The average numbers are really high. Like a factor of 3x-4x off. Would be good to print the standard deviation and see why. Maybe it's due to the tracing overhead.
It is a good suggestion, i will print stddev in the next version.
Quoted 10 lines
Quoted 10 lines
The default event to be analysed is vmexit, we can use --event to specify it, for example, if we want to trace mmio event:
# ./perf kvm-events report --event mmio Warning: Error: expected type 5 but read 4 Warning: Error: expected type 5 but read 0 Warning: unknown op '}'Analyze events for all VCPUs:
Quoted 9 lines
Quoted 6 lines
MMIO Access Samples Samples% Time% Avg time 0xfee00380:W 196589 64.95% 70.01% 3.83us 0xfee00310:W 35356 11.68% 6.48% 1.97us 0xfee00300:W 35356 11.68% 16.37% 4.97us 0xfee00300:R 35356 11.68% 7.14% 2.17usThese are more reasonable (though still high - 5us for an ICR write?)
Hmm, maybe i need look into it...
Quoted 9 lines
Quoted 3 lines
Total Samples:975981, Total events handled time:126502464.88us.
I hope guys will like it and any comments are welcome! :)
I think it's great! A live version would be a nice addition too.
Please copy the perf userspace maintainers to get more detailed review in the next version.
Okay, Thanks!
Quoted 7 lines · Xiao Guangrong
This tool is very like xenoprof(if i remember correctly), and traces kvm events smartly. currently, it supports vmexit/mmio/ioport events.
Usage:
- to trace kvm events:# ./perf kvm-events record
Quoted 8 lines
- show the result
# ./perf kvm-events reportSome output are as follow:
# ./perf kvm-events report Warning: Error: expected type 5 but read 4 Warning: Error: expected type 5 but read 0 Warning: unknown op '}'
Integrating the trace-cmd plugins into perf will remedy the above errors:
https://lkml.org/lkml/2011/8/16/352
Unfortunately, that effort is stalled at the moment.
Quoted 16 lines
Analyze events for all VCPUs:
VM-EXIT Samples Samples% Time% Avg time
APIC_ACCESS438107 44.89% 6.20% 17.91usEXTERNAL_INTERRUPT 219226 22.46% 8.01% 46.20us IO_INSTRUCTION 122651 12.57% 1.88% 19.44us EPT_VIOLATION 83110 8.52% 1.36% 20.75us PENDING_INTERRUPT 37055 3.80% 0.16% 5.38us CPUID 32718 3.35% 0.08% 3.15us EXCEPTION_NMI 23601 2.42% 0.17% 8.87us HLT 15424 1.58% 82.12% 6735.06us CR_ACCESS 4089 0.42% 0.02% 6.08us
Quoted 1 line
Total Samples:975981, Total events handled time:126502464.88us.
Have you thought about dumping a time history -- something similar to what perf-script can do with dumping events but adding in kvm-specific analysis like what you are doing in these examples?
David
Quoted 69 lines
The default event to be analysed is vmexit, we can use --event to specify it, for example, if we want to trace mmio event:
# ./perf kvm-events report --event mmio Warning: Error: expected type 5 but read 4 Warning: Error: expected type 5 but read 0 Warning: unknown op '}'Analyze events for all VCPUs:
MMIO Access Samples Samples% Time% Avg time 0xfee00380:W 196589 64.95% 70.01% 3.83us 0xfee00310:W 35356 11.68% 6.48% 1.97us 0xfee00300:W 35356 11.68% 16.37% 4.97us 0xfee00300:R 35356 11.68% 7.14% 2.17usTotal Samples:302657, Total events handled time:1074746.01us.
We can use --vcpu to specify which vcpu is traced:
root@localhost perf]# ./perf kvm-events report --event mmio --vcpu 1
Warning: Error: expected type 5 but read 4
Warning: Error: expected type 5 but read 0
Warning: unknown op '}'Analyze events for VCPU 1:
MMIO Access Samples Samples% Time% Avg time 0xfee00380:W 58041 71.20% 74.90% 3.70us 0xfee00310:W 7826 9.60% 5.28% 1.93us 0xfee00300:W 7826 9.60% 13.82% 5.06us 0xfee00300:R 7826 9.60% 6.01% 2.20usTotal Samples:81519, Total events handled time:286577.81us.
And, '--key' is used to sort the result, the possible value sample (default, the result is sorted by samples number), time(the result is sorted by time%):
# ./perf kvm-events report --key time Warning: Error: expected type 5 but read 4 Warning: Error: expected type 5 but read 0 Warning: unknown op '}'Analyze events for all VCPUs:
VM-EXIT Samples Samples% Time% Avg time
HLT 15424 1.58% 82.12% 6735.06us
EXTERNAL_INTERRUPT 219226 22.46% 8.01% 46.20us APIC_ACCESS 438107 44.89% 6.20% 17.91us IO_INSTRUCTION 122651 12.57% 1.88% 19.44us EPT_VIOLATION 83110 8.52% 1.36% 20.75us EXCEPTION_NMI 23601 2.42% 0.17% 8.87us PENDING_INTERRUPT 37055 3.80% 0.16% 5.38us CPUID 32718 3.35% 0.08% 3.15us CR_ACCESS 4089 0.42% 0.02% 6.08usTotal Samples:975981, Total events handled time:126502464.88us.
I hope guys will like it and any comments are welcome! :)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Quoted 13 lines · David Ahern
Quoted 10 lines · Xiao Guangrong
This tool is very like xenoprof(if i remember correctly), and traces kvm events smartly. currently, it supports vmexit/mmio/ioport events.
Usage:
- to trace kvm events:# ./perf kvm-events record- show the result
# ./perf kvm-events report
Quoted 9 lines
Quoted 5 lines
Some output are as follow:
# ./perf kvm-events report Warning: Error: expected type 5 but read 4 Warning: Error: expected type 5 but read 0 Warning: unknown op '}'Integrating the trace-cmd plugins into perf will remedy the above errors:
https://lkml.org/lkml/2011/8/16/352
Yes, it is great!
Quoted 18 lines
Unfortunately, that effort is stalled at the moment.
Quoted 16 lines
Analyze events for all VCPUs:
VM-EXIT Samples Samples% Time% Avg time
APIC_ACCESS438107 44.89% 6.20% 17.91usEXTERNAL_INTERRUPT 219226 22.46% 8.01% 46.20us IO_INSTRUCTION 122651 12.57% 1.88% 19.44us EPT_VIOLATION 83110 8.52% 1.36% 20.75us PENDING_INTERRUPT 37055 3.80% 0.16% 5.38us CPUID 32718 3.35% 0.08% 3.15us EXCEPTION_NMI 23601 2.42% 0.17% 8.87us HLT 15424 1.58% 82.12% 6735.06us CR_ACCESS 4089 0.42% 0.02% 6.08us
Quoted 6 lines
Quoted 1 line
Total Samples:975981, Total events handled time:126502464.88us.
Have you thought about dumping a time history -- something similar to what perf-script can do with dumping events but adding in kvm-specific analysis like what you are doing in these examples?
I will look into it and put it to my todo list if it is possible. Thanks, David!
Quoted 9 lines · Xiao Guangrong
Quoted 4 lines
Have you thought about dumping a time history -- something similar to what perf-script can do with dumping events but adding in kvm-specific analysis like what you are doing in these examples?
I will look into it and put it to my todo list if it is possible. Thanks, David!
I've played around with ways to do it as time (and motivation) allowed. Attached is one example using perf with the trace-cmd plugin plus a patch on perf-script to dump time between events:
perf record -e kvm:* -fo /tmp/perf.data -p 2540 -- sleep 1 perf script -i /tmp/perf.data
The output of perf-script is in the attached file. The 5th column is the dt between successive events which is mainly a convenience.
A perf-kvm-events type command would allow more customization in the output -- like correlating specific events and computing total time between exit and entry accounting for HLT reasons -- as well as various statistical dumps (average, stddev, max/min, histograms).
David
qemu-kvm 2542 [001] 20757.662426 0.000001 kvm_cr: cr_write 3 = 0x6f3000 qemu-kvm 2542 [001] 20757.662430 0.000004 kvm_entry: vcpu 0 qemu-kvm 2542 [001] 20757.662432 0.000002 kvm_exit: reason IO_INSTRUCTION rip 0x806d8dbc info b008000b 0
qemu-kvm 2542 [001] 20757.662434 0.000002 kvm_emulate_insn: 0:806d8dbc: ed qemu-kvm 2542 [001] 20757.662435 0.000001 kvm_pio: pio_read at 0xb008 size 4 count 1 qemu-kvm 2542 [001] 20757.662436 0.000001 kvm_userspace_exit: reason KVM_EXIT_IO (2) qemu-kvm 2542 [001] 20757.662442 0.000006 kvm_entry: vcpu 0 qemu-kvm 2542 [001] 20757.662444 0.000002 kvm_exit: reason HLT rip 0xf770fd3d info 0 0
qemu-kvm 2540 [000] 20757.666479 0.004287 kvm_set_irq: gsi 9 level 1 source 0 qemu-kvm 2540 [000] 20757.666481 0.000002 kvm_pic_set_irq: chip 1 pin 1 (edge|masked) qemu-kvm 2540 [000] 20757.666482 0.000001 kvm_apic_accept_irq: apicid 0 vec 177 (LowPrio|level) qemu-kvm 2540 [000] 20757.666485 0.000003 kvm_ioapic_set_irq: pin 9 dst 1 vec=177 (LowPrio|logical|level)
qemu-kvm 2542 [001] 20757.666505 0.004061 kvm_inj_virq: irq 177 qemu-kvm 2542 [001] 20757.666506 0.000001 kvm_entry: vcpu 0 qemu-kvm 2542 [001] 20757.666512 0.000006 kvm_exit: reason IO_INSTRUCTION rip 0x806d88ca info b0000009 0
qemu-kvm 2542 [001] 20757.666516 0.000004 kvm_emulate_insn: 0:806d88ca: 66 ed qemu-kvm 2542 [001] 20757.666517 0.000001 kvm_pio: pio_read at 0xb000 size 2 count 1 qemu-kvm 2542 [001] 20757.666519 0.000002 kvm_userspace_exit: reason KVM_EXIT_IO (2) qemu-kvm 2542 [001] 20757.666528 0.000009 kvm_entry: vcpu 0 qemu-kvm 2542 [001] 20757.666531 0.000003 kvm_exit: reason IO_INSTRUCTION rip 0x806d88be info afe00008 0
qemu-kvm 2542 [001] 20757.666534 0.000003 kvm_emulate_insn: 0:806d88be: ec qemu-kvm 2542 [001] 20757.666535 0.000001 kvm_pio: pio_read at 0xafe0 size 1 count 1 qemu-kvm 2542 [001] 20757.666537 0.000002 kvm_userspace_exit: reason KVM_EXIT_IO (2) qemu-kvm 2542 [001] 20757.666544 0.000007 kvm_entry: vcpu 0 qemu-kvm 2542 [001] 20757.666547 0.000003 kvm_exit: reason IO_INSTRUCTION rip 0x806d88be info afe10008 0
qemu-kvm 2542 [001] 20757.666550 0.000003 kvm_emulate_insn: 0:806d88be: ec qemu-kvm 2542 [001] 20757.666551 0.000001 kvm_pio: pio_read at 0xafe1 size 1 count 1 qemu-kvm 2542 [001] 20757.666552 0.000001 kvm_userspace_exit: reason KVM_EXIT_IO (2) qemu-kvm 2542 [001] 20757.666558 0.000006 kvm_entry: vcpu 0 qemu-kvm 2542 [001] 20757.666562 0.000004 kvm_exit: reason IO_INSTRUCTION rip 0x806d8934 info b0000001 0