On Wednesday 23 January 2008, Keir Fraser wrote:
> On 23/1/08 22:34, "Ian Pratt" <Ian.Pratt@xxxxxxxxxxxxx> wrote:
>
> > Since we probably don't know how long we had to wait between when the
> > multipler was increased and when the CPU was un-paused, it will be
> > necessary to recalibrate the CPU to the global time source (PIT/HPET).
>
> Yes, actually that is a good point. Possibly we would get better results by
> setting t->stime_local_stamp = t->stime_master_stamp = read_platform_stime()
> in xen/arch/x86/time.c:cpu_frequency_change(). Currently we set the local
> stamp to get_s_time(), but get_s_time() may not be trustworthy.
I tried this suggestion and also implemented the trace function in
cpu_frequency_change() and local_time_calibration() you suggested in
a previous message.
It made no discernable difference in my tests. I did high to low
and low to high changes roughly every five minutes, and always got
an excessive difference inside of Xen and usually got error messages
in Linux.
Changed code follows and the xm dmesg log is attached.
diff -r 62fc84adc8ed xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Fri Jan 18 13:43:26 2008 +0000
+++ b/xen/arch/x86/time.c Fri Jan 25 16:45:03 2008 -0600
@@ -724,6 +724,20 @@ void update_domain_wallclock_time(struct
spin_unlock(&wc_lock);
}
+void checktime(char *buf);
+void checktime(char *buf)
+{
+ u64 s_tmp, p_tmp, diff;
+ s_tmp = get_s_time();
+ p_tmp = read_platform_stime();
+ if (s_tmp > p_tmp)
+ diff = s_tmp - p_tmp;
+ else
+ diff = p_tmp - s_tmp;
+ if (diff > 50000000)
+ printk(KERN_ERR "%s:time differed by %lu platform time %lu,
systime %lu\n", buf, diff, p_tmp, s_tmp);
+}
+
int cpu_frequency_change(u64 freq)
{
struct cpu_time *t = &this_cpu(cpu_time);
@@ -732,11 +746,14 @@ int cpu_frequency_change(u64 freq)
local_irq_disable();
rdtscll(curr_tsc);
t->local_tsc_stamp = curr_tsc;
- t->stime_local_stamp = get_s_time();
+// t->stime_local_stamp = get_s_time();
t->stime_master_stamp = read_platform_stime();
+ t->stime_local_stamp = t->stime_master_stamp;
set_time_scale(&t->tsc_scale, freq);
+checktime("frequency_change");
local_irq_enable();
+printk(KERN_ERR "freq change at %lu\n", t->stime_master_stamp);
/* A full epoch should pass before we check for deviation. */
set_timer(&t->calibration_timer, NOW() + EPOCH);
if ( smp_processor_id() == 0 )
@@ -808,6 +825,7 @@ static void local_time_calibration(void
rdtscll(curr_tsc);
curr_local_stime = get_s_time();
curr_master_stime = read_platform_stime();
+checktime("calibration");
local_irq_enable();
#if 0
xen_revf_time.log.gz
Description: GNU Zip compressed data
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|