# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1259674582 0
# Node ID f330d9edf67c0e225d1acabd2ec0e2e21ebfecac
# Parent d84edda40cb346463e370dce2d893a599aa44286
Report hardware tsc frequency even for emulated tsc
I was starting some documentation for tsc_mode and
realized this discussion was never resolved. Currently
when TSC is emulated the pvclock algorithm reports
to a PV OS Xen's system clock hz rate (1GHz). Linux
at boottime samples the TSC rate and shows it in
dmesg and the rate is also shown in the "cpu MHz"
field in /proc/cpuinfo. So when TSC is emulated,
it appears that the processor MHz is 1000.0, which
is likely to be confusing to many Xen users.
This patch changes the reported hz rate to the
hz rate of the initial machine on which the guest
is booted and retains that reported hz rate across
save/restore/migration.
Jeremy has pointed out that reporting 1000.0 MHz is
useful because it shows that TSC is being emulated.
However, with the new tsc_mode default where
a guest may start with native TSC and switch to
emulated TSC after migration, users are likely to
get even more confused. And "xm debug-key s"
reveals not only whether TSC is being emulated but
also the frequency so is more descriptive anyway.
Signed-off-by: Dan Magenheimer <dan.magenheimer@xxxxxxxxxx>
---
xen/arch/x86/time.c | 59 ++++++++++++----------------------------------------
1 files changed, 14 insertions(+), 45 deletions(-)
diff -r d84edda40cb3 -r f330d9edf67c xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Tue Dec 01 13:35:28 2009 +0000
+++ b/xen/arch/x86/time.c Tue Dec 01 13:36:22 2009 +0000
@@ -146,23 +146,7 @@ static inline u64 scale_delta(u64 delta,
return product;
}
-#define _TS_SHIFT_IDENTITY 1
#define _TS_MUL_FRAC_IDENTITY 0x80000000UL
-#define _TS_IDENTITY { _TS_SHIFT_IDENTITY, _TS_MUL_FRAC_IDENTITY }
-static inline int time_scale_is_identity(struct time_scale *ts)
-{
- if ( ts->shift != _TS_SHIFT_IDENTITY )
- return 0;
- else if ( ts->mul_frac != _TS_MUL_FRAC_IDENTITY )
- return 0;
- return 1;
-}
-
-static inline void set_time_scale_identity(struct time_scale *ts)
-{
- ts->shift = _TS_SHIFT_IDENTITY;
- ts->mul_frac = _TS_MUL_FRAC_IDENTITY;
-}
/* Compute the reciprocal of the given time_scale. */
static inline struct time_scale scale_reciprocal(struct time_scale scale)
@@ -843,11 +827,8 @@ static void __update_vcpu_system_time(st
u = &vcpu_info(v, time);
if ( d->arch.vtsc )
- {
- tsc_stamp = t->stime_local_stamp - d->arch.vtsc_offset;
- if ( !time_scale_is_identity(&d->arch.ns_to_vtsc) )
- tsc_stamp = scale_delta(tsc_stamp, &d->arch.ns_to_vtsc);
- }
+ tsc_stamp = scale_delta(t->stime_local_stamp - d->arch.vtsc_offset,
+ &d->arch.ns_to_vtsc);
else
tsc_stamp = t->local_tsc_stamp;
@@ -1631,9 +1612,7 @@ void pv_soft_rdtsc(struct vcpu *v, struc
spin_unlock(&d->arch.vtsc_lock);
- now = now - d->arch.vtsc_offset;
- if ( !time_scale_is_identity(&d->arch.ns_to_vtsc) )
- now = scale_delta(now, &d->arch.ns_to_vtsc);
+ now = scale_delta(now - d->arch.vtsc_offset, &d->arch.ns_to_vtsc);
regs->eax = (uint32_t)now;
regs->edx = (uint32_t)(now >> 32);
@@ -1714,7 +1693,7 @@ void tsc_get_info(struct domain *d, uint
break;
case TSC_MODE_ALWAYS_EMULATE:
*elapsed_nsec = get_s_time() - d->arch.vtsc_offset;
- *gtsc_khz = 1000000UL;
+ *gtsc_khz = d->arch.tsc_khz;
break;
case TSC_MODE_DEFAULT:
if ( d->arch.vtsc )
@@ -1760,29 +1739,20 @@ void tsc_set_info(struct domain *d,
case TSC_MODE_ALWAYS_EMULATE:
d->arch.vtsc = 1;
d->arch.vtsc_offset = get_s_time() - elapsed_nsec;
- set_time_scale_identity(&d->arch.vtsc_to_ns);
+ d->arch.tsc_khz = gtsc_khz ? gtsc_khz : cpu_khz;
+ set_time_scale(&d->arch.vtsc_to_ns, d->arch.tsc_khz * 1000 );
+ d->arch.ns_to_vtsc = scale_reciprocal(d->arch.vtsc_to_ns);
break;
case TSC_MODE_DEFAULT:
+ d->arch.vtsc = 1;
d->arch.vtsc_offset = get_s_time() - elapsed_nsec;
- if ( (host_tsc_is_safe() && incarnation == 0) || !d->domain_id )
- {
- /* use native TSC if initial host supports it */
+ d->arch.tsc_khz = gtsc_khz ? gtsc_khz : cpu_khz;
+ set_time_scale(&d->arch.vtsc_to_ns, d->arch.tsc_khz * 1000 );
+ /* use native TSC if initial host has safe TSC and not migrated yet */
+ if ( host_tsc_is_safe() && incarnation == 0 )
d->arch.vtsc = 0;
- d->arch.tsc_khz = gtsc_khz ? gtsc_khz : cpu_khz;
- set_time_scale(&d->arch.vtsc_to_ns, d->arch.tsc_khz * 1000 );
- set_time_scale_identity(&d->arch.ns_to_vtsc);
- } else if ( gtsc_khz != 0 && gtsc_khz != 1000000UL ) {
- /* was native on initial host, now emulated at initial tsc hz*/
- d->arch.vtsc = 1;
- d->arch.tsc_khz = gtsc_khz;
- set_time_scale(&d->arch.vtsc_to_ns, gtsc_khz * 1000 );
- d->arch.ns_to_vtsc =
- scale_reciprocal(d->arch.vtsc_to_ns);
- } else {
- d->arch.vtsc = 1;
- set_time_scale_identity(&d->arch.vtsc_to_ns);
- set_time_scale_identity(&d->arch.ns_to_vtsc);
- }
+ else
+ d->arch.ns_to_vtsc = scale_reciprocal(d->arch.vtsc_to_ns);
break;
case TSC_MODE_PVRDTSCP:
if ( boot_cpu_has(X86_FEATURE_RDTSCP) && gtsc_khz != 0 ) {
@@ -1791,7 +1761,6 @@ void tsc_set_info(struct domain *d,
} else {
d->arch.vtsc = 1;
d->arch.vtsc_offset = get_s_time() - elapsed_nsec;
- set_time_scale_identity(&d->arch.vtsc_to_ns);
}
break;
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|