[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v7 07/36] KVM: x86: Restructure get_kvmclock()



From: David Woodhouse <dwmw@xxxxxxxxxxxx>

Wrap the entire use_master_clock block in #ifdef CONFIG_X86_64, since
use_master_clock is never true on 32-bit (host_tsc_clocksource is only
set under CONFIG_X86_64), and declare hv_clock inside the block so it is
not left as an unused variable on 32-bit.

Use 'continue' on the master-clock success path so the non-master-clock
computation becomes the common tail, avoiding a goto and label. When the
clock read fails (e.g. clocksource transitioning away from TSC), fall
back to that path rather than proceeding with uninitialised data or
spinning in the seqcount loop.

Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
---
 arch/x86/kvm/x86.c | 36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 590a7ba723f7..51908d7093ba 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1653,34 +1653,38 @@ static unsigned long get_cpu_tsc_khz(void)
 static void get_kvmclock(struct kvm *kvm, struct kvm_clock_data *data)
 {
        struct kvm_arch *ka = &kvm->arch;
-       struct pvclock_vcpu_time_info hv_clock;
        unsigned int seq;
 
        do {
                seq = read_seqcount_begin(&ka->pvclock_sc);
 
                data->flags = 0;
-               if (ka->use_master_clock) {
 #ifdef CONFIG_X86_64
+               if (ka->use_master_clock) {
+                       struct pvclock_vcpu_time_info hv_clock;
                        struct timespec64 ts;
 
                        if (kvm_get_walltime_and_clockread(&ts, 
&data->host_tsc)) {
                                data->realtime = ts.tv_nsec + NSEC_PER_SEC * 
ts.tv_sec;
-                               data->flags |= KVM_CLOCK_REALTIME | 
KVM_CLOCK_HOST_TSC;
-                       } else
-#endif
-                       data->host_tsc = rdtsc();
-
-                       data->flags |= KVM_CLOCK_TSC_STABLE;
-                       hv_clock.tsc_timestamp = ka->master_cycle_now;
-                       hv_clock.system_time = ka->master_kernel_ns + 
ka->kvmclock_offset;
-                       kvm_get_time_scale(NSEC_PER_SEC, get_cpu_tsc_khz() * 
1000LL,
-                                          &hv_clock.tsc_shift,
-                                          &hv_clock.tsc_to_system_mul);
-                       data->clock = __pvclock_read_cycles(&hv_clock, 
data->host_tsc);
-               } else {
-                       data->clock = get_kvmclock_base_ns() + 
ka->kvmclock_offset;
+                               data->flags |= KVM_CLOCK_REALTIME | 
KVM_CLOCK_HOST_TSC | KVM_CLOCK_TSC_STABLE;
+
+                               hv_clock.tsc_timestamp = ka->master_cycle_now;
+                               hv_clock.system_time = ka->master_kernel_ns + 
ka->kvmclock_offset;
+                               kvm_get_time_scale(NSEC_PER_SEC, 
get_cpu_tsc_khz() * 1000LL,
+                                                  &hv_clock.tsc_shift,
+                                                  &hv_clock.tsc_to_system_mul);
+                               data->clock = __pvclock_read_cycles(&hv_clock, 
data->host_tsc);
+                               continue;
+                       }
+
+                       /*
+                        * Clock read failed (e.g. clocksource is transitioning
+                        * away from TSC). Fall back to the non-master-clock 
path
+                        * rather than spinning.
+                        */
                }
+#endif
+               data->clock = get_kvmclock_base_ns() + ka->kvmclock_offset;
        } while (read_seqcount_retry(&ka->pvclock_sc, seq));
 }
 
-- 
2.55.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.