diff options
author | Keir Fraser <keir@xensource.com> | 2007-10-30 16:11:47 +0000 |
---|---|---|
committer | Keir Fraser <keir@xensource.com> | 2007-10-30 16:11:47 +0000 |
commit | edba492627726fbeaba2dee066156adcf02467d8 (patch) | |
tree | 4a7bbe4b250bc26e0ac65ecfa7c7d3a212faf5b7 /xen/arch/x86/hvm/vpt.c | |
parent | 414614d84e67f0e87539b2a4a0a6b16791a5cc30 (diff) | |
download | xen-edba492627726fbeaba2dee066156adcf02467d8.tar.gz xen-edba492627726fbeaba2dee066156adcf02467d8.tar.bz2 xen-edba492627726fbeaba2dee066156adcf02467d8.zip |
x86, hvm: New timer mode 'no missed-tick accounting'.
From: Haitao Shan <haitao.shan@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'xen/arch/x86/hvm/vpt.c')
-rw-r--r-- | xen/arch/x86/hvm/vpt.c | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c index ec0ac0b11c..605a572283 100644 --- a/xen/arch/x86/hvm/vpt.c +++ b/xen/arch/x86/hvm/vpt.c @@ -23,11 +23,8 @@ #include <asm/hvm/vpt.h> #include <asm/event.h> -static int pt_support_time_frozen(struct domain *d) -{ - return (d->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == - HVMPTM_delay_for_missed_ticks); -} +#define mode_is(d, name) \ + ((d)->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == HVMPTM_##name) static void pt_lock(struct periodic_time *pt) { @@ -48,7 +45,7 @@ static void pt_unlock(struct periodic_time *pt) spin_unlock(&pt->vcpu->arch.hvm_vcpu.tm_lock); } -static void missed_ticks(struct periodic_time *pt) +static void pt_process_missed_ticks(struct periodic_time *pt) { s_time_t missed_ticks; @@ -73,11 +70,26 @@ static void missed_ticks(struct periodic_time *pt) pt->scheduled += missed_ticks * pt->period; } -static __inline__ void pt_freeze_time(struct vcpu *v) +static void pt_freeze_time(struct vcpu *v) { + if ( !mode_is(v->domain, delay_for_missed_ticks) ) + return; + v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); } +static void pt_thaw_time(struct vcpu *v) +{ + if ( !mode_is(v->domain, delay_for_missed_ticks) ) + return; + + if ( v->arch.hvm_vcpu.guest_time == 0 ) + return; + + hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time); + v->arch.hvm_vcpu.guest_time = 0; +} + void pt_save_timer(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; @@ -91,21 +103,11 @@ void pt_save_timer(struct vcpu *v) list_for_each_entry ( pt, head, list ) stop_timer(&pt->timer); - if ( pt_support_time_frozen(v->domain) ) - pt_freeze_time(v); + pt_freeze_time(v); spin_unlock(&v->arch.hvm_vcpu.tm_lock); } -static __inline__ void pt_thaw_time(struct vcpu *v) -{ - if ( v->arch.hvm_vcpu.guest_time ) - { - hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time); - v->arch.hvm_vcpu.guest_time = 0; - } -} - void pt_restore_timer(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; @@ -115,12 +117,12 @@ void pt_restore_timer(struct vcpu *v) list_for_each_entry ( pt, head, list ) { - missed_ticks(pt); + if ( !mode_is(v->domain, no_missed_tick_accounting) ) + pt_process_missed_ticks(pt); set_timer(&pt->timer, pt->scheduled); } - if ( pt_support_time_frozen(v->domain) ) - pt_thaw_time(v); + pt_thaw_time(v); spin_unlock(&v->arch.hvm_vcpu.tm_lock); } @@ -136,7 +138,15 @@ static void pt_timer_fn(void *data) if ( !pt->one_shot ) { pt->scheduled += pt->period; - missed_ticks(pt); + if ( !mode_is(pt->vcpu->domain, no_missed_tick_accounting) ) + { + pt_process_missed_ticks(pt); + } + else if ( (NOW() - pt->scheduled) >= 0 ) + { + pt->pending_intr_nr++; + pt->scheduled = NOW() + pt->period; + } set_timer(&pt->timer, pt->scheduled); } @@ -233,11 +243,14 @@ void pt_intr_post(struct vcpu *v, struct hvm_intack intack) else { pt->pending_intr_nr--; - pt->last_plt_gtime += pt->period_cycles; + if ( mode_is(v->domain, no_missed_tick_accounting) ) + pt->last_plt_gtime = hvm_get_guest_time(v); + else + pt->last_plt_gtime += pt->period_cycles; } - if ( pt_support_time_frozen(v->domain) && - hvm_get_guest_time(v) < pt->last_plt_gtime ) + if ( mode_is(v->domain, delay_for_missed_ticks) && + (hvm_get_guest_time(v) < pt->last_plt_gtime) ) hvm_set_guest_time(v, pt->last_plt_gtime); cb = pt->cb; |