direct-io.hg

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.
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);