Skip to content

Commit

Permalink
x86: kvm: Make kvm_get_time_and_clockread() nanoseconds based
Browse files Browse the repository at this point in the history
Convert the relevant base data right away to nanoseconds instead of
doing the conversion on every readout. Reduces text size by 160 bytes.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Gleb Natapov <gleb@kernel.org>
Cc: kvm@vger.kernel.org
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
  • Loading branch information
Thomas Gleixner authored and John Stultz committed Jul 23, 2014
1 parent bb0b581 commit cbcf2dd
Showing 1 changed file with 14 additions and 30 deletions.
44 changes: 14 additions & 30 deletions arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -984,16 +984,18 @@ struct pvclock_gtod_data {
u32 shift;
} clock;

/* open coded 'struct timespec' */
u64 monotonic_time_snsec;
time_t monotonic_time_sec;
u64 boot_ns;
u64 nsec_base;
};

static struct pvclock_gtod_data pvclock_gtod_data;

static void update_pvclock_gtod(struct timekeeper *tk)
{
struct pvclock_gtod_data *vdata = &pvclock_gtod_data;
u64 boot_ns;

boot_ns = ktime_to_ns(ktime_add(tk->base_mono, tk->offs_boot));

write_seqcount_begin(&vdata->seq);

Expand All @@ -1004,17 +1006,8 @@ static void update_pvclock_gtod(struct timekeeper *tk)
vdata->clock.mult = tk->mult;
vdata->clock.shift = tk->shift;

vdata->monotonic_time_sec = tk->xtime_sec
+ tk->wall_to_monotonic.tv_sec;
vdata->monotonic_time_snsec = tk->xtime_nsec
+ (tk->wall_to_monotonic.tv_nsec
<< tk->shift);
while (vdata->monotonic_time_snsec >=
(((u64)NSEC_PER_SEC) << tk->shift)) {
vdata->monotonic_time_snsec -=
((u64)NSEC_PER_SEC) << tk->shift;
vdata->monotonic_time_sec++;
}
vdata->boot_ns = boot_ns;
vdata->nsec_base = tk->xtime_nsec;

write_seqcount_end(&vdata->seq);
}
Expand Down Expand Up @@ -1371,43 +1364,34 @@ static inline u64 vgettsc(cycle_t *cycle_now)
return v * gtod->clock.mult;
}

static int do_monotonic(struct timespec *ts, cycle_t *cycle_now)
static int do_monotonic_boot(s64 *t, cycle_t *cycle_now)
{
struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
unsigned long seq;
u64 ns;
int mode;
struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
u64 ns;

ts->tv_nsec = 0;
do {
seq = read_seqcount_begin(&gtod->seq);
mode = gtod->clock.vclock_mode;
ts->tv_sec = gtod->monotonic_time_sec;
ns = gtod->monotonic_time_snsec;
ns = gtod->nsec_base;
ns += vgettsc(cycle_now);
ns >>= gtod->clock.shift;
ns += gtod->boot_ns;
} while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
timespec_add_ns(ts, ns);
*t = ns;

return mode;
}

/* returns true if host is using tsc clocksource */
static bool kvm_get_time_and_clockread(s64 *kernel_ns, cycle_t *cycle_now)
{
struct timespec ts;

/* checked again under seqlock below */
if (pvclock_gtod_data.clock.vclock_mode != VCLOCK_TSC)
return false;

if (do_monotonic(&ts, cycle_now) != VCLOCK_TSC)
return false;

monotonic_to_bootbased(&ts);
*kernel_ns = timespec_to_ns(&ts);

return true;
return do_monotonic_boot(kernel_ns, cycle_now) == VCLOCK_TSC;
}
#endif

Expand Down

0 comments on commit cbcf2dd

Please sign in to comment.