# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1174992440 -3600
# Node ID ba9d3fd4ee4b6efbb38a26717d2050f01902352f
# Parent 2c1556c893e7d68eb2dcfe51f8acdf32d1310c49
Fix time reporting to guest.
The recent change to guest time handling dropped a call to
update_vcpu_system_time(), leading to time-went-backwards messages and
guest hangs (the latter were observed only in 2.6.21-rc4 and only when
no serial console was in use).
Debugging the issue also revealed that some commented out debug
printk-s in x86's time handling code didn't compile under x86-64.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/time.c | 22 ++++++++++++----------
xen/common/domain.c | 4 +++-
xen/common/schedule.c | 7 ++-----
3 files changed, 17 insertions(+), 16 deletions(-)
diff -r 2c1556c893e7 -r ba9d3fd4ee4b xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Tue Mar 27 11:31:25 2007 +0100
+++ b/xen/arch/x86/time.c Tue Mar 27 11:47:20 2007 +0100
@@ -670,13 +670,19 @@ static inline void version_update_end(u3
(*version)++;
}
-static inline void __update_vcpu_system_time(struct vcpu *v)
+void update_vcpu_system_time(struct vcpu *v)
{
struct cpu_time *t;
struct vcpu_time_info *u;
+ if ( v->vcpu_info == NULL )
+ return;
+
t = &this_cpu(cpu_time);
u = &vcpu_info(v, time);
+
+ if ( u->tsc_timestamp == t->local_tsc_stamp )
+ return;
version_update_begin(&u->version);
@@ -686,13 +692,6 @@ static inline void __update_vcpu_system_
u->tsc_shift = (s8)t->tsc_scale.shift;
version_update_end(&u->version);
-}
-
-void update_vcpu_system_time(struct vcpu *v)
-{
- if ( vcpu_info(v, time.tsc_timestamp) !=
- this_cpu(cpu_time).local_tsc_stamp )
- __update_vcpu_system_time(v);
}
void update_domain_wallclock_time(struct domain *d)
@@ -771,9 +770,10 @@ static void local_time_calibration(void
local_irq_enable();
#if 0
- printk("PRE%d: tsc=%lld stime=%lld master=%lld\n",
+ printk("PRE%d: tsc=%"PRIu64" stime=%"PRIu64" master=%"PRIu64"\n",
smp_processor_id(), prev_tsc, prev_local_stime, prev_master_stime);
- printk("CUR%d: tsc=%lld stime=%lld master=%lld -> %lld\n",
+ printk("CUR%d: tsc=%"PRIu64" stime=%"PRIu64" master=%"PRIu64
+ " -> %"PRId64"\n",
smp_processor_id(), curr_tsc, curr_local_stime, curr_master_stime,
curr_master_stime - curr_local_stime);
#endif
@@ -854,6 +854,8 @@ static void local_time_calibration(void
t->local_tsc_stamp = curr_tsc;
t->stime_local_stamp = curr_local_stime;
t->stime_master_stamp = curr_master_stime;
+
+ update_vcpu_system_time(current);
out:
set_timer(&t->calibration_timer, NOW() + EPOCH);
diff -r 2c1556c893e7 -r ba9d3fd4ee4b xen/common/domain.c
--- a/xen/common/domain.c Tue Mar 27 11:31:25 2007 +0100
+++ b/xen/common/domain.c Tue Mar 27 11:47:20 2007 +0100
@@ -96,14 +96,16 @@ struct vcpu *alloc_vcpu(
v->domain = d;
v->vcpu_id = vcpu_id;
- v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]);
spin_lock_init(&v->pause_lock);
v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline;
v->runstate.state_entry_time = NOW();
if ( !is_idle_domain(d) )
+ {
set_bit(_VCPUF_down, &v->vcpu_flags);
+ v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]);
+ }
if ( sched_init_vcpu(v, cpu_id) != 0 )
{
diff -r 2c1556c893e7 -r ba9d3fd4ee4b xen/common/schedule.c
--- a/xen/common/schedule.c Tue Mar 27 11:31:25 2007 +0100
+++ b/xen/common/schedule.c Tue Mar 27 11:47:20 2007 +0100
@@ -659,11 +659,8 @@ static void schedule(void)
stop_timer(&prev->periodic_timer);
/* Ensure that the domain has an up-to-date time base. */
- if ( !is_idle_vcpu(next) )
- {
- update_vcpu_system_time(next);
- vcpu_periodic_timer_work(next);
- }
+ update_vcpu_system_time(next);
+ vcpu_periodic_timer_work(next);
TRACE_4D(TRC_SCHED_SWITCH,
prev->domain->domain_id, prev->vcpu_id,
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|