ia64/xen-unstable
changeset 3147:2a161976f1d7
bitkeeper revision 1.1159.1.456 (41a620473ke53REbncb8KcHcla_d3g)
time.c:
Add per-cpu processed_system_time to get number of ticks right.
time.c:
Add per-cpu processed_system_time to get number of ticks right.
author | cl349@arcadians.cl.cam.ac.uk |
---|---|
date | Thu Nov 25 18:11:19 2004 +0000 (2004-11-25) |
parents | c470392942a5 |
children | 8b8852411a96 |
files | linux-2.6.9-xen-sparse/arch/xen/i386/kernel/time.c |
line diff
1.1 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/time.c Thu Nov 25 18:09:59 2004 +0000 1.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/time.c Thu Nov 25 18:11:19 2004 +0000 1.3 @@ -46,6 +46,7 @@ 1.4 #include <linux/bcd.h> 1.5 #include <linux/efi.h> 1.6 #include <linux/sysctl.h> 1.7 +#include <linux/percpu.h> 1.8 1.9 #include <asm/io.h> 1.10 #include <asm/smp.h> 1.11 @@ -91,7 +92,6 @@ u32 shadow_tsc_stamp; 1.12 u64 shadow_system_time; 1.13 static u32 shadow_time_version; 1.14 static struct timeval shadow_tv; 1.15 -extern u64 processed_system_time; 1.16 1.17 /* 1.18 * We use this to ensure that gettimeofday() is monotonically increasing. We 1.19 @@ -109,6 +109,7 @@ static long last_update_from_xen; /* U 1.20 1.21 /* Keep track of last time we did processing/updating of jiffies and xtime. */ 1.22 u64 processed_system_time; /* System time (ns) at last processing. */ 1.23 +DEFINE_PER_CPU(u64, processed_system_time); 1.24 1.25 #define NS_PER_TICK (1000000000ULL/HZ) 1.26 1.27 @@ -719,22 +720,39 @@ void time_resume(void) 1.28 static irqreturn_t local_timer_interrupt(int irq, void *dev_id, 1.29 struct pt_regs *regs) 1.30 { 1.31 -#if 0 1.32 - static int xxx = 0; 1.33 - if ((xxx++ % 2000) == 0) 1.34 - printk("local_timer_interrupt %d\n", xxx); 1.35 -#endif 1.36 + s64 delta; 1.37 + int cpu = smp_processor_id(); 1.38 + 1.39 + do { 1.40 + __get_time_values_from_xen(); 1.41 + 1.42 + delta = (s64)(shadow_system_time + 1.43 + ((s64)cur_timer->get_offset() * 1.44 + (s64)NSEC_PER_USEC) - 1.45 + per_cpu(processed_system_time, cpu)); 1.46 + } 1.47 + while (!TIME_VALUES_UP_TO_DATE); 1.48 1.49 - /* 1.50 - * update_process_times() expects us to have done irq_enter(). 1.51 - * Besides, if we don't timer interrupts ignore the global 1.52 - * interrupt lock, which is the WrongThing (tm) to do. 1.53 - */ 1.54 - // irq_enter(); 1.55 - /* XXX add processed_system_time loop thingy */ 1.56 - if (regs) 1.57 - update_process_times(user_mode(regs)); 1.58 - // irq_exit(); 1.59 + if (unlikely(delta < 0)) { 1.60 + printk("Timer ISR/%d: Time went backwards: %lld %lld %lld %lld\n", 1.61 + cpu, delta, shadow_system_time, 1.62 + ((s64)cur_timer->get_offset() * (s64)NSEC_PER_USEC), 1.63 + processed_system_time); 1.64 + return IRQ_HANDLED; 1.65 + } 1.66 + 1.67 + /* Process elapsed jiffies since last call. */ 1.68 + while (delta >= NS_PER_TICK) { 1.69 + delta -= NS_PER_TICK; 1.70 + per_cpu(processed_system_time, cpu) += NS_PER_TICK; 1.71 + if (regs) 1.72 + update_process_times(user_mode(regs)); 1.73 +#if 0 1.74 + if (regs) 1.75 + profile_tick(CPU_PROFILING, regs); 1.76 +#endif 1.77 + } 1.78 + 1.79 if (smp_processor_id() == 0) { 1.80 xxprint("bug bug\n"); 1.81 BUG(); 1.82 @@ -750,7 +768,13 @@ static struct irqaction local_irq_timer 1.83 1.84 void local_setup_timer(void) 1.85 { 1.86 - int time_irq; 1.87 + int seq, time_irq; 1.88 + int cpu = smp_processor_id(); 1.89 + 1.90 + do { 1.91 + seq = read_seqbegin(&xtime_lock); 1.92 + per_cpu(processed_system_time, cpu) = shadow_system_time; 1.93 + } while (read_seqretry(&xtime_lock, seq)); 1.94 1.95 time_irq = bind_virq_to_irq(VIRQ_TIMER); 1.96 (void)setup_irq(time_irq, &local_irq_timer);