x86/kvm: Support the vCPU preemption check
authorPan Xinhui <xinhui.pan@linux.vnet.ibm.com>
Wed, 2 Nov 2016 09:08:35 +0000 (05:08 -0400)
committerIngo Molnar <mingo@kernel.org>
Tue, 22 Nov 2016 11:48:08 +0000 (12:48 +0100)
Support the vcpu_is_preempted() functionality under KVM. This will
enhance lock performance on overcommitted hosts (more runnable vCPUs
than physical CPUs in the system) as doing busy waits for preempted
vCPUs will hurt system performance far worse than early yielding.

Use struct kvm_steal_time::preempted to indicate that if a vCPU
is running or not.

Signed-off-by: Pan Xinhui <xinhui.pan@linux.vnet.ibm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Cc: David.Laight@ACULAB.COM
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: benh@kernel.crashing.org
Cc: boqun.feng@gmail.com
Cc: borntraeger@de.ibm.com
Cc: bsingharora@gmail.com
Cc: dave@stgolabs.net
Cc: jgross@suse.com
Cc: kernellwp@gmail.com
Cc: konrad.wilk@oracle.com
Cc: linuxppc-dev@lists.ozlabs.org
Cc: mpe@ellerman.id.au
Cc: paulmck@linux.vnet.ibm.com
Cc: paulus@samba.org
Cc: rkrcmar@redhat.com
Cc: virtualization@lists.linux-foundation.org
Cc: will.deacon@arm.com
Cc: xen-devel-request@lists.xenproject.org
Cc: xen-devel@lists.xenproject.org
Link: http://lkml.kernel.org/r/1478077718-37424-9-git-send-email-xinhui.pan@linux.vnet.ibm.com
[ Typo fixes. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/include/uapi/asm/kvm_para.h
arch/x86/kvm/x86.c

index 94dc8ca434e0863c5170d6bf44afa8860cfbf857..1421a6585126bca1da9c46d247addc3104f321e2 100644 (file)
@@ -45,7 +45,9 @@ struct kvm_steal_time {
        __u64 steal;
        __u32 version;
        __u32 flags;
-       __u32 pad[12];
+       __u8  preempted;
+       __u8  u8_pad[3];
+       __u32 pad[11];
 };
 
 #define KVM_STEAL_ALIGNMENT_BITS 5
index 04c5d96b1d678a6eeec993b71efb93f509496bdf..59c2d6f1b13153f5842dde2357f48a49e5001c73 100644 (file)
@@ -2071,6 +2071,8 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
                &vcpu->arch.st.steal, sizeof(struct kvm_steal_time))))
                return;
 
+       vcpu->arch.st.steal.preempted = 0;
+
        if (vcpu->arch.st.steal.version & 1)
                vcpu->arch.st.steal.version += 1;  /* first time write, random junk */
 
@@ -2826,8 +2828,22 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
 }
 
+static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu)
+{
+       if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
+               return;
+
+       vcpu->arch.st.steal.preempted = 1;
+
+       kvm_write_guest_offset_cached(vcpu->kvm, &vcpu->arch.st.stime,
+                       &vcpu->arch.st.steal.preempted,
+                       offsetof(struct kvm_steal_time, preempted),
+                       sizeof(vcpu->arch.st.steal.preempted));
+}
+
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
+       kvm_steal_time_set_preempted(vcpu);
        kvm_x86_ops->vcpu_put(vcpu);
        kvm_put_guest_fpu(vcpu);
        vcpu->arch.last_host_tsc = rdtsc();