ia64/xen-unstable

changeset 323:fb9fb3949b4c

bitkeeper revision 1.140.1.1 (3e747812JL9EFIy408RAfKRoUWkB7Q)

schedule.c, time.c, irq.c, apic.c:
Fixed TSC sync problem in Xen timer code.
author kaf24@scramble.cl.cam.ac.uk
date Sun Mar 16 13:11:46 2003 +0000 (2003-03-16)
parents e27bfabd1b5a
children 0f28cb35057d
files xen/arch/i386/apic.c xen/arch/i386/irq.c xen/arch/i386/time.c xen/common/schedule.c
line diff
     1.1 --- a/xen/arch/i386/apic.c	Sun Mar 16 12:30:28 2003 +0000
     1.2 +++ b/xen/arch/i386/apic.c	Sun Mar 16 13:11:46 2003 +0000
     1.3 @@ -748,8 +748,10 @@ unsigned int apic_timer_irqs [NR_CPUS];
     1.4  void smp_apic_timer_interrupt(struct pt_regs * regs)
     1.5  {
     1.6      int cpu = smp_processor_id();
     1.7 +#ifndef NDEBUG
     1.8      u32 cc_start, cc_end;
     1.9      rdtscl(cc_start);
    1.10 +#endif
    1.11  
    1.12      /*
    1.13       * the NMI deadlock-detector uses this.
    1.14 @@ -771,9 +773,11 @@ void smp_apic_timer_interrupt(struct pt_
    1.15      if (softirq_pending(cpu))
    1.16          do_softirq();
    1.17  
    1.18 +#ifndef NDEBUG
    1.19      rdtscl(cc_end);
    1.20      if ( (cc_end - cc_start) > (cpu_khz * 100) )
    1.21          printk("APIC Long ISR on CPU=%02d %08X -> %08X\n",cpu,cc_start,cc_end);
    1.22 +#endif
    1.23  }
    1.24  
    1.25  /*
     2.1 --- a/xen/arch/i386/irq.c	Sun Mar 16 12:30:28 2003 +0000
     2.2 +++ b/xen/arch/i386/irq.c	Sun Mar 16 13:11:46 2003 +0000
     2.3 @@ -543,8 +543,10 @@ asmlinkage unsigned int do_IRQ(struct pt
     2.4      if ( !action || (!(action->flags & SA_NOPROFILE)) )
     2.5      {
     2.6          perfc_adda(irq_time, cpu, cc_end - cc_start);
     2.7 +#ifndef NDEBUG
     2.8          if ( (cc_end - cc_start) > (cpu_khz * 100) )
     2.9              printk("Long interrupt %08x -> %08x\n", cc_start, cc_end);
    2.10 +#endif
    2.11      }
    2.12  
    2.13      return 1;
     3.1 --- a/xen/arch/i386/time.c	Sun Mar 16 12:30:28 2003 +0000
     3.2 +++ b/xen/arch/i386/time.c	Sun Mar 16 13:11:46 2003 +0000
     3.3 @@ -12,7 +12,7 @@
     3.4   * Environment: Xen Hypervisor
     3.5   * Description: modified version of Linux' time.c
     3.6   *              implements system and wall clock time.
     3.7 - *				based on freebsd's implementation.
     3.8 + *              based on freebsd's implementation.
     3.9   *
    3.10   ****************************************************************************
    3.11   * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
    3.12 @@ -48,7 +48,7 @@
    3.13  #define TRC(_x)
    3.14  #endif
    3.15  
    3.16 -unsigned long cpu_khz;	/* Detected as we calibrate the TSC */
    3.17 +unsigned long cpu_khz;  /* Detected as we calibrate the TSC */
    3.18  unsigned long ticks_per_usec; /* TSC ticks per microsecond. */
    3.19  
    3.20  spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
    3.21 @@ -86,7 +86,7 @@ static void timer_interrupt(int irq, voi
    3.22  }
    3.23  
    3.24  static struct irqaction irq0  = { timer_interrupt, SA_INTERRUPT, 0,
    3.25 -								  "timer", NULL, NULL};
    3.26 +                                  "timer", NULL, NULL};
    3.27  
    3.28  /* ------ Calibrate the TSC ------- 
    3.29   * Return processor ticks per second / CALIBRATE_FRAC.
    3.30 @@ -108,9 +108,9 @@ static unsigned long __init calibrate_ts
    3.31       * terminal count mode), binary count, load 5 * LATCH count, (LSB and MSB)
    3.32       * to begin countdown.
    3.33       */
    3.34 -    outb(0xb0, 0x43);			/* binary, mode 0, LSB/MSB, Ch 2 */
    3.35 -    outb(CALIBRATE_LATCH & 0xff, 0x42);	/* LSB of count */
    3.36 -    outb(CALIBRATE_LATCH >> 8, 0x42);	/* MSB of count */
    3.37 +    outb(0xb0, 0x43);           /* binary, mode 0, LSB/MSB, Ch 2 */
    3.38 +    outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
    3.39 +    outb(CALIBRATE_LATCH >> 8, 0x42);   /* MSB of count */
    3.40  
    3.41      {
    3.42          unsigned long startlow, starthigh;
    3.43 @@ -177,7 +177,7 @@ mktime (unsigned int year, unsigned int 
    3.44      if (0 >= (int) (mon -= 2)) {   /* 1..12 -> 11,12,1..10 */
    3.45          mon += 12;                 /* Puts Feb last since it has leap day */
    3.46          year -= 1;
    3.47 -	}
    3.48 +    }
    3.49      return ((((unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day)+
    3.50                year*365 - 719499
    3.51          )*24 + hour /* now have hours */
    3.52 @@ -197,13 +197,13 @@ static unsigned long get_cmos_time(void)
    3.53       * Let's hope other operating systems interpret the RTC the same way.
    3.54       */
    3.55      /* read RTC exactly on falling edge of update flag */
    3.56 -    for (i = 0 ; i < 1000000 ; i++)	/* may take up to 1 second... */
    3.57 +    for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
    3.58          if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
    3.59              break;
    3.60 -    for (i = 0 ; i < 1000000 ; i++)	/* must try at least 2.228 ms */
    3.61 +    for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
    3.62          if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
    3.63              break;
    3.64 -	do { /* Isn't this overkill ? UIP above should guarantee consistency */
    3.65 +    do { /* Isn't this overkill ? UIP above should guarantee consistency */
    3.66          sec = CMOS_READ(RTC_SECONDS);
    3.67          min = CMOS_READ(RTC_MINUTES);
    3.68          hour = CMOS_READ(RTC_HOURS);
    3.69 @@ -215,10 +215,10 @@ static unsigned long get_cmos_time(void)
    3.70      {
    3.71          BCD_TO_BIN(sec);
    3.72          BCD_TO_BIN(min);
    3.73 -	    BCD_TO_BIN(hour);
    3.74 -	    BCD_TO_BIN(day);
    3.75 -	    BCD_TO_BIN(mon);
    3.76 -	    BCD_TO_BIN(year);
    3.77 +        BCD_TO_BIN(hour);
    3.78 +        BCD_TO_BIN(day);
    3.79 +        BCD_TO_BIN(mon);
    3.80 +        BCD_TO_BIN(year);
    3.81      }
    3.82      spin_unlock(&rtc_lock);
    3.83      if ((year += 1900) < 1970)
    3.84 @@ -235,23 +235,29 @@ static unsigned long get_cmos_time(void)
    3.85   ***************************************************************************/
    3.86  
    3.87  static spinlock_t stime_lock;
    3.88 -static u32	st_scale_f;
    3.89 -static u32	st_scale_i;
    3.90 -u32			stime_pcc;	 /* cycle counter value at last timer irq */
    3.91 -s_time_t	stime_now;   /* time in ns at last timer IRQ */
    3.92 +static u32  st_scale_f;
    3.93 +static u32  st_scale_i;
    3.94 +u32         stime_pcc;   /* cycle counter value at last timer irq */
    3.95 +s_time_t    stime_now;   /* time in ns at last timer IRQ */
    3.96  
    3.97  static inline s_time_t __get_s_time(void)
    3.98  {
    3.99 -    u32 	 delta_tsc, low, pcc;
   3.100 +    s32      delta_tsc;
   3.101 +    u32      low, pcc;
   3.102      u64      delta;
   3.103      s_time_t now;
   3.104  
   3.105 -    pcc = stime_pcc;		
   3.106 +    pcc = stime_pcc;        
   3.107      now = stime_now;
   3.108  
   3.109 -    /* only use bottom 32bits of TSC. This should be sufficient */
   3.110 +    /*
   3.111 +     * We only use the bottom 32 bits of the TSC. This should be sufficient,
   3.112 +     * although we take care that TSC on thsi CPU may be lagging the master TSC
   3.113 +     * slightly. In this case we clamp the TSC difference to a minimum of zero.
   3.114 +     */
   3.115      rdtscl(low);
   3.116      delta_tsc = low - pcc;
   3.117 +    if ( unlikely(delta_tsc < 0) ) delta_tsc = 0;
   3.118      delta = ((u64)delta_tsc * st_scale_f);
   3.119      delta >>= 32;
   3.120      delta += ((u64)delta_tsc * st_scale_i);
   3.121 @@ -273,7 +279,7 @@ s_time_t get_s_time(void)
   3.122  /* Wall Clock time */
   3.123  static spinlock_t wctime_lock;
   3.124  struct timeval    wall_clock_time; /* wall clock time at last update */
   3.125 -s_time_t	      wctime_st;       /* system time at last update */
   3.126 +s_time_t          wctime_st;       /* system time at last update */
   3.127  
   3.128  void do_gettimeofday(struct timeval *tv)
   3.129  {
   3.130 @@ -318,7 +324,7 @@ void update_dom_time(shared_info_t *si)
   3.131      si->tv_usec      = wall_clock_time.tv_usec;
   3.132      si->wc_timestamp = wctime_st;
   3.133      si->wc_version++;
   3.134 -    spin_unlock_irqrestore(&wctime_lock, flags);	
   3.135 +    spin_unlock_irqrestore(&wctime_lock, flags);    
   3.136  
   3.137      TRC(printk(" 0x%08X%08X\n", (u32)(wctime_st>>32), (u32)wctime_st));
   3.138  }
   3.139 @@ -371,7 +377,7 @@ static void update_time(unsigned long fo
   3.140  int __init init_xeno_time()
   3.141  {
   3.142      int      cpu = smp_processor_id();
   3.143 -    u32	     cpu_cycle;  /* time of one cpu cyle in pico-seconds */
   3.144 +    u32      cpu_cycle;  /* time of one cpu cyle in pico-seconds */
   3.145      u64      scale;      /* scale factor  */
   3.146  
   3.147      spin_lock_init(&stime_lock);
     4.1 --- a/xen/common/schedule.c	Sun Mar 16 12:30:28 2003 +0000
     4.2 +++ b/xen/common/schedule.c	Sun Mar 16 13:11:46 2003 +0000
     4.3 @@ -249,7 +249,6 @@ asmlinkage void schedule(void)
     4.4   need_resched_back:
     4.5      perfc_incrc(sched_run2);
     4.6  
     4.7 -
     4.8      prev = current;
     4.9      next = NULL;
    4.10  
    4.11 @@ -262,14 +261,11 @@ asmlinkage void schedule(void)
    4.12      /* remove timer  */
    4.13      rem_ac_timer(&schedule_data[this_cpu].s_timer);
    4.14  
    4.15 -    /*
    4.16 -     * deschedule the current domain
    4.17 -     */
    4.18 +    /* deschedule the current domain */
    4.19  
    4.20      ASSERT(!in_interrupt());
    4.21      ASSERT(__task_on_runqueue(prev));
    4.22  
    4.23 -
    4.24      if (is_idle_task(prev)) 
    4.25          goto deschedule_done;
    4.26  
    4.27 @@ -371,11 +367,10 @@ asmlinkage void schedule(void)
    4.28      r_time = ((next_prime->evt - next->evt)/next->mcu_advance) + ctx_allow;
    4.29  
    4.30   sched_done:
    4.31 -    ASSERT(r_time != 0);
    4.32      ASSERT(r_time >= ctx_allow);
    4.33  
    4.34  #ifndef NDEBUG
    4.35 -    if ( (r_time==0) || (r_time < ctx_allow)) {
    4.36 +    if (r_time < ctx_allow) {
    4.37          printk("[%02d]: %lx\n", this_cpu, r_time);
    4.38          dump_rqueue(&schedule_data[this_cpu].runqueue, "foo");
    4.39      }
    4.40 @@ -393,7 +388,7 @@ asmlinkage void schedule(void)
    4.41   timer_redo:
    4.42      schedule_data[this_cpu].s_timer.expires  = now + r_time;
    4.43      if (add_ac_timer(&schedule_data[this_cpu].s_timer) == 1) {
    4.44 -        printk("SCHED[%02d]: Shit this shouldn't happen r_time=%lu\n", 
    4.45 +        printk("SCHED[%02d]: timeout already happened! r_time=%u\n",
    4.46                 this_cpu, r_time);
    4.47          now = NOW();
    4.48          goto timer_redo;