[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.1-testing] [HVM] Don't count "missed ticks" on one-shot timers.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1197470499 0 # Node ID 03551b644e35dbec62d657e6f943faa5dd310409 # Parent 1caed71f2a357533a569a7fdac7bfb06ca2368a7 [HVM] Don't count "missed ticks" on one-shot timers. It's not clear what it would mean, and it leads to division by zero. Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx> xen-unstable changeset: 15943:c0d1825f51899b329495efb2078dd15e0fb3b479 xen-unstable date: Mon Sep 24 13:44:29 2007 +0100 hvm: Fix one-shot timers. Do not disable until the interrupt has been latched by the target VCPU. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> xen-unstable changeset: 16125:b4278beaf3549f410a5a6086dbd8af93c495aeac xen-unstable date: Wed Oct 17 13:12:03 2007 +0100 hvm: Fix destroy_periodic_time() to not race destruction of one-shot timers. This bug was tracked down by Dexuan Cui <dexuan.cui@xxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> xen-unstable changeset: 16595:f2f7c92bf1c15206aa7072f6a4e470a132d528e2 xen-unstable date: Wed Dec 12 11:08:21 2007 +0000 --- xen/arch/x86/hvm/vioapic.c | 2 +- xen/arch/x86/hvm/vlapic.c | 13 +++++-------- xen/arch/x86/hvm/vpt.c | 35 ++++++++++++++++++++++++----------- xen/include/asm-x86/hvm/vpt.h | 17 ++++++++++++++--- 4 files changed, 44 insertions(+), 23 deletions(-) diff -r 1caed71f2a35 -r 03551b644e35 xen/arch/x86/hvm/vioapic.c --- a/xen/arch/x86/hvm/vioapic.c Wed Dec 12 14:32:10 2007 +0000 +++ b/xen/arch/x86/hvm/vioapic.c Wed Dec 12 14:41:39 2007 +0000 @@ -311,7 +311,7 @@ static inline int pit_channel0_enabled(v { PITState *pit = ¤t->domain->arch.hvm_domain.pl_time.vpit; struct periodic_time *pt = &pit->pt[0]; - return pt->enabled; + return pt_active(pt); } static void vioapic_deliver(struct hvm_hw_vioapic *vioapic, int irq) diff -r 1caed71f2a35 -r 03551b644e35 xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Wed Dec 12 14:32:10 2007 +0000 +++ b/xen/arch/x86/hvm/vlapic.c Wed Dec 12 14:41:39 2007 +0000 @@ -957,15 +957,12 @@ void vlapic_destroy(struct vcpu *v) int is_lvtt(struct vcpu *v, int vector) { - return vcpu_vlapic(v)->pt.enabled && - vector == vlapic_lvt_vector(vcpu_vlapic(v), APIC_LVTT); + return (pt_active(&vcpu_vlapic(v)->pt) && + (vector == vlapic_lvt_vector(vcpu_vlapic(v), APIC_LVTT))); } int is_lvtt_enabled(struct vcpu *v) { - if ( unlikely(!vlapic_enabled(vcpu_vlapic(v))) || - !vlapic_lvt_enabled(vcpu_vlapic(v), APIC_LVTT)) - return 0; - - return 1; -} + return (vlapic_enabled(vcpu_vlapic(v)) && + vlapic_lvt_enabled(vcpu_vlapic(v), APIC_LVTT)); +} diff -r 1caed71f2a35 -r 03551b644e35 xen/arch/x86/hvm/vpt.c --- a/xen/arch/x86/hvm/vpt.c Wed Dec 12 14:32:10 2007 +0000 +++ b/xen/arch/x86/hvm/vpt.c Wed Dec 12 14:41:39 2007 +0000 @@ -46,6 +46,9 @@ static void missed_ticks(struct periodic { s_time_t missed_ticks; + if ( pt->one_shot ) + return; + missed_ticks = NOW() - pt->scheduled; if ( missed_ticks <= 0 ) return; @@ -111,12 +114,13 @@ static void pt_timer_fn(void *data) pt_lock(pt); pt->pending_intr_nr++; - pt->scheduled += pt->period; - - missed_ticks(pt); if ( !pt->one_shot ) + { + pt->scheduled += pt->period; + missed_ticks(pt); set_timer(&pt->timer, pt->scheduled); + } vcpu_kick(pt->vcpu); @@ -201,10 +205,17 @@ void pt_intr_post(struct vcpu *v, int ve return; } - ASSERT(pt->vcpu == v); - - pt->pending_intr_nr--; - pt->last_plt_gtime += pt->period_cycles; + if ( pt->one_shot ) + { + if ( pt->on_list ) + list_del(&pt->list); + pt->on_list = 0; + } + else + { + pt->pending_intr_nr--; + pt->last_plt_gtime += pt->period_cycles; + } if ( hvm_get_guest_time(v) < pt->last_plt_gtime ) hvm_set_guest_time(v, pt->last_plt_gtime); @@ -257,7 +268,6 @@ void create_periodic_time( spin_lock(&v->arch.hvm_vcpu.tm_lock); - pt->enabled = 1; pt->pending_intr_nr = 0; /* Periodic timer must be at least 0.9ms. */ @@ -279,6 +289,7 @@ void create_periodic_time( pt->cb = cb; pt->priv = data; + pt->on_list = 1; list_add(&pt->list, &v->arch.hvm_vcpu.tm_list); init_timer(&pt->timer, pt_timer_fn, pt, v->processor); @@ -289,12 +300,14 @@ void create_periodic_time( void destroy_periodic_time(struct periodic_time *pt) { - if ( !pt->enabled ) + /* Was this structure previously initialised by create_periodic_time()? */ + if ( pt->vcpu == NULL ) return; pt_lock(pt); - pt->enabled = 0; - list_del(&pt->list); + if ( pt->on_list ) + list_del(&pt->list); + pt->on_list = 0; pt_unlock(pt); /* diff -r 1caed71f2a35 -r 03551b644e35 xen/include/asm-x86/hvm/vpt.h --- a/xen/include/asm-x86/hvm/vpt.h Wed Dec 12 14:32:10 2007 +0000 +++ b/xen/include/asm-x86/hvm/vpt.h Wed Dec 12 14:41:39 2007 +0000 @@ -55,11 +55,11 @@ typedef void time_cb(struct vcpu *v, voi struct periodic_time { struct list_head list; - char enabled; - char one_shot; /* one shot time */ + bool_t on_list; + bool_t one_shot; u8 irq; struct vcpu *vcpu; /* vcpu timer interrupt delivers to */ - u32 pending_intr_nr; /* the couner for pending timer interrupts */ + u32 pending_intr_nr; /* pending timer interrupts */ u64 period; /* frequency in ns */ u64 period_cycles; /* frequency in cpu cycles */ s_time_t scheduled; /* scheduled timer interrupt */ @@ -122,6 +122,17 @@ void pt_intr_post(struct vcpu *v, int ve void pt_intr_post(struct vcpu *v, int vector, int type); void pt_reset(struct vcpu *v); void pt_migrate(struct vcpu *v); + +/* Is given periodic timer active? */ +#define pt_active(pt) ((pt)->on_list) + +/* + * Create/destroy a periodic (or one-shot!) timer. + * The given periodic timer structure must be initialised with zero bytes or + * have been initialised by a previous invocation of create_periodic_time(). + * Note that, for a given periodic timer, invocations of these functions MUST + * be serialised. + */ void create_periodic_time( struct vcpu *v, struct periodic_time *pt, uint64_t period, uint8_t irq, char one_shot, time_cb *cb, void *data); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |