> I tried this suggestion and also implemented the trace function in
> cpu_frequency_change() and local_time_calibration() you suggested in a
> previous message.
Please provide the output of the tracing. Presumably the
time-goes-backwards messages only come out when stepping frequency down?
Presumably it is the CPU that is down-stepping that thinks time has gone
backwards? The messages comes out shortly after the downstep?
Once the multiplier change has happened, you need to create a new time
record for the CPU based on the global clock PIT/HPET (and update the
frequency info in the record).
Implemented correctly, this really ought to work just fine.
Ian
> 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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|