hvm: Split no_missed_tick_accounting into two modes:
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 6 Dec 2007 11:56:51 +0000 (11:56 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 6 Dec 2007 11:56:51 +0000 (11:56 +0000)
 * no_missed_ticks_pending ('SYNC')
 * one_missed_tick_pending ('MIXED')

This is based on a patch by Dave Winchell <dwinchell@virtualiron.com>

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/vpt.c
xen/include/asm-x86/hvm/vpt.h
xen/include/public/hvm/params.h

index ec7344b06b2741f4db640499c5b4628b31ea26e1..c42ff62aa5d51717fd2b42b97acce22d555c35d2 100644 (file)
@@ -1874,9 +1874,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
                 break;
             case HVM_PARAM_TIMER_MODE:
                 rc = -EINVAL;
-                if ( (a.value != HVMPTM_delay_for_missed_ticks) &&
-                     (a.value != HVMPTM_no_delay_for_missed_ticks) &&
-                     (a.value != HVMPTM_no_missed_tick_accounting) )
+                if ( a.value > HVMPTM_one_missed_tick_pending )
                     goto param_fail;
                 break;
             }
index 9f691cae0c644e5b9f7bcf1d4ebdee4d411f1ed1..0a780298b813c52fd538601232bf3278b1466324 100644 (file)
@@ -57,7 +57,10 @@ static void pt_process_missed_ticks(struct periodic_time *pt)
         return;
 
     missed_ticks = missed_ticks / (s_time_t) pt->period + 1;
-    pt->pending_intr_nr += missed_ticks;
+    if ( mode_is(pt->vcpu->domain, no_missed_ticks_pending) )
+        pt->do_not_freeze = !pt->pending_intr_nr;
+    else
+        pt->pending_intr_nr += missed_ticks;
     pt->scheduled += missed_ticks * pt->period;
 }
 
@@ -92,7 +95,8 @@ void pt_save_timer(struct vcpu *v)
     spin_lock(&v->arch.hvm_vcpu.tm_lock);
 
     list_for_each_entry ( pt, head, list )
-        stop_timer(&pt->timer);
+        if ( !pt->do_not_freeze )
+            stop_timer(&pt->timer);
 
     pt_freeze_time(v);
 
@@ -217,6 +221,8 @@ void pt_intr_post(struct vcpu *v, struct hvm_intack intack)
         return;
     }
 
+    pt->do_not_freeze = 0;
+
     if ( pt->one_shot )
     {
         pt->enabled = 0;
@@ -224,7 +230,7 @@ void pt_intr_post(struct vcpu *v, struct hvm_intack intack)
     }
     else
     {
-        if ( mode_is(v->domain, no_missed_tick_accounting) )
+        if ( mode_is(v->domain, one_missed_tick_pending) )
         {
             pt->last_plt_gtime = hvm_get_guest_time(v);
             pt->pending_intr_nr = 0; /* 'collapse' all missed ticks */
@@ -290,6 +296,7 @@ void create_periodic_time(
 
     pt->enabled = 1;
     pt->pending_intr_nr = 0;
+    pt->do_not_freeze = 0;
 
     /* Periodic timer must be at least 0.9ms. */
     if ( (period < 900000) && !one_shot )
index 4471fd990db3330da9a2f279fc904743399809b8..9f69024340d874eee6bce43b44a8e49f13291e37 100644 (file)
@@ -74,6 +74,7 @@ struct periodic_time {
     struct list_head list;
     char enabled;
     char one_shot;              /* one shot time */
+    char do_not_freeze;
     u8 irq;
     struct vcpu *vcpu;          /* vcpu timer interrupt delivers to */
     u32 pending_intr_nr;        /* the couner for pending timer interrupts */
index 9fa80d39e7ae5ce13455a9c3856183b67a1c6b5e..486499816d7247d86a01ba35646af287a3b2c4f5 100644 (file)
  *   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.
+ *   No missed interrupts are held pending. Instead, to ensure ticks are
+ *   delivered at some non-zero rate, if we detect missed ticks then the
+ *   internal tick alarm is not disabled if the VCPU is preempted during the
+ *   next tick period.
+ *  one_missed_tick_pending:
+ *   Missed interrupts are collapsed together and delivered as one 'late tick'.
+ *   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 HVMPTM_no_missed_ticks_pending   2
+#define HVMPTM_one_missed_tick_pending   3
 
 #define HVM_NR_PARAMS          11