ia64/xen-unstable

changeset 17782:5603534c62f9

Improve HPET comparator reprog to prevent intr-near-missing case

HPET intr-near-missing means if the current counter value is too close
to the comparator value to be reprogrammed the expected HPET intr may
be missing. Linux kernel uses a mininal 48-hpet-ticks(~3.5us) distance
to workaround this, but personal observation showed there is still
failure case while delta=3D0xba (~13.5us). So choosing 20us as the
MIN_DELTA_NS should be helpful to prevent near-missing from happening.

local_irq_save/restore were used to avoid disturbance. (+ 2) was used
as a final guard to avoid wrong judgement due to the real happened
near-missing case.

Signed-off-by: Wei Gang <gang.wei@intel.com>
Signed-off-by: Tian Kevin <kevin.tian@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 03 09:41:19 2008 +0100 (2008-06-03)
parents 6b77c311fd3c
children bbb4bb69efb2
files xen/arch/x86/hpet.c
line diff
     1.1 --- a/xen/arch/x86/hpet.c	Tue Jun 03 09:35:02 2008 +0100
     1.2 +++ b/xen/arch/x86/hpet.c	Tue Jun 03 09:41:19 2008 +0100
     1.3 @@ -17,7 +17,7 @@
     1.4  #define STIME_MAX ((s_time_t)((uint64_t)~0ull>>1))
     1.5  
     1.6  #define MAX_DELTA_NS MILLISECS(10*1000)
     1.7 -#define MIN_DELTA_NS MICROSECS(1)
     1.8 +#define MIN_DELTA_NS MICROSECS(20)
     1.9  
    1.10  struct hpet_event_channel
    1.11  {
    1.12 @@ -67,13 +67,18 @@ static inline unsigned long ns2ticks(uns
    1.13  
    1.14  static int hpet_legacy_next_event(unsigned long delta)
    1.15  {
    1.16 -    unsigned long cnt;
    1.17 +    uint32_t cnt, cmp;
    1.18 +    unsigned long flags;
    1.19  
    1.20 +    local_irq_save(flags);
    1.21      cnt = hpet_read32(HPET_COUNTER);
    1.22 -    cnt += delta;
    1.23 -    hpet_write32(cnt, HPET_T0_CMP);
    1.24 +    cmp = cnt + delta;
    1.25 +    hpet_write32(cmp, HPET_T0_CMP);
    1.26 +    cmp = hpet_read32(HPET_COUNTER);
    1.27 +    local_irq_restore(flags);
    1.28  
    1.29 -    return ((long)(hpet_read32(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0;
    1.30 +    /* Are we within two ticks of the deadline passing? Then we may miss. */
    1.31 +    return ((cmp + 2 - cnt) > delta) ? -ETIME : 0;
    1.32  }
    1.33  
    1.34  static int reprogram_hpet_evt_channel(