ia64/xen-unstable

changeset 16282:44dde35cb2a6

x86, hvm: New timer mode 'no missed-tick accounting'.
From: Haitao Shan <haitao.shan@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Tue Oct 30 16:11:47 2007 +0000 (2007-10-30)
parents cc58c6f3950e
children 9379c83e14b5
files xen/arch/x86/hvm/vpt.c xen/include/public/hvm/params.h
line diff
     1.1 --- a/xen/arch/x86/hvm/vpt.c	Tue Oct 30 16:02:33 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/vpt.c	Tue Oct 30 16:11:47 2007 +0000
     1.3 @@ -23,11 +23,8 @@
     1.4  #include <asm/hvm/vpt.h>
     1.5  #include <asm/event.h>
     1.6  
     1.7 -static int pt_support_time_frozen(struct domain *d)
     1.8 -{
     1.9 -    return (d->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == 
    1.10 -            HVMPTM_delay_for_missed_ticks);
    1.11 -}
    1.12 +#define mode_is(d, name) \
    1.13 +    ((d)->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == HVMPTM_##name)
    1.14  
    1.15  static void pt_lock(struct periodic_time *pt)
    1.16  {
    1.17 @@ -48,7 +45,7 @@ static void pt_unlock(struct periodic_ti
    1.18      spin_unlock(&pt->vcpu->arch.hvm_vcpu.tm_lock);
    1.19  }
    1.20  
    1.21 -static void missed_ticks(struct periodic_time *pt)
    1.22 +static void pt_process_missed_ticks(struct periodic_time *pt)
    1.23  {
    1.24      s_time_t missed_ticks;
    1.25  
    1.26 @@ -73,11 +70,26 @@ static void missed_ticks(struct periodic
    1.27      pt->scheduled += missed_ticks * pt->period;
    1.28  }
    1.29  
    1.30 -static __inline__ void pt_freeze_time(struct vcpu *v)
    1.31 +static void pt_freeze_time(struct vcpu *v)
    1.32  {
    1.33 +    if ( !mode_is(v->domain, delay_for_missed_ticks) )
    1.34 +        return;
    1.35 +
    1.36      v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
    1.37  }
    1.38  
    1.39 +static void pt_thaw_time(struct vcpu *v)
    1.40 +{
    1.41 +    if ( !mode_is(v->domain, delay_for_missed_ticks) )
    1.42 +        return;
    1.43 +
    1.44 +    if ( v->arch.hvm_vcpu.guest_time == 0 )
    1.45 +        return;
    1.46 +
    1.47 +    hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time);
    1.48 +    v->arch.hvm_vcpu.guest_time = 0;
    1.49 +}
    1.50 +
    1.51  void pt_save_timer(struct vcpu *v)
    1.52  {
    1.53      struct list_head *head = &v->arch.hvm_vcpu.tm_list;
    1.54 @@ -91,21 +103,11 @@ void pt_save_timer(struct vcpu *v)
    1.55      list_for_each_entry ( pt, head, list )
    1.56          stop_timer(&pt->timer);
    1.57  
    1.58 -    if ( pt_support_time_frozen(v->domain) )
    1.59 -        pt_freeze_time(v);
    1.60 +    pt_freeze_time(v);
    1.61  
    1.62      spin_unlock(&v->arch.hvm_vcpu.tm_lock);
    1.63  }
    1.64  
    1.65 -static __inline__ void pt_thaw_time(struct vcpu *v)
    1.66 -{
    1.67 -    if ( v->arch.hvm_vcpu.guest_time )
    1.68 -    {
    1.69 -        hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time);
    1.70 -        v->arch.hvm_vcpu.guest_time = 0;
    1.71 -    }
    1.72 -}
    1.73 -
    1.74  void pt_restore_timer(struct vcpu *v)
    1.75  {
    1.76      struct list_head *head = &v->arch.hvm_vcpu.tm_list;
    1.77 @@ -115,12 +117,12 @@ void pt_restore_timer(struct vcpu *v)
    1.78  
    1.79      list_for_each_entry ( pt, head, list )
    1.80      {
    1.81 -        missed_ticks(pt);
    1.82 +        if ( !mode_is(v->domain, no_missed_tick_accounting) )
    1.83 +            pt_process_missed_ticks(pt);
    1.84          set_timer(&pt->timer, pt->scheduled);
    1.85      }
    1.86  
    1.87 -    if ( pt_support_time_frozen(v->domain) )
    1.88 -        pt_thaw_time(v);
    1.89 +    pt_thaw_time(v);
    1.90  
    1.91      spin_unlock(&v->arch.hvm_vcpu.tm_lock);
    1.92  }
    1.93 @@ -136,7 +138,15 @@ static void pt_timer_fn(void *data)
    1.94      if ( !pt->one_shot )
    1.95      {
    1.96          pt->scheduled += pt->period;
    1.97 -        missed_ticks(pt);
    1.98 +        if ( !mode_is(pt->vcpu->domain, no_missed_tick_accounting) )
    1.99 +        {
   1.100 +            pt_process_missed_ticks(pt);
   1.101 +        }
   1.102 +        else if ( (NOW() - pt->scheduled) >= 0 )
   1.103 +        {
   1.104 +            pt->pending_intr_nr++;
   1.105 +            pt->scheduled = NOW() + pt->period;
   1.106 +        }
   1.107          set_timer(&pt->timer, pt->scheduled);
   1.108      }
   1.109  
   1.110 @@ -233,11 +243,14 @@ void pt_intr_post(struct vcpu *v, struct
   1.111      else
   1.112      {
   1.113          pt->pending_intr_nr--;
   1.114 -        pt->last_plt_gtime += pt->period_cycles;
   1.115 +        if ( mode_is(v->domain, no_missed_tick_accounting) )
   1.116 +            pt->last_plt_gtime = hvm_get_guest_time(v);
   1.117 +        else
   1.118 +            pt->last_plt_gtime += pt->period_cycles;
   1.119      }
   1.120  
   1.121 -    if ( pt_support_time_frozen(v->domain) &&
   1.122 -            hvm_get_guest_time(v) < pt->last_plt_gtime )
   1.123 +    if ( mode_is(v->domain, delay_for_missed_ticks) &&
   1.124 +         (hvm_get_guest_time(v) < pt->last_plt_gtime) )
   1.125          hvm_set_guest_time(v, pt->last_plt_gtime);
   1.126  
   1.127      cb = pt->cb;
     2.1 --- a/xen/include/public/hvm/params.h	Tue Oct 30 16:02:33 2007 +0000
     2.2 +++ b/xen/include/public/hvm/params.h	Tue Oct 30 16:11:47 2007 +0000
     2.3 @@ -66,10 +66,14 @@
     2.4   *  no_delay_for_missed_ticks:
     2.5   *   As above, missed interrupts are delivered, but guest time always tracks
     2.6   *   wallclock (i.e., real) time while doing so.
     2.7 + *  no_missed_ticks_pending:
     2.8 + *   No more than one missed interrupt is held pending, and guest time always
     2.9 + *   tracks wallclock (i.e., real) time.
    2.10   */
    2.11  #define HVM_PARAM_TIMER_MODE   10
    2.12  #define HVMPTM_delay_for_missed_ticks    0
    2.13  #define HVMPTM_no_delay_for_missed_ticks 1
    2.14 +#define HVMPTM_no_missed_tick_accounting 2
    2.15  
    2.16  #define HVM_NR_PARAMS          11
    2.17