From: Joerg Roedel <[email protected]>

The algorithm is to always run the lowest runnable plane. Plane
switches are done by stopping the current plane and setting another
runnable.

Signed-off-by: Joerg Roedel <[email protected]>
---
 include/linux/kvm_host.h | 16 ++++++++++++++
 virt/kvm/kvm_main.c      | 45 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 5c3f9dfa15ea..e3611e6cc3e4 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -168,6 +168,7 @@ static inline bool kvm_is_error_gpa(gpa_t gpa)
 #define KVM_REQ_VM_DEAD                        (1 | KVM_REQUEST_WAIT | 
KVM_REQUEST_NO_WAKEUP)
 #define KVM_REQ_UNBLOCK                        2
 #define KVM_REQ_DIRTY_RING_SOFT_FULL   3
+#define KVM_REQ_PLANE_RESCHED          4
 #define KVM_REQUEST_ARCH_BASE          8
 
 /*
@@ -324,6 +325,8 @@ struct kvm_mmio_fragment {
        unsigned int len;
 };
 
+
+
 struct kvm_vcpu_common {
        struct kvm *kvm;
 
@@ -381,6 +384,8 @@ struct kvm_vcpu_common {
 
        struct kvm_dirty_ring dirty_ring;
 
+       bool plane_switch;
+
        struct kvm_vcpu_arch_common arch;
 };
 
@@ -388,6 +393,12 @@ struct kvm_vcpu_common {
        for ((i) = 0; (i) < KVM_MAX_PLANES; ++(i))              \
                if (((v) = common->vcpus[(i)]) != NULL)
 
+/* Tracked per plane-VCPU - used for deciding which plane-vcpu to run */
+enum kvm_vcpu_state {
+       STOPPED,
+       RUNNABLE,
+};
+
 struct kvm_vcpu {
        struct kvm *kvm;
        struct kvm_plane *plane;
@@ -401,6 +412,7 @@ struct kvm_vcpu {
        struct kvm_run *run;
 
        u64 plane_requests;
+       enum kvm_vcpu_state plane_state;
 
        /* S390 only */
        bool valid_wakeup;
@@ -440,6 +452,10 @@ struct kvm_vcpu {
        unsigned plane_level;
 };
 
+void kvm_vcpu_set_plane_runnable(struct kvm_vcpu *vcpu);
+void kvm_vcpu_set_plane_stopped(struct kvm_vcpu *vcpu);
+struct kvm_vcpu *kvm_vcpu_select_plane(struct kvm_vcpu *vcpu);
+
 static inline bool kvm_vcpu_wants_to_run(struct kvm_vcpu *vcpu)
 {
        return vcpu->common->wants_to_run;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 9d30fd85ce5f..a30123b77112 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -4397,6 +4397,7 @@ static int kvm_plane_ioctl_create_vcpu(struct kvm_plane 
*plane, unsigned long id
        vcpu->vcpu_idx = vcpu->common->vcpu_idx;
        vcpu->plane = plane;
        vcpu->plane_level = plane->level;
+       vcpu->plane_state = STOPPED;
        vcpu->run = vcpu->common->run;
 
        kvm_vcpu_init(vcpu, kvm, id);
@@ -4938,6 +4939,50 @@ static struct file_operations kvm_plane_fops = {
        KVM_COMPAT(kvm_plane_ioctl),
 };
 
+void kvm_vcpu_set_plane_runnable(struct kvm_vcpu *vcpu)
+{
+       vcpu->plane_state = RUNNABLE;
+       vcpu->common->plane_switch = true;
+       kvm_make_request(KVM_REQ_PLANE_RESCHED, vcpu);
+}
+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_vcpu_set_plane_runnable);
+
+void kvm_vcpu_set_plane_stopped(struct kvm_vcpu *vcpu)
+{
+       vcpu->plane_state = STOPPED;
+       kvm_make_request(KVM_REQ_PLANE_RESCHED, vcpu);
+}
+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_vcpu_set_plane_stopped);
+
+struct kvm_vcpu *kvm_vcpu_select_plane(struct kvm_vcpu *vcpu)
+{
+       struct kvm_vcpu_common *common = vcpu->common;
+       struct kvm_vcpu *ret = NULL;
+       unsigned i;
+
+       for (i = 0; i < KVM_MAX_PLANES; i++) {
+               if (common->vcpus[i] == NULL)
+                       continue;
+
+               if (common->vcpus[i]->plane_state == RUNNABLE) {
+                       ret = common->vcpus[i];
+                       break;
+               }
+       }
+
+       if (ret == NULL) {
+               ret = common->vcpus[0];
+               ret->plane_state = RUNNABLE;
+       }
+
+       common->current_vcpu = ret;
+
+       common->plane_switch = false;
+
+       return ret;
+}
+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_vcpu_select_plane);
+
 static int kvm_device_mmap(struct file *filp, struct vm_area_struct *vma)
 {
        struct kvm_device *dev = filp->private_data;
-- 
2.53.0


Reply via email to