lkml.org 
[lkml]   [2012]   [Aug]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v6 2/3] KVM: x86: tracemmio begin and complete
    Date
    From: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>

    'perf kvm stat record/report' will use kvm_exit and kvm_mmio(read...) to
    calculate mmio read emulated time for the old kernel, in order to trace
    mmio read event more exactly, we add kvm_mmio_begin to trace the time when
    mmio read begins, also, add kvm_io_done to trace the time when mmio/pio is
    completed

    [ Dong Hao <haodong@linux.vnet.ibm.com>: rebase it on current kvm tree ]
    Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
    Signed-off-by: Dong Hao <haodong@linux.vnet.ibm.com>
    ---
    arch/x86/kvm/x86.c | 32 ++++++++++++++++++++------------
    include/trace/events/kvm.h | 37 +++++++++++++++++++++++++++++++++++++
    2 files changed, 57 insertions(+), 12 deletions(-)

    diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
    index 8ebf65c..164ed9d 100644
    --- a/arch/x86/kvm/x86.c
    +++ b/arch/x86/kvm/x86.c
    @@ -3807,9 +3807,12 @@ mmio:
    /*
    * Is this MMIO handled locally?
    */
    + trace_kvm_mmio_begin(vcpu->vcpu_id, write, gpa);
    handled = ops->read_write_mmio(vcpu, gpa, bytes, val);
    - if (handled == bytes)
    + if (handled == bytes) {
    + trace_kvm_io_done(vcpu->vcpu_id);
    return X86EMUL_CONTINUE;
    + }

    gpa += handled;
    bytes -= handled;
    @@ -4002,6 +4005,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_io_done(vcpu->vcpu_id);
    vcpu->arch.pio.count = 0;
    return 1;
    }
    @@ -4602,9 +4606,7 @@ restart:
    inject_emulated_exception(vcpu);
    r = EMULATE_DONE;
    } else if (vcpu->arch.pio.count) {
    - if (!vcpu->arch.pio.in)
    - vcpu->arch.pio.count = 0;
    - else
    + if (vcpu->arch.pio.in)
    writeback = false;
    r = EMULATE_DO_MMIO;
    } else if (vcpu->mmio_needed) {
    @@ -4635,8 +4637,6 @@ int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port)
    unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX);
    int ret = emulator_pio_out_emulated(&vcpu->arch.emulate_ctxt,
    size, port, &val, 1);
    - /* do not return to emulator after return from userspace */
    - vcpu->arch.pio.count = 0;
    return ret;
    }
    EXPORT_SYMBOL_GPL(kvm_fast_pio_out);
    @@ -5487,11 +5487,16 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
    {
    struct kvm_run *run = vcpu->run;
    struct kvm_mmio_fragment *frag;
    - int r;
    + int r = 1;

    if (!(vcpu->arch.pio.count || vcpu->mmio_needed))
    return 1;

    + if (vcpu->arch.pio.count && !vcpu->arch.pio.in) {
    + vcpu->arch.pio.count = 0;
    + goto exit;
    + }
    +
    if (vcpu->mmio_needed) {
    /* Complete previous fragment */
    frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++];
    @@ -5499,8 +5504,10 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
    memcpy(frag->data, run->mmio.data, frag->len);
    if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) {
    vcpu->mmio_needed = 0;
    +
    if (vcpu->mmio_is_write)
    - return 1;
    + goto exit;
    +
    vcpu->mmio_read_completed = 1;
    goto done;
    }
    @@ -5517,11 +5524,12 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
    }
    done:
    vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
    - r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
    + r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE) == EMULATE_DONE;
    srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
    - if (r != EMULATE_DONE)
    - return 0;
    - return 1;
    +
    +exit:
    + trace_kvm_io_done(vcpu->vcpu_id);
    + return r;
    }

    int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
    diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
    index 7ef9e75..5be5ad3 100644
    --- a/include/trace/events/kvm.h
    +++ b/include/trace/events/kvm.h
    @@ -177,6 +177,43 @@ TRACE_EVENT(kvm_mmio,
    __entry->len, __entry->gpa, __entry->val)
    );

    +TRACE_EVENT(kvm_mmio_begin,
    + TP_PROTO(unsigned int vcpu_id, bool rw, u64 gpa),
    + TP_ARGS(vcpu_id, rw, gpa),
    +
    + TP_STRUCT__entry(
    + __field(unsigned int, vcpu_id)
    + __field(int, type)
    + __field(u64, gpa)
    + ),
    +
    + TP_fast_assign(
    + __entry->vcpu_id = vcpu_id;
    + __entry->type = rw ? KVM_TRACE_MMIO_WRITE :
    + KVM_TRACE_MMIO_READ;
    + __entry->gpa = gpa;
    + ),
    +
    + TP_printk("vcpu %u mmio %s gpa 0x%llx", __entry->vcpu_id,
    + __print_symbolic(__entry->type, kvm_trace_symbol_mmio),
    + __entry->gpa)
    +);
    +
    +TRACE_EVENT(kvm_io_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"}
    --
    1.7.2.5


    \
     
     \ /
      Last update: 2012-08-10 06:01    [W:0.039 / U:0.088 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site