]> xenbits.xensource.com Git - xen.git/commitdiff
x86, hvm: New timer mode 'no missed-tick accounting'.
authorKeir Fraser <keir@xensource.com>
Tue, 30 Oct 2007 16:11:47 +0000 (16:11 +0000)
committerKeir Fraser <keir@xensource.com>
Tue, 30 Oct 2007 16:11:47 +0000 (16:11 +0000)
From: Haitao Shan <haitao.shan@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/hvm/vpt.c
xen/include/public/hvm/params.h

index ec0ac0b11cd5ffb6730cc0a27388085bcb2e0e2b..605a5722833083f5c5b1c8e955399e6ee6c898c4 100644 (file)
 #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;
index dbf2fb0b443ee64fbe2bd55afc62fb6bcc3d2345..9fa80d39e7ae5ce13455a9c3856183b67a1c6b5e 100644 (file)
  *  no_delay_for_missed_ticks:
  *   As above, missed interrupts are delivered, but guest time always tracks
  *   wallclock (i.e., real) time while doing so.
+ *  no_missed_ticks_pending:
+ *   No more than one missed interrupt is held pending, and guest time always
+ *   tracks wallclock (i.e., real) time.
  */
 #define HVM_PARAM_TIMER_MODE   10
 #define HVMPTM_delay_for_missed_ticks    0
 #define HVMPTM_no_delay_for_missed_ticks 1
+#define HVMPTM_no_missed_tick_accounting 2
 
 #define HVM_NR_PARAMS          11