KVM: fix tracing kvm_try_async_get_page
PATCH 1/8 KVM: fix tracing kvm_try_async_get_page
Tracing 'async' and *pfn is useless, since 'async' is always true, and '*pfn' is always "fault_pfn'
We can trace 'gva' and 'gfn' instead, it can help us to see the life-cycle of an async_pf
--- arch/x86/kvm/mmu.c | 2 +- include/trace/events/kvm.h | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-)
arch/x86/kvm/mmu.c +1 -1
@@ -2618,7 +2618,7 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool no_apf, gfn_t gfn,put_page (pfn_to_page (*pfn));if (!no_apf &&can_do_async_pf (vcpu)) { -trace_kvm_try_async_get_page (async, *pfn); +trace_kvm_try_async_get_page (gva, gfn);if (kvm_find_async_pf_gfn (vcpu, gfn)) {trace_kvm_async_pf_doublefault (gva, gfn);kvm_make_request (KVM_REQ_APF_HALT , vcpu);
include/trace/events/kvm.h +7 -5
@@ -188,18 +188,20 @@ TRACE_EVENT(kvm_age_page,#ifdef CONFIG_KVM_ASYNC_PF TRACE_EVENT ( kvm_try_async_get_page, - TP_PROTO(bool async, u64 pfn), -TP_ARGS (async, pfn), + TP_PROTO(u64 gva, u64 gfn), +TP_ARGS (gva, gfn),TP_STRUCT__entry ( -__field (__u64, pfn) + __field(u64, gva) +__field (u64, gfn) ),TP_fast_assign ( - __entry->pfn = (!async) ? pfn : (u64)-1; + __entry->gva = gva; + __entry->gfn = gfn; ), -TP_printk ("pfn %#llx" , __entry->pfn) +TP_printk ("gva = %#llx, gfn = %#llx" , __entry->gva, __entry->gfn) ); TRACE_EVENT(
Signature · 1 line
1.7.0.4
PATCH 2/8 KVM: cleanup aysnc_pf tracepoints
Use 'DECLARE_EVENT_CLASS' to cleanup async_pf tracepoints
--- include/trace/events/kvm.h | 76 ++++++++++++++++++++----------------------- 1 files changed, 35 insertions(+), 41 deletions(-)
include/trace/events/kvm.h +35 -41
@@ -186,59 +186,71 @@ TRACE_EVENT(kvm_age_page, );#ifdef CONFIG_KVM_ASYNC_PF -TRACE_EVENT ( - kvm_try_async_get_page, +DECLARE_EVENT_CLASS (kvm_async_get_page_class, + TP_PROTO(u64 gva, u64 gfn), +TP_ARGS (gva, gfn),TP_STRUCT__entry ( - __field(u64, gva) + __field(__u64, gva)__field (u64, gfn) - ), + ),TP_fast_assign ( __entry->gva = gva; __entry->gfn = gfn; - ), + ),TP_printk ("gva = %#llx, gfn = %#llx" , __entry->gva, __entry->gfn) ); -TRACE_EVENT ( - kvm_async_pf_not_present, +DEFINE_EVENT (kvm_async_get_page_class, kvm_try_async_get_page, + + TP_PROTO(u64 gva, u64 gfn), + +TP_ARGS (gva, gfn) +); + +DEFINE_EVENT (kvm_async_get_page_class, kvm_async_pf_doublefault, + + TP_PROTO(u64 gva, u64 gfn), + +TP_ARGS (gva, gfn) +); + +DECLARE_EVENT_CLASS (kvm_async_pf_nopresent_ready, + TP_PROTO(u64 token, u64 gva), +TP_ARGS (token, gva),TP_STRUCT__entry ( __field(__u64, token)__field (__u64, gva) - ), + ),TP_fast_assign ( __entry->token = token; __entry->gva = gva; - ), + ), + +TP_printk ("token %#llx gva %#llx" , __entry->token, __entry->gva) -TP_printk ("token %#llx gva %#llx not present" , __entry->token, - __entry->gva) ); -TRACE_EVENT ( - kvm_async_pf_ready, +DEFINE_EVENT (kvm_async_pf_nopresent_ready, kvm_async_pf_not_present, + TP_PROTO(u64 token, u64 gva), -TP_ARGS (token, gva), -TP_STRUCT__entry ( - __field(__u64, token) -__field (__u64, gva) - ), +TP_ARGS (token, gva) +); -TP_fast_assign ( - __entry->token = token; - __entry->gva = gva; - ), +DEFINE_EVENT (kvm_async_pf_nopresent_ready, kvm_async_pf_ready, + + TP_PROTO(u64 token, u64 gva), -TP_printk ("token %#llx gva %#llx ready" , __entry->token, __entry->gva) +TP_ARGS (token, gva) ); TRACE_EVENT(
@@ -262,24 +274,6 @@ TRACE_EVENT( __entry->address, __entry->pfn) ); -TRACE_EVENT ( - kvm_async_pf_doublefault, - TP_PROTO(u64 gva, u64 gfn), -TP_ARGS (gva, gfn), - -TP_STRUCT__entry ( - __field(u64, gva) -__field (u64, gfn) - ), - -TP_fast_assign ( - __entry->gva = gva; - __entry->gfn = gfn; - ), - -TP_printk ("gva = %#llx, gfn = %#llx" , __entry->gva, __entry->gfn) -); -#endif #endif /* _TRACE_KVM_MAIN_H */
Signature · 1 line
1.7.0.4
Re: [PATCH 2/8] KVM: cleanup aysnc_pf tracepoints
Quoted 3 lines · Xiao Guangrong
Use '
DECLARE_EVENT_CLASS' to cleanupasync_pftracepointsSigned-off-by Xiao Guangrong <[email protected]>
Nice
Quoted 136 lines
--- include/trace/events/kvm.h | 76 ++++++++++++++++++++----------------------- 1 files changed, 35 insertions(+), 41 deletions(-)include/trace/events/kvm.h +35
-41@@ -186,59 +186,71 @@ TRACE_EVENT(kvm_age_page, );#ifdef CONFIG_KVM_ASYNC_PF -TRACE_EVENT ( - kvm_try_async_get_page, +DECLARE_EVENT_CLASS (kvm_async_get_page_class, + TP_PROTO(u64 gva, u64 gfn), +TP_ARGS (gva, gfn),TP_STRUCT__entry ( - __field(u64, gva) + __field(__u64, gva)__field (u64, gfn) - ), + ),TP_fast_assign ( __entry->gva = gva; __entry->gfn = gfn; - ), + ),TP_printk ("gva = %#llx, gfn = %#llx" , __entry->gva, __entry->gfn) ); -TRACE_EVENT ( - kvm_async_pf_not_present, +DEFINE_EVENT (kvm_async_get_page_class, kvm_try_async_get_page, + + TP_PROTO(u64 gva, u64 gfn), + +TP_ARGS (gva, gfn) +); + +DEFINE_EVENT (kvm_async_get_page_class, kvm_async_pf_doublefault, + + TP_PROTO(u64 gva, u64 gfn), + +TP_ARGS (gva, gfn) +); + +DECLARE_EVENT_CLASS (kvm_async_pf_nopresent_ready, + TP_PROTO(u64 token, u64 gva), +TP_ARGS (token, gva),TP_STRUCT__entry ( __field(__u64, token)__field (__u64, gva) - ), + ),TP_fast_assign ( __entry->token = token; __entry->gva = gva; - ), + ), + +TP_printk ("token %#llx gva %#llx" , __entry->token, __entry->gva) -TP_printk ("token %#llx gva %#llx not present" , __entry->token, - __entry->gva) ); -TRACE_EVENT ( - kvm_async_pf_ready, +DEFINE_EVENT (kvm_async_pf_nopresent_ready, kvm_async_pf_not_present, + TP_PROTO(u64 token, u64 gva), -TP_ARGS (token, gva), -TP_STRUCT__entry ( - __field(__u64, token) -__field (__u64, gva) - ), +TP_ARGS (token, gva) +); -TP_fast_assign ( - __entry->token = token; - __entry->gva = gva; - ), +DEFINE_EVENT (kvm_async_pf_nopresent_ready, kvm_async_pf_ready, + + TP_PROTO(u64 token, u64 gva), -TP_printk ("token %#llx gva %#llx ready" , __entry->token, __entry->gva) +TP_ARGS (token, gva) ); TRACE_EVENT(@@ -262,24 +274,6 @@ TRACE_EVENT( __entry->address, __entry->pfn) ); -TRACE_EVENT ( - kvm_async_pf_doublefault, - TP_PROTO(u64 gva, u64 gfn), -TP_ARGS (gva, gfn), - -TP_STRUCT__entry ( - __field(u64, gva) -__field (u64, gfn) - ), - -TP_fast_assign ( - __entry->gva = gva; - __entry->gfn = gfn; - ), - -TP_printk ("gva = %#llx, gfn = %#llx" , __entry->gva, __entry->gfn) -); -#endif #endif /* _TRACE_KVM_MAIN_H */ Signature · 7 lines
1.7.0.4 -- 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/
--
Gleb.
PATCH 3/8 KVM: fix searching async gfn in kvm_async_pf_gfn_slot
In reply to Xiao GuangrongThe 'gfn' is not recorded if the next slot is empty
--- arch/x86/kvm/x86.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/x86.c +2 -2
@@ -6207,8 +6207,8 @@ static u32 kvm_async_pf_gfn_slot(struct kvm_vcpu *vcpu, gfn_t gfn)u32 key =kvm_async_pf_hash_fn (gfn);for (i =0 ; i <roundup_pow_of_two (ASYNC_PF_PER_VCPU ) && - (vcpu->arch.apf.gfns[key] != gfn || - vcpu->arch.apf.gfns[key] == ~0 ); i++) + (vcpu->arch.apf.gfns[key] != gfn && + vcpu->arch.apf.gfns[key] != ~0 ); i++) key =kvm_async_pf_next_probe (key);return key;
Signature · 1 line
1.7.0.4
Re: [PATCH 3/8] KVM: fix searching async gfn in kvm_async_pf_gfn_slot
Quoted 2 lines · Xiao Guangrong
The 'gfn' is not recorded if the next slot is empty
This function is not used for gfn recording, only to search for recorded gfn, but without the fix it walks over all entries if gfn is not in the hash.
Quoted 1 line
Signed-off-by Xiao Guangrong <[email protected]>
Quoted 27 lines
--- arch/x86/kvm/x86.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)arch/x86/kvm/x86.c +2
-2@@ -6207,8 +6207,8 @@ static u32 kvm_async_pf_gfn_slot(struct kvm_vcpu *vcpu, gfn_t gfn)u32 key =kvm_async_pf_hash_fn (gfn);for (i =0 ; i <roundup_pow_of_two (ASYNC_PF_PER_VCPU ) && - (vcpu->arch.apf.gfns[key] != gfn || - vcpu->arch.apf.gfns[key] == ~0 ); i++) + (vcpu->arch.apf.gfns[key] != gfn && + vcpu->arch.apf.gfns[key] != ~0 ); i++) key =kvm_async_pf_next_probe (key);return key;Signature · 7 lines
1.7.0.4 -- 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/
--
Gleb.
PATCH 4/8 KVM: avoid unnecessary wait for a async pf
In reply to Xiao GuangrongIn current code, it checks async pf completion out of the wait context, like this:
if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
!vcpu->arch.apf.halted)
r = vcpu_enter_guest(vcpu);
else {
......
kvm_vcpu_block(vcpu)
^- waiting until 'async_pf.done' is not empty
}kvm_check_async_pf_completion(vcpu)
^- delete list from async_pf.done
So, if we check aysnc pf completion first, it can be blocked at kvm_vcpu_block
Fixed by move the check into wait context
--- arch/x86/kvm/x86.c | 3 --- include/linux/kvm_host.h | 1 - virt/kvm/async_pf.c | 6 ++++-- virt/kvm/async_pf.h | 6 ++++++ virt/kvm/kvm_main.c | 3 ++- 5 files changed, 12 insertions(+), 7 deletions(-)
arch/x86/kvm/x86.c +0 -3
@@ -5321,8 +5321,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) vcpu->run->exit_reason =KVM_EXIT_INTR ; ++vcpu->stat.request_irq_exits; } - -kvm_check_async_pf_completion (vcpu);if (signal_pending (current)) { r = -EINTR ;
@@ -6108,7 +6106,6 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) {return (vcpu->arch.mp_state ==KVM_MP_STATE_RUNNABLE && !vcpu->arch.apf.halted) - || !list_empty_careful (&vcpu->async_pf.done) || vcpu->arch.mp_state ==KVM_MP_STATE_SIPI_RECEIVED || vcpu->arch.nmi_pending || (kvm_arch_interrupt_allowed(vcpu) &&
include/linux/kvm_host.h +0 -1
@@ -90,7 +90,6 @@ struct kvm_async_pf { };void kvm_clear_async_pf_completion_queue (struct kvm_vcpu *vcpu); -void kvm_check_async_pf_completion (struct kvm_vcpu *vcpu);int kvm_setup_async_pf (struct kvm_vcpu *vcpu,gva_t gva,gfn_t gfn,struct kvm_arch_async_pf *arch);int kvm_async_pf_wakeup_all (struct kvm_vcpu *vcpu);
virt/kvm/async_pf.c +4 -2
@@ -120,13 +120,13 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) vcpu->async_pf.queued =0 ; } -void kvm_check_async_pf_completion (struct kvm_vcpu *vcpu) +bool kvm_check_async_pf_completion (struct kvm_vcpu *vcpu) {struct kvm_async_pf *work;if (list_empty_careful (&vcpu->async_pf.done) || !kvm_arch_can_inject_async_page_present (vcpu)) -return ; +return false;spin_lock (&vcpu->async_pf.lock); work =list_first_entry (&vcpu->async_pf.done,typeof (*work), link);
@@ -142,6 +142,8 @@ void kvm_check_async_pf_completion(struct kvm_vcpu *vcpu)if (work->page)put_page (work->page);kmem_cache_free (async_pf_cache, work); + +return true; } int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn,
virt/kvm/async_pf.h +6 -0
@@ -27,10 +27,16 @@int kvm_async_pf_init (void );void kvm_async_pf_deinit (void );void kvm_async_pf_vcpu_init (struct kvm_vcpu *vcpu); +bool kvm_check_async_pf_completion (struct kvm_vcpu *vcpu); +#else #define kvm_async_pf_init () (0)#define kvm_async_pf_deinit () do{}while(0)#define kvm_async_pf_vcpu_init (C ) do{}while(0) +static inline bool kvm_check_async_pf_completion (struct kvm_vcpu *vcpu) +{ +return false; +}#endif #endif
virt/kvm/kvm_main.c +2 -1
@@ -1347,7 +1347,8 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)for (;;) {prepare_to_wait (&vcpu->wq, &wait,TASK_INTERRUPTIBLE ); -if (kvm_arch_vcpu_runnable (vcpu)) { +if (kvm_arch_vcpu_runnable (vcpu) || +kvm_check_async_pf_completion (vcpu)) {kvm_make_request (KVM_REQ_UNHALT , vcpu);break ; }
Signature · 1 line
1.7.0.4
Re: [PATCH 4/8] KVM: avoid unnecessary wait for a async pf
Quoted 12 lines · Xiao Guangrong
In current code, it checks async pf completion out of the wait context, like this:
if (
vcpu->arch.mp_state==KVM_MP_STATE_RUNNABLE&&!vcpu->arch.apf.halted) r = vcpu_enter_guest(vcpu); else { ...... kvm_vcpu_block(vcpu) ^- waiting until 'async_pf.done' is not empty }
Quoted 6 lines
kvm_check_async_pf_completion(vcpu)
^- delete list from async_pf.doneSo, if we check aysnc pf completion first, it can be blocked at
kvm_vcpu_block
Correct, but it can be fixed by adding vcpu->arch.apf.halted = false; to kvm_arch_async_page_present(), no?
Adding kvm_check_async_pf_completion() to arch independent kvm_vcpu_block() constrains how other archs may implement async pf support IMO.
Quoted 115 lines
Fixed by move the check into wait context
Signed-off-by Xiao Guangrong <[email protected]>--- arch/x86/kvm/x86.c | 3 --- include/linux/kvm_host.h | 1 - virt/kvm/async_pf.c | 6 ++++-- virt/kvm/async_pf.h | 6 ++++++ virt/kvm/kvm_main.c | 3 ++- 5 files changed, 12 insertions(+), 7 deletions(-)arch/x86/kvm/x86.c +0
-3@@ -5321,8 +5321,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) vcpu->run->exit_reason =KVM_EXIT_INTR ; ++vcpu->stat.request_irq_exits; } - -kvm_check_async_pf_completion (vcpu);if (signal_pending (current)) { r = -EINTR ;@@ -6108,7 +6106,6 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) {return (vcpu->arch.mp_state ==KVM_MP_STATE_RUNNABLE && !vcpu->arch.apf.halted) - || !list_empty_careful (&vcpu->async_pf.done) || vcpu->arch.mp_state ==KVM_MP_STATE_SIPI_RECEIVED || vcpu->arch.nmi_pending || (kvm_arch_interrupt_allowed(vcpu) &&include/linux/kvm_host.h +0
-1@@ -90,7 +90,6 @@ struct kvm_async_pf { };void kvm_clear_async_pf_completion_queue (struct kvm_vcpu *vcpu); -void kvm_check_async_pf_completion (struct kvm_vcpu *vcpu);int kvm_setup_async_pf (struct kvm_vcpu *vcpu,gva_t gva,gfn_t gfn,struct kvm_arch_async_pf *arch);int kvm_async_pf_wakeup_all (struct kvm_vcpu *vcpu);virt/kvm/async_pf.c +4
-2@@ -120,13 +120,13 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) vcpu->async_pf.queued =0 ; } -void kvm_check_async_pf_completion (struct kvm_vcpu *vcpu) +bool kvm_check_async_pf_completion (struct kvm_vcpu *vcpu) {struct kvm_async_pf *work;if (list_empty_careful (&vcpu->async_pf.done) || !kvm_arch_can_inject_async_page_present (vcpu)) -return ; +return false;spin_lock (&vcpu->async_pf.lock); work =list_first_entry (&vcpu->async_pf.done,typeof (*work), link);@@ -142,6 +142,8 @@ void kvm_check_async_pf_completion(struct kvm_vcpu *vcpu)if (work->page)put_page (work->page);kmem_cache_free (async_pf_cache, work); + +return true; } int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn,virt/kvm/async_pf.h +6
-0@@ -27,10 +27,16 @@int kvm_async_pf_init (void );void kvm_async_pf_deinit (void );void kvm_async_pf_vcpu_init (struct kvm_vcpu *vcpu); +bool kvm_check_async_pf_completion (struct kvm_vcpu *vcpu); +#else #define kvm_async_pf_init () (0)#define kvm_async_pf_deinit () do{}while(0)#define kvm_async_pf_vcpu_init (C ) do{}while(0) +static inline bool kvm_check_async_pf_completion (struct kvm_vcpu *vcpu) +{ +return false; +}#endif #endif virt/kvm/kvm_main.c +2
-1@@ -1347,7 +1347,8 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)for (;;) {prepare_to_wait (&vcpu->wq, &wait,TASK_INTERRUPTIBLE ); -if (kvm_arch_vcpu_runnable (vcpu)) { +if (kvm_arch_vcpu_runnable (vcpu) || +kvm_check_async_pf_completion (vcpu)) {kvm_make_request (KVM_REQ_UNHALT , vcpu);break ; }Signature · 6 lines
1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Gleb.
Re: [PATCH 4/8] KVM: avoid unnecessary wait for a async pf
Quoted 16 lines · Gleb Natapov
Quoted 15 lines · Xiao Guangrong
In current code, it checks async pf completion out of the wait context, like this:
if (
vcpu->arch.mp_state==KVM_MP_STATE_RUNNABLE&&!vcpu->arch.apf.halted) r = vcpu_enter_guest(vcpu); else { ...... kvm_vcpu_block(vcpu) ^- waiting until 'async_pf.done' is not empty }
kvm_check_async_pf_completion(vcpu)
^- delete list from async_pf.done
Quoted 8 lines
Quoted 3 lines
So, if we check aysnc pf completion first, it can be blocked at
kvm_vcpu_blockCorrect, but it can be fixed by adding
vcpu->arch.apf.halted= false; tokvm_arch_async_page_present(), no?
Addingkvm_check_async_pf_completion()to arch independentkvm_vcpu_block()constrains how other archs may implement async pf support IMO.
Um, i think it's reasonable, will fix it address your comment.
PATCH 5/8 KVM: don't touch vcpu stat after async pf is complete
In reply to Xiao GuangrongDon't make a KVM_REQ_UNHALT request after async pf is completed since it can break guest's 'halt' instruction.
--- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/x86.c | 5 +++++ virt/kvm/async_pf.c | 1 + virt/kvm/kvm_main.c | 7 +++++-- 4 files changed, 12 insertions(+), 2 deletions(-)
arch/x86/include/asm/kvm_host.h +1 -0
@@ -822,6 +822,7 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, struct kvm_async_pf *work);void kvm_arch_async_page_ready (struct kvm_vcpu *vcpu,struct kvm_async_pf *work); +void kvm_arch_async_pf_completion (struct kvm_vcpu *vcpu);bool kvm_arch_can_inject_async_page_present (struct kvm_vcpu *vcpu);extern bool kvm_find_async_pf_gfn (struct kvm_vcpu *vcpu,gfn_t gfn);
arch/x86/kvm/x86.c +5 -0
@@ -6280,6 +6280,11 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, } } +void kvm_arch_async_pf_completion (struct kvm_vcpu *vcpu) +{ + vcpu->arch.apf.halted = false; +} +bool kvm_arch_can_inject_async_page_present (struct kvm_vcpu *vcpu) {if (!(vcpu->arch.apf.msr_val &KVM_ASYNC_PF_ENABLED ))
virt/kvm/async_pf.c +1 -0
@@ -142,6 +142,7 @@ bool kvm_check_async_pf_completion(struct kvm_vcpu *vcpu)if (work->page)put_page (work->page);kmem_cache_free (async_pf_cache, work); +kvm_arch_async_pf_completion (vcpu);return true; }
virt/kvm/kvm_main.c +5 -2
@@ -1347,11 +1347,14 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)for (;;) {prepare_to_wait (&vcpu->wq, &wait,TASK_INTERRUPTIBLE ); -if (kvm_arch_vcpu_runnable (vcpu) || -kvm_check_async_pf_completion (vcpu)) { +if (kvm_arch_vcpu_runnable (vcpu)) {kvm_make_request (KVM_REQ_UNHALT , vcpu);break ; } + +if (kvm_check_async_pf_completion (vcpu)) +break ; +if (kvm_cpu_has_pending_timer (vcpu))break ;if (signal_pending (current))
Signature · 1 line
1.7.0.4
Re: [PATCH 5/8] KVM: don't touch vcpu stat after async pf is complete
Quoted 3 lines · Xiao Guangrong
Don't make a
KVM_REQ_UNHALTrequest after async pf is completed since it can break guest's 'halt' instruction.
Why is it a problem? CPU may be unhalted by different events so OS shouldn't depend on it.
Quoted 76 lines
Signed-off-by Xiao Guangrong <[email protected]>--- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/x86.c | 5 +++++ virt/kvm/async_pf.c | 1 + virt/kvm/kvm_main.c | 7 +++++-- 4 files changed, 12 insertions(+), 2 deletions(-)arch/x86/include/asm/kvm_host.h +1
-0@@ -822,6 +822,7 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, struct kvm_async_pf *work);void kvm_arch_async_page_ready (struct kvm_vcpu *vcpu,struct kvm_async_pf *work); +void kvm_arch_async_pf_completion (struct kvm_vcpu *vcpu);bool kvm_arch_can_inject_async_page_present (struct kvm_vcpu *vcpu);extern bool kvm_find_async_pf_gfn (struct kvm_vcpu *vcpu,gfn_t gfn);arch/x86/kvm/x86.c +5
-0@@ -6280,6 +6280,11 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, } } +void kvm_arch_async_pf_completion (struct kvm_vcpu *vcpu) +{ + vcpu->arch.apf.halted = false; +} +bool kvm_arch_can_inject_async_page_present (struct kvm_vcpu *vcpu) {if (!(vcpu->arch.apf.msr_val &KVM_ASYNC_PF_ENABLED ))virt/kvm/async_pf.c +1
-0@@ -142,6 +142,7 @@ bool kvm_check_async_pf_completion(struct kvm_vcpu *vcpu)if (work->page)put_page (work->page);kmem_cache_free (async_pf_cache, work); +kvm_arch_async_pf_completion (vcpu);return true; }virt/kvm/kvm_main.c +5
-2@@ -1347,11 +1347,14 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)for (;;) {prepare_to_wait (&vcpu->wq, &wait,TASK_INTERRUPTIBLE ); -if (kvm_arch_vcpu_runnable (vcpu) || -kvm_check_async_pf_completion (vcpu)) { +if (kvm_arch_vcpu_runnable (vcpu)) {kvm_make_request (KVM_REQ_UNHALT , vcpu);break ; } + +if (kvm_check_async_pf_completion (vcpu)) +break ; +if (kvm_cpu_has_pending_timer (vcpu))break ;if (signal_pending (current))Signature · 6 lines
1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Gleb.
Re: [PATCH 5/8] KVM: don't touch vcpu stat after async pf is complete
Quoted 7 lines · Gleb Natapov
Quoted 3 lines · Xiao Guangrong
Don't make a
KVM_REQ_UNHALTrequest after async pf is completed since it can break guest's 'halt' instruction.Why is it a problem? CPU may be unhalted by different events so OS shouldn't depend on it.
We don't know how guest OS handles it after HLT instruction is completed, according to X86's spec, only NMI/INTR/RESET/INIT/SMI can break halt state, it violations the hardware behavior if we allow other event break this state. Your opinion? :-)
Re: [PATCH 5/8] KVM: don't touch vcpu stat after async pf is complete
Quoted 5 lines · Xiao Guangrong
Quoted 4 lines · Gleb Natapov
Quoted 3 lines · Xiao Guangrong
Don't make a
KVM_REQ_UNHALTrequest after async pf is completed since it can break guest's 'halt' instruction.
Quoted 8 lines
Quoted 3 lines
Why is it a problem? CPU may be unhalted by different events so OS shouldn't depend on it.
We don't know how guest OS handles it after HLT instruction is completed, according to X86's spec, only NMI/INTR/RESET/INIT/SMI can break halt state, it violations the hardware behavior if we allow other event break this state. Your opinion? :-)
I agree in principle, but since SMI (which is completely out of guest OS control) can cause CPU to exit halt, in practice OS can't rely on CPU to be unhalted only by events controlled by OS itself. In the past we had a bug that any timer even unhalted vcpu even when timer interrupt was masked. The only practical problem it caused was that vcpu that executed cli; 1: hlt; jmp 1b sequence still consumed host cpu time. That said I am not against fixing it if the fix is easy. Your current fix though relies on patch 4 that I have problem with.
--
Gleb.
PATCH 6/8 KVM: simply wakup async pf
In reply to Xiao GuangrongThe current way is queued a complete async pf with:
asyc_pf.page = bad_page async_pf.arch.gfn = 0
It has two problems while kvm_check_async_pf_completion handle this async_pf:
- since !async_pf.page, it can retry a pseudo #PF
- it can delete gfn 0 from vcpu->arch.apf.gfns[]
Actually, we can simply record this wakeup request and let kvm_check_async_pf_completion simply break the wait
--- include/linux/kvm_host.h | 1 + virt/kvm/async_pf.c | 21 ++++++--------------- 2 files changed, 7 insertions(+), 15 deletions(-)
include/linux/kvm_host.h +1 -0
@@ -131,6 +131,7 @@ struct kvm_vcpu {struct list_head queue;struct list_head done;spinlock_t lock; + bool wakeup; } async_pf;#endif
virt/kvm/async_pf.c +6 -15
@@ -124,6 +124,11 @@ bool kvm_check_async_pf_completion(struct kvm_vcpu *vcpu) {struct kvm_async_pf *work; +if (vcpu->async_pf.wakeup) { + vcpu->async_pf.wakeup = false; +return true; + } +if (list_empty_careful (&vcpu->async_pf.done) || !kvm_arch_can_inject_async_page_present (vcpu))return false;
@@ -197,20 +202,6 @@ retry_sync:int kvm_async_pf_wakeup_all (struct kvm_vcpu *vcpu) { -struct kvm_async_pf *work; - -if (!list_empty (&vcpu->async_pf.done)) -return 0 ; - - work =kmem_cache_zalloc (async_pf_cache,GFP_ATOMIC ); -if (!work) -return -ENOMEM ; - - work->page = bad_page; -get_page (bad_page); -INIT_LIST_HEAD (&work->queue);/* for list_del to work */ - -list_add_tail (&work->link, &vcpu->async_pf.done); - vcpu->async_pf.queued++; + vcpu->async_pf.wakeup = true;return 0 ; }
Signature · 1 line
1.7.0.4
Re: [PATCH 6/8] KVM: simply wakup async pf
Quoted 7 lines · Xiao Guangrong
The current way is queued a complete async pf with:
asyc_pf.page =bad_pageasync_pf.arch.gfn = 0It has two problems while
kvm_check_async_pf_completionhandle thisasync_pf:
- since !async_pf.page, it can retry a pseudo #PF
kvm_arch_async_page_ready checks for is_error_page()
Quoted 1 line
- it can delete gfn 0 from vcpu->arch.apf.gfns[]
kvm_arch_async_page_present() checks for is_error_page() too and, in case of PV guest, injects special token if it is true.
After your patch special token will not be injected and migration will not work.
Quoted 3 lines
Actually, we can simply record this wakeup request and let
kvm_check_async_pf_completionsimply break the wait
May be wakeup_all function naming is misleading. It means wake up all PV guest processes by sending broadcast async pf notification. It is not about waking host vcpu thread.
Quoted 63 lines
Signed-off-by Xiao Guangrong <[email protected]>--- include/linux/kvm_host.h | 1 + virt/kvm/async_pf.c | 21 ++++++--------------- 2 files changed, 7 insertions(+), 15 deletions(-)include/linux/kvm_host.h +1
-0@@ -131,6 +131,7 @@ struct kvm_vcpu {struct list_head queue;struct list_head done;spinlock_t lock; + bool wakeup; } async_pf;#endif virt/kvm/async_pf.c +6
-15@@ -124,6 +124,11 @@ bool kvm_check_async_pf_completion(struct kvm_vcpu *vcpu) {struct kvm_async_pf *work; +if (vcpu->async_pf.wakeup) { + vcpu->async_pf.wakeup = false; +return true; + } +if (list_empty_careful (&vcpu->async_pf.done) || !kvm_arch_can_inject_async_page_present (vcpu))return false;@@ -197,20 +202,6 @@ retry_sync:int kvm_async_pf_wakeup_all (struct kvm_vcpu *vcpu) { -struct kvm_async_pf *work; - -if (!list_empty (&vcpu->async_pf.done)) -return 0 ; - - work =kmem_cache_zalloc (async_pf_cache,GFP_ATOMIC ); -if (!work) -return -ENOMEM ; - - work->page = bad_page; -get_page (bad_page); -INIT_LIST_HEAD (&work->queue);/* for list_del to work */ - -list_add_tail (&work->link, &vcpu->async_pf.done); - vcpu->async_pf.queued++; + vcpu->async_pf.wakeup = true;return 0 ; }Signature · 6 lines
1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Gleb.
Re: [PATCH 6/8] KVM: simply wakup async pf
Quoted 5 lines · Gleb Natapov
Quoted 4 lines · Xiao Guangrong
The current way is queued a complete async pf with:
asyc_pf.page =bad_pageasync_pf.arch.gfn = 0
Quoted 9 lines
Quoted 3 lines
It has two problems while
kvm_check_async_pf_completionhandle thisasync_pf:
- since !async_pf.page, it can retry a pseudo #PF
kvm_arch_async_page_readychecks foris_error_page()Quoted 1 line
- it can delete gfn 0 from vcpu->arch.apf.gfns[]
kvm_arch_async_page_present()checks foris_error_page()too and, in case of PV guest, injects special token if it is true.
Ah, sorry for my stupid questions.
Quoted 10 lines
After your patch special token will not be injected and migration will not work.
Quoted 3 lines
Actually, we can simply record this wakeup request and let
kvm_check_async_pf_completionsimply break the waitMay be
wakeup_allfunction naming is misleading. It means wake up all PV guest processes by sending broadcast async pf notification. It is not about waking host vcpu thread.
I'm not good at the KVM PV way, i'll dig into it, please ignore this patch, thanks.
PATCH 7/8 KVM: make async_pf work queue lockless
In reply to Xiao GuangrongThe async_pf number is very few since only pending interrupt can let it re-enter to the guest mode.
During my test(Host 4 CPU + 4G, Guest 4 VCPU + 6G), it's no more than 10 requests in the system.
So, we can only increase the completion counter in the work queue context, and walk vcpu->async_pf.queue list to get all completed async_pf
--- include/linux/kvm_host.h | 4 +-- virt/kvm/async_pf.c | 50 +++++++++++++++++++-------------------------- 2 files changed, 22 insertions(+), 32 deletions(-)
include/linux/kvm_host.h +1 -3
@@ -78,7 +78,6 @@ int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, #ifdef CONFIG_KVM_ASYNC_PF struct kvm_async_pf { struct work_struct work; - struct list_head link; struct list_head queue; struct kvm_vcpu *vcpu; struct mm_struct *mm;
@@ -127,10 +126,9 @@ struct kvm_vcpu {#ifdef CONFIG_KVM_ASYNC_PF struct { +atomic_t done;u32 queued;struct list_head queue; -struct list_head done; -spinlock_t lock;bool wakeup; } async_pf;#endif
virt/kvm/async_pf.c +21 -29
93 lines not on this page · raw message
Signature · 1 line
1.7.0.4
Re: [PATCH 7/8] KVM: make async_pf work queue lockless
Quoted 10 lines · Xiao Guangrong
The
async_pfnumber is very few since only pending interrupt can let it re-enter to the guest mode.During my
test(Host 4 CPU + 4G, Guest 4 VCPU + 6G), it's no more than 10 requests in the system.So, we can only increase the completion counter in the work queue context, and walk
vcpu->async_pf.queuelist to get all completedasync_pf
That depends on the load. I used memory cgroups to create very big memory pressure and I saw hundreds of apfs per second. We shouldn't optimize for very low numbers. With vcpu->async_pf.queue having more then one element I am not sure your patch is beneficial.
Quoted 110 lines
Signed-off-by Xiao Guangrong <[email protected]>--- include/linux/kvm_host.h | 4 +-- virt/kvm/async_pf.c | 50 +++++++++++++++++++-------------------------- 2 files changed, 22 insertions(+), 32 deletions(-)include/linux/kvm_host.h +1
-3@@ -78,7 +78,6 @@ int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, #ifdef CONFIG_KVM_ASYNC_PF struct kvm_async_pf { struct work_struct work; - struct list_head link; struct list_head queue; struct kvm_vcpu *vcpu; struct mm_struct *mm;@@ -127,10 +126,9 @@ struct kvm_vcpu {#ifdef CONFIG_KVM_ASYNC_PF struct { +atomic_t done;u32 queued;struct list_head queue; -struct list_head done; -spinlock_t lock;bool wakeup; } async_pf;#endif virt/kvm/async_pf.c +10
-24@@ -49,9 +49,7 @@ void kvm_async_pf_deinit(void)void kvm_async_pf_vcpu_init (struct kvm_vcpu *vcpu) { -INIT_LIST_HEAD (&vcpu->async_pf.done);INIT_LIST_HEAD (&vcpu->async_pf.queue); -spin_lock_init (&vcpu->async_pf.lock); }static void async_pf_execute (struct work_struct *work)@@ -72,11 +70,9 @@ static void async_pf_execute(struct work_struct *work)up_read (&mm->mmap_sem);unuse_mm (mm); -spin_lock (&vcpu->async_pf.lock); -list_add_tail (&apf->link, &vcpu->async_pf.done); apf->page = page; apf->done = true; -spin_unlock (&vcpu->async_pf.lock); +atomic_inc (&vcpu->async_pf.done);/* * apf may be freed by kvm_check_async_pf_completion() after @@ -101,52 +97,48 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) typeof(*work), queue);cancel_work_sync (&work->work);list_del (&work->queue); -if (!work->done)/* work was canceled */ -kmem_cache_free (async_pf_cache, work); - } - -spin_lock (&vcpu->async_pf.lock); -while (!list_empty (&vcpu->async_pf.done)) { -struct kvm_async_pf *work = -list_entry (vcpu->async_pf.done.next, -typeof (*work), link); -list_del (&work->link);if (work->page)put_page (work->page);kmem_cache_free (async_pf_cache, work); } -spin_unlock (&vcpu->async_pf.lock); vcpu->async_pf.queued =0 ; +atomic_set (&vcpu->async_pf.done,0 ); }bool kvm_check_async_pf_completion (struct kvm_vcpu *vcpu) {struct kvm_async_pf *work; +struct list_head *pos, *temp;if (vcpu->async_pf.wakeup) { vcpu->async_pf.wakeup = false;return true; } -if (list_empty_careful (&vcpu->async_pf.done) || +if (!atomic_read (&vcpu->async_pf.done) || !kvm_arch_can_inject_async_page_present (vcpu))return false; -spin_lock (&vcpu->async_pf.lock); - work =list_first_entry (&vcpu->async_pf.done,typeof (*work), link); -list_del (&work->link); -spin_unlock (&vcpu->async_pf.lock); +list_for_each_safe (pos, temp, &vcpu->async_pf.queue) { + work =list_entry (pos,typeof (*work), queue); +if (!work->done) +continue ; -if (work->page) -kvm_arch_async_page_ready (vcpu, work); -kvm_arch_async_page_present (vcpu, work); +if (work->page) { +kvm_arch_async_page_ready (vcpu, work);
virt/kvm/async_pf.c void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) · line 139
Quoted 10 lines
virt/kvm/async_pf.c +10
-0+put_page (work->page); + } + +kvm_arch_async_page_present (vcpu, work); + +list_del (&work->queue); + vcpu->async_pf.queued--; +kmem_cache_free (async_pf_cache, work); +if (atomic_dec_and_test (&vcpu->async_pf.done)) +break ;
You should do atomic_dec() and always break. We cannot inject two apfs during one vcpu entry.
Quoted 18 lines
virt/kvm/async_pf.c +1
-5+ } -list_del (&work->queue); - vcpu->async_pf.queued--; -if (work->page) -put_page (work->page); -kmem_cache_free (async_pf_cache, work);kvm_arch_async_pf_completion (vcpu);return true;Signature · 7 lines
1.7.0.4 -- 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/
--
Gleb.
Re: [PATCH 7/8] KVM: make async_pf work queue lockless
Quoted 7 lines · Gleb Natapov
Quoted 6 lines · Xiao Guangrong
The
async_pfnumber is very few since only pending interrupt can let it re-enter to the guest mode.During my
test(Host 4 CPU + 4G, Guest 4 VCPU + 6G), it's no more than 10 requests in the system.
Quoted 9 lines
Quoted 4 lines
So, we can only increase the completion counter in the work queue context, and walk
vcpu->async_pf.queuelist to get all completedasync_pfThat depends on the load. I used memory cgroups to create very big memory pressure and I saw hundreds of apfs per second. We shouldn't optimize for very low numbers. With
vcpu->async_pf.queuehaving more then one element I am not sure your patch is beneficial.
Maybe we need a new no-lock way to record the complete apfs, i'll reproduce your test environment and improve it.
Quoted 9 lines
virt/kvm/async_pf.c void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) · line 139
Quoted 6 lines
virt/kvm/async_pf.c +6
-0+ +list_del (&work->queue); + vcpu->async_pf.queued--; +kmem_cache_free (async_pf_cache, work); +if (atomic_dec_and_test (&vcpu->async_pf.done)) +break ;You should do
atomic_dec()and always break. We cannot inject two apfs during one vcpu entry.
Sorry, i'm little confused.
Why 'atomic_dec_and_test(&vcpu->async_pf.done)' always break? async_pf.done is used to record the complete apfs and many apfs may be completed when vcpu enters guest mode(it means vcpu->async_pf.done > 1)
Look at the current code:
void kvm_check_async_pf_completion(struct kvm_vcpu *vcpu)
{
......
spin_lock(&vcpu->async_pf.lock);
work = list_first_entry(&vcpu->async_pf.done, typeof(*work), link);
list_del(&work->link);
spin_unlock(&vcpu->async_pf.lock);
......
}You only handle one complete apf, why we inject them at once? I missed something? :-(
Re: [PATCH 7/8] KVM: make async_pf work queue lockless
Quoted 12 lines · Xiao Guangrong
Quoted 11 lines · Gleb Natapov
Quoted 10 lines · Xiao Guangrong
The
async_pfnumber is very few since only pending interrupt can let it re-enter to the guest mode.During my
test(Host 4 CPU + 4G, Guest 4 VCPU + 6G), it's no more than 10 requests in the system.So, we can only increase the completion counter in the work queue context, and walk
vcpu->async_pf.queuelist to get all completedasync_pf
Quoted 9 lines
Quoted 5 lines
That depends on the load. I used memory cgroups to create very big memory pressure and I saw hundreds of apfs per second. We shouldn't optimize for very low numbers. With
vcpu->async_pf.queuehaving more then one element I am not sure your patch is beneficial.Maybe we need a new no-lock way to record the complete apfs, i'll reproduce your test environment and improve it.
That is always welcomed :)
Quoted 10 lines
Quoted 9 lines
virt/kvm/async_pf.c void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) · line 139
Quoted 6 lines
virt/kvm/async_pf.c +6
-0+ +list_del (&work->queue); + vcpu->async_pf.queued--; +kmem_cache_free (async_pf_cache, work); +if (atomic_dec_and_test (&vcpu->async_pf.done)) +break ;You should do
atomic_dec()and always break. We cannot inject two apfs during one vcpu entry.
Quoted 3 lines
Sorry, i'm little confused.
Why '
atomic_dec_and_test(&vcpu->async_pf.done)' always break? async_pf.done is used to
In your code it is not, but it should (at least if guest is PV, read below).
Quoted 3 lines
record the complete apfs and many apfs may be completed when vcpu enters guest
mode(it means vcpu->async_pf.done > 1)
Correct, but only one apf should be handled on each vcpu entry in case of PV guest. Look at kvm_arch_async_page_present(vcpu, work); that is called in a loop in your code. If vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED is not null it injects exception into the guest. You can't inject more then one exception on each guest entry. If guest is not PV you are correct that we can loop here until vcpu->async_pf.done == 0.
Quoted 12 lines
Look at the current code:
void
kvm_check_async_pf_completion(struct kvm_vcpu *vcpu){ ...... spin_lock(&vcpu->async_pf.lock); work = list_first_entry(&vcpu->async_pf.done, typeof(*work), link); list_del(&work->link); spin_unlock(&vcpu->async_pf.lock); ...... }
Quoted 1 line
You only handle one complete apf, why we inject them at once? I missed something? :-(
--
Gleb.
PATCH 8/8 KVM: add debugfs file to show the number of async pf
In reply to Xiao GuangrongIt can help us to see the state of async pf
--- arch/x86/kvm/x86.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
arch/x86/kvm/x86.c +3 -0
@@ -88,6 +88,8 @@ static u64 __read_mostly efer_reserved_bits = 0xfffffffffffffffeULL;#define VM_STAT (x) offsetof(struct kvm, stat.x), KVM_STAT_VM#define VCPU_STAT (x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU +#define VCPU_ASYNC_PF_STAT offsetof(struct kvm_vcpu, async_pf.queued), \ + KVM_STAT_VCPUstatic void update_cr8_intercept (struct kvm_vcpu *vcpu); static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
@@ -141,6 +143,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) }, { "irq_injections", VCPU_STAT(irq_injections) }, { "nmi_injections", VCPU_STAT(nmi_injections) }, + { "async_pf_queued", VCPU_ASYNC_PF_STAT}, { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) }, { "mmu_pte_write", VM_STAT(mmu_pte_write) }, { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
Signature · 1 line
1.7.0.4
Re: [PATCH 8/8] KVM: add debugfs file to show the number of async pf
Quoted 2 lines · Xiao Guangrong
It can help us to see the state of async pf
I have patch to add three async pf statistics:apf_not_presentapf_presentapf_doublefault
But Avi now wants to deprecate debugfs interface completely and move towards ftrace, so I had to drop it.
Quoted 33 lines
Signed-off-by Xiao Guangrong <[email protected]>--- arch/x86/kvm/x86.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)arch/x86/kvm/x86.c +3
-0@@ -88,6 +88,8 @@ static u64 __read_mostly efer_reserved_bits = 0xfffffffffffffffeULL;#define VM_STAT (x) offsetof(struct kvm, stat.x), KVM_STAT_VM#define VCPU_STAT (x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU +#define VCPU_ASYNC_PF_STAT offsetof(struct kvm_vcpu, async_pf.queued), \ + KVM_STAT_VCPUstatic void update_cr8_intercept (struct kvm_vcpu *vcpu); static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,@@ -141,6 +143,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) }, { "irq_injections", VCPU_STAT(irq_injections) }, { "nmi_injections", VCPU_STAT(nmi_injections) }, + { "async_pf_queued", VCPU_ASYNC_PF_STAT}, { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) }, { "mmu_pte_write", VM_STAT(mmu_pte_write) }, { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },Signature · 6 lines
1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Gleb.
Re: [PATCH 8/8] KVM: add debugfs file to show the number of async pf
Quoted 11 lines · Gleb Natapov
Quoted 2 lines · Xiao Guangrong
It can help us to see the state of async pf
I have patch to add three async pf statistics:
apf_not_presentapf_presentapf_doublefaultBut Avi now wants to deprecate debugfs interface completely and move towards ftrace, so I had to drop it.
OK, let's ignore this patch, thanks :-)
Quoted 6 lines · Xiao Guangrong
Tracing 'async' and *pfn is useless, since 'async' is always true, and '*pfn' is always "
fault_pfn'We can trace 'gva' and 'gfn' instead, it can help us to see the life-cycle of an
async_pf
Make sense. This is leftover from earlier patches iteration where this trace function was called when async==false too.
Quoted 56 lines
Signed-off-by Xiao Guangrong <[email protected]>--- arch/x86/kvm/mmu.c | 2 +- include/trace/events/kvm.h | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-)arch/x86/kvm/mmu.c +1
-1@@ -2618,7 +2618,7 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool no_apf, gfn_t gfn,put_page (pfn_to_page (*pfn));if (!no_apf &&can_do_async_pf (vcpu)) { -trace_kvm_try_async_get_page (async, *pfn); +trace_kvm_try_async_get_page (gva, gfn);if (kvm_find_async_pf_gfn (vcpu, gfn)) {trace_kvm_async_pf_doublefault (gva, gfn);kvm_make_request (KVM_REQ_APF_HALT , vcpu);include/trace/events/kvm.h +7
-5@@ -188,18 +188,20 @@ TRACE_EVENT(kvm_age_page,#ifdef CONFIG_KVM_ASYNC_PF TRACE_EVENT ( kvm_try_async_get_page, - TP_PROTO(bool async, u64 pfn), -TP_ARGS (async, pfn), + TP_PROTO(u64 gva, u64 gfn), +TP_ARGS (gva, gfn),TP_STRUCT__entry ( -__field (__u64, pfn) + __field(u64, gva) +__field (u64, gfn) ),TP_fast_assign ( - __entry->pfn = (!async) ? pfn : (u64)-1; + __entry->gva = gva; + __entry->gfn = gfn; ), -TP_printk ("pfn %#llx" , __entry->pfn) +TP_printk ("gva = %#llx, gfn = %#llx" , __entry->gva, __entry->gfn) ); TRACE_EVENT(Signature · 6 lines
1.7.0.4 -- 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/
--
Gleb.