diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-07-16 17:04:54 -0400 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2014-07-23 18:01:46 -0400 |
commit | cbcf2dd3b3d4d990610259e8d878fc8dc1f17d80 (patch) | |
tree | 56a7086ddb4b6af2df797a2ad94581d258e42d16 /arch/x86/kvm | |
parent | bb0b58127c5add364cb597d58b1cf66eb279eae8 (diff) |
x86: kvm: Make kvm_get_time_and_clockread() nanoseconds based
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>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/x86.c | 44 |
1 files changed, 14 insertions, 30 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 65c430512132..63832f5110b6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -984,9 +984,8 @@ struct pvclock_gtod_data { | |||
984 | u32 shift; | 984 | u32 shift; |
985 | } clock; | 985 | } clock; |
986 | 986 | ||
987 | /* open coded 'struct timespec' */ | 987 | u64 boot_ns; |
988 | u64 monotonic_time_snsec; | 988 | u64 nsec_base; |
989 | time_t monotonic_time_sec; | ||
990 | }; | 989 | }; |
991 | 990 | ||
992 | static struct pvclock_gtod_data pvclock_gtod_data; | 991 | static struct pvclock_gtod_data pvclock_gtod_data; |
@@ -994,6 +993,9 @@ static struct pvclock_gtod_data pvclock_gtod_data; | |||
994 | static void update_pvclock_gtod(struct timekeeper *tk) | 993 | static void update_pvclock_gtod(struct timekeeper *tk) |
995 | { | 994 | { |
996 | struct pvclock_gtod_data *vdata = &pvclock_gtod_data; | 995 | struct pvclock_gtod_data *vdata = &pvclock_gtod_data; |
996 | u64 boot_ns; | ||
997 | |||
998 | boot_ns = ktime_to_ns(ktime_add(tk->base_mono, tk->offs_boot)); | ||
997 | 999 | ||
998 | write_seqcount_begin(&vdata->seq); | 1000 | write_seqcount_begin(&vdata->seq); |
999 | 1001 | ||
@@ -1004,17 +1006,8 @@ static void update_pvclock_gtod(struct timekeeper *tk) | |||
1004 | vdata->clock.mult = tk->mult; | 1006 | vdata->clock.mult = tk->mult; |
1005 | vdata->clock.shift = tk->shift; | 1007 | vdata->clock.shift = tk->shift; |
1006 | 1008 | ||
1007 | vdata->monotonic_time_sec = tk->xtime_sec | 1009 | vdata->boot_ns = boot_ns; |
1008 | + tk->wall_to_monotonic.tv_sec; | 1010 | vdata->nsec_base = tk->xtime_nsec; |
1009 | vdata->monotonic_time_snsec = tk->xtime_nsec | ||
1010 | + (tk->wall_to_monotonic.tv_nsec | ||
1011 | << tk->shift); | ||
1012 | while (vdata->monotonic_time_snsec >= | ||
1013 | (((u64)NSEC_PER_SEC) << tk->shift)) { | ||
1014 | vdata->monotonic_time_snsec -= | ||
1015 | ((u64)NSEC_PER_SEC) << tk->shift; | ||
1016 | vdata->monotonic_time_sec++; | ||
1017 | } | ||
1018 | 1011 | ||
1019 | write_seqcount_end(&vdata->seq); | 1012 | write_seqcount_end(&vdata->seq); |
1020 | } | 1013 | } |
@@ -1371,23 +1364,22 @@ static inline u64 vgettsc(cycle_t *cycle_now) | |||
1371 | return v * gtod->clock.mult; | 1364 | return v * gtod->clock.mult; |
1372 | } | 1365 | } |
1373 | 1366 | ||
1374 | static int do_monotonic(struct timespec *ts, cycle_t *cycle_now) | 1367 | static int do_monotonic_boot(s64 *t, cycle_t *cycle_now) |
1375 | { | 1368 | { |
1369 | struct pvclock_gtod_data *gtod = &pvclock_gtod_data; | ||
1376 | unsigned long seq; | 1370 | unsigned long seq; |
1377 | u64 ns; | ||
1378 | int mode; | 1371 | int mode; |
1379 | struct pvclock_gtod_data *gtod = &pvclock_gtod_data; | 1372 | u64 ns; |
1380 | 1373 | ||
1381 | ts->tv_nsec = 0; | ||
1382 | do { | 1374 | do { |
1383 | seq = read_seqcount_begin(>od->seq); | 1375 | seq = read_seqcount_begin(>od->seq); |
1384 | mode = gtod->clock.vclock_mode; | 1376 | mode = gtod->clock.vclock_mode; |
1385 | ts->tv_sec = gtod->monotonic_time_sec; | 1377 | ns = gtod->nsec_base; |
1386 | ns = gtod->monotonic_time_snsec; | ||
1387 | ns += vgettsc(cycle_now); | 1378 | ns += vgettsc(cycle_now); |
1388 | ns >>= gtod->clock.shift; | 1379 | ns >>= gtod->clock.shift; |
1380 | ns += gtod->boot_ns; | ||
1389 | } while (unlikely(read_seqcount_retry(>od->seq, seq))); | 1381 | } while (unlikely(read_seqcount_retry(>od->seq, seq))); |
1390 | timespec_add_ns(ts, ns); | 1382 | *t = ns; |
1391 | 1383 | ||
1392 | return mode; | 1384 | return mode; |
1393 | } | 1385 | } |
@@ -1395,19 +1387,11 @@ static int do_monotonic(struct timespec *ts, cycle_t *cycle_now) | |||
1395 | /* returns true if host is using tsc clocksource */ | 1387 | /* returns true if host is using tsc clocksource */ |
1396 | static bool kvm_get_time_and_clockread(s64 *kernel_ns, cycle_t *cycle_now) | 1388 | static bool kvm_get_time_and_clockread(s64 *kernel_ns, cycle_t *cycle_now) |
1397 | { | 1389 | { |
1398 | struct timespec ts; | ||
1399 | |||
1400 | /* checked again under seqlock below */ | 1390 | /* checked again under seqlock below */ |
1401 | if (pvclock_gtod_data.clock.vclock_mode != VCLOCK_TSC) | 1391 | if (pvclock_gtod_data.clock.vclock_mode != VCLOCK_TSC) |
1402 | return false; | 1392 | return false; |
1403 | 1393 | ||
1404 | if (do_monotonic(&ts, cycle_now) != VCLOCK_TSC) | 1394 | return do_monotonic_boot(kernel_ns, cycle_now) == VCLOCK_TSC; |
1405 | return false; | ||
1406 | |||
1407 | monotonic_to_bootbased(&ts); | ||
1408 | *kernel_ns = timespec_to_ns(&ts); | ||
1409 | |||
1410 | return true; | ||
1411 | } | 1395 | } |
1412 | #endif | 1396 | #endif |
1413 | 1397 | ||