From: Wanpeng Li <[email protected]>

preempted_in_kernel is updated in preempt_notifier when involuntary preemption
ocurrs, it can be stale when the voluntarily preempted vCPUs are taken into
account by kvm_vcpu_on_spin() loop. This patch lets it just check 
preempted_in_kernel
for involuntary preemption.

Cc: Paolo Bonzini <[email protected]>
Cc: Radim Krčmář <[email protected]>
Signed-off-by: Wanpeng Li <[email protected]>
---
 virt/kvm/kvm_main.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index e121423..2ae9e84 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2522,7 +2522,8 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool 
yield_to_kernel_mode)
                                continue;
                        if (swait_active(&vcpu->wq) && !vcpu_runnable(vcpu))
                                continue;
-                       if (yield_to_kernel_mode && 
!kvm_arch_vcpu_in_kernel(vcpu))
+                       if (READ_ONCE(vcpu->preempted) && yield_to_kernel_mode 
&&
+                               !kvm_arch_vcpu_in_kernel(vcpu))
                                continue;
                        if (!kvm_vcpu_eligible_for_directed_yield(vcpu))
                                continue;
@@ -4219,7 +4220,7 @@ static void kvm_sched_in(struct preempt_notifier *pn, int 
cpu)
 {
        struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn);
 
-       vcpu->preempted = false;
+       WRITE_ONCE(vcpu->preempted, false);
        WRITE_ONCE(vcpu->ready, false);
 
        kvm_arch_sched_in(vcpu, cpu);
@@ -4233,7 +4234,7 @@ static void kvm_sched_out(struct preempt_notifier *pn,
        struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn);
 
        if (current->state == TASK_RUNNING) {
-               vcpu->preempted = true;
+               WRITE_ONCE(vcpu->preempted, true);
                WRITE_ONCE(vcpu->ready, true);
        }
        kvm_arch_vcpu_put(vcpu);
-- 
2.7.4

Reply via email to