From: Joerg Roedel <[email protected]>

Onlyh one struct kvm_vcpu across all planes can be in a spin-loop.
Move the state to struct kvm_vcpu_common to make detection independent
of the active struct kvm_vcpu.

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

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 9220c452aa3a..f6e8a0b653b3 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -350,6 +350,20 @@ struct kvm_vcpu_common {
        rwlock_t pid_lock;
        int sigset_active;
        sigset_t sigset;
+       unsigned int halt_poll_ns;
+
+#ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT
+       /*
+        * Cpu relax intercept or pause loop exit optimization
+        * in_spin_loop: set when a vcpu does a pause loop exit
+        *  or cpu relax intercepted.
+        * dy_eligible: indicates whether vcpu is eligible for directed yield.
+        */
+       struct {
+               bool in_spin_loop;
+               bool dy_eligible;
+       } spin_loop;
+#endif
 
        /* Scheduling state */
 #ifdef CONFIG_PREEMPT_NOTIFIERS
@@ -373,8 +387,6 @@ struct kvm_vcpu {
 
        struct kvm_run *run;
 
-       unsigned int halt_poll_ns;
-
        u64 plane_requests;
 
        /* S390 only */
@@ -398,18 +410,6 @@ struct kvm_vcpu {
        } async_pf;
 #endif
 
-#ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT
-       /*
-        * Cpu relax intercept or pause loop exit optimization
-        * in_spin_loop: set when a vcpu does a pause loop exit
-        *  or cpu relax intercepted.
-        * dy_eligible: indicates whether vcpu is eligible for directed yield.
-        */
-       struct {
-               bool in_spin_loop;
-               bool dy_eligible;
-       } spin_loop;
-#endif
        struct kvm_vcpu_arch arch;
        struct kvm_vcpu_stat stat;
        char stats_id[KVM_STATS_NAME_SIZE];
@@ -2500,11 +2500,11 @@ extern struct kvm_device_ops kvm_arm_vgic_v5_ops;
 
 static inline void kvm_vcpu_set_in_spin_loop(struct kvm_vcpu *vcpu, bool val)
 {
-       vcpu->spin_loop.in_spin_loop = val;
+       vcpu->common->spin_loop.in_spin_loop = val;
 }
 static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
 {
-       vcpu->spin_loop.dy_eligible = val;
+       vcpu->common->spin_loop.dy_eligible = val;
 }
 
 #else /* !CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 1858880ee3d3..24ff8748a317 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -485,6 +485,9 @@ static int kvm_vcpu_init_common(struct kvm_vcpu *vcpu, 
struct kvm *kvm, unsigned
 
        vcpu->common = no_free_ptr(common);
 
+       kvm_vcpu_set_in_spin_loop(vcpu, false);
+       kvm_vcpu_set_dy_eligible(vcpu, false);
+
        return 0;
 
 out_drop_counter:
@@ -515,8 +518,6 @@ static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm 
*kvm, unsigned id)
        vcpu->vcpu_id = id;
        kvm_async_pf_vcpu_init(vcpu);
 
-       kvm_vcpu_set_in_spin_loop(vcpu, false);
-       kvm_vcpu_set_dy_eligible(vcpu, false);
        vcpu->last_used_slot = NULL;
 
        vcpu->plane_level = 0;
@@ -3721,9 +3722,10 @@ void kvm_sigset_deactivate(struct kvm_vcpu *vcpu)
 
 static void grow_halt_poll_ns(struct kvm_vcpu *vcpu)
 {
+       struct kvm_vcpu_common *common = vcpu->common;
        unsigned int old, val, grow, grow_start;
 
-       old = val = vcpu->halt_poll_ns;
+       old = val = common->halt_poll_ns;
        grow_start = READ_ONCE(halt_poll_ns_grow_start);
        grow = READ_ONCE(halt_poll_ns_grow);
        if (!grow)
@@ -3733,16 +3735,17 @@ static void grow_halt_poll_ns(struct kvm_vcpu *vcpu)
        if (val < grow_start)
                val = grow_start;
 
-       vcpu->halt_poll_ns = val;
+       common->halt_poll_ns = val;
 out:
        trace_kvm_halt_poll_ns_grow(vcpu->vcpu_id, val, old);
 }
 
 static void shrink_halt_poll_ns(struct kvm_vcpu *vcpu)
 {
+       struct kvm_vcpu_common *common = vcpu->common;
        unsigned int old, val, shrink, grow_start;
 
-       old = val = vcpu->halt_poll_ns;
+       old = val = common->halt_poll_ns;
        shrink = READ_ONCE(halt_poll_ns_shrink);
        grow_start = READ_ONCE(halt_poll_ns_grow_start);
        if (shrink == 0)
@@ -3753,7 +3756,7 @@ static void shrink_halt_poll_ns(struct kvm_vcpu *vcpu)
        if (val < grow_start)
                val = 0;
 
-       vcpu->halt_poll_ns = val;
+       common->halt_poll_ns = val;
        trace_kvm_halt_poll_ns_shrink(vcpu->vcpu_id, val, old);
 }
 
@@ -3864,19 +3867,20 @@ void kvm_vcpu_halt(struct kvm_vcpu *vcpu)
 {
        unsigned int max_halt_poll_ns = kvm_vcpu_max_halt_poll_ns(vcpu);
        bool halt_poll_allowed = !kvm_arch_no_poll(vcpu);
+       struct kvm_vcpu_common *common = vcpu->common;
        ktime_t start, cur, poll_end;
        bool waited = false;
        bool do_halt_poll;
        u64 halt_ns;
 
-       if (vcpu->halt_poll_ns > max_halt_poll_ns)
-               vcpu->halt_poll_ns = max_halt_poll_ns;
+       if (common->halt_poll_ns > max_halt_poll_ns)
+               common->halt_poll_ns = max_halt_poll_ns;
 
-       do_halt_poll = halt_poll_allowed && vcpu->halt_poll_ns;
+       do_halt_poll = halt_poll_allowed && common->halt_poll_ns;
 
        start = cur = poll_end = ktime_get();
        if (do_halt_poll) {
-               ktime_t stop = ktime_add_ns(start, vcpu->halt_poll_ns);
+               ktime_t stop = ktime_add_ns(start, common->halt_poll_ns);
 
                do {
                        if (kvm_vcpu_check_block(vcpu) < 0)
@@ -3914,18 +3918,18 @@ void kvm_vcpu_halt(struct kvm_vcpu *vcpu)
                if (!vcpu_valid_wakeup(vcpu)) {
                        shrink_halt_poll_ns(vcpu);
                } else if (max_halt_poll_ns) {
-                       if (halt_ns <= vcpu->halt_poll_ns)
+                       if (halt_ns <= common->halt_poll_ns)
                                ;
                        /* we had a long block, shrink polling */
-                       else if (vcpu->halt_poll_ns &&
+                       else if (common->halt_poll_ns &&
                                 halt_ns > max_halt_poll_ns)
                                shrink_halt_poll_ns(vcpu);
                        /* we had a short halt and our poll time is too small */
-                       else if (vcpu->halt_poll_ns < max_halt_poll_ns &&
+                       else if (common->halt_poll_ns < max_halt_poll_ns &&
                                 halt_ns < max_halt_poll_ns)
                                grow_halt_poll_ns(vcpu);
                } else {
-                       vcpu->halt_poll_ns = 0;
+                       common->halt_poll_ns = 0;
                }
        }
 
@@ -4046,13 +4050,14 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_vcpu_yield_to);
 static bool kvm_vcpu_eligible_for_directed_yield(struct kvm_vcpu *vcpu)
 {
 #ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT
+       struct kvm_vcpu_common *common = vcpu->common;
        bool eligible;
 
-       eligible = !vcpu->spin_loop.in_spin_loop ||
-                   vcpu->spin_loop.dy_eligible;
+       eligible = !common->spin_loop.in_spin_loop ||
+                   common->spin_loop.dy_eligible;
 
-       if (vcpu->spin_loop.in_spin_loop)
-               kvm_vcpu_set_dy_eligible(vcpu, !vcpu->spin_loop.dy_eligible);
+       if (common->spin_loop.in_spin_loop)
+               kvm_vcpu_set_dy_eligible(vcpu, !common->spin_loop.dy_eligible);
 
        return eligible;
 #else
-- 
2.53.0


Reply via email to