ia64/xen-unstable

changeset 6208:d80dd1169acc

Fix xtime_lock handling in timer interrupt. There's no need
to hold it while doing local VCPU work, and there might be
danger of deadlock if we do.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Aug 16 15:40:43 2005 +0000 (2005-08-16)
parents 3d187585c141
children 24e881f81cea
files linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c	Tue Aug 16 11:20:47 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c	Tue Aug 16 15:40:43 2005 +0000
     1.3 @@ -540,17 +540,14 @@ unsigned long profile_pc(struct pt_regs 
     1.4  EXPORT_SYMBOL(profile_pc);
     1.5  #endif
     1.6  
     1.7 -/*
     1.8 - * timer_interrupt() needs to keep up the real-time clock,
     1.9 - * as well as call the "do_timer()" routine every clocktick
    1.10 - */
    1.11 -static inline void do_timer_interrupt(int irq, void *dev_id,
    1.12 -					struct pt_regs *regs)
    1.13 +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
    1.14  {
    1.15  	s64 delta, delta_cpu;
    1.16  	int cpu = smp_processor_id();
    1.17  	struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
    1.18  
    1.19 +	write_seqlock(&xtime_lock);
    1.20 +
    1.21  	do {
    1.22  		get_time_values_from_xen();
    1.23  
    1.24 @@ -582,7 +579,18 @@ static inline void do_timer_interrupt(in
    1.25  		do_timer(regs);
    1.26  	}
    1.27  
    1.28 -	/* Local CPU jiffy work. */
    1.29 +	if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) {
    1.30 +		update_wallclock();
    1.31 +		clock_was_set();
    1.32 +	}
    1.33 +
    1.34 +	write_sequnlock(&xtime_lock);
    1.35 +
    1.36 +	/*
    1.37 +         * Local CPU jiffy work. No need to hold xtime_lock, and I'm not sure
    1.38 +         * if there is risk of deadlock if we do (since update_process_times
    1.39 +         * may do scheduler rebalancing work and thus acquire runqueue locks).
    1.40 +         */
    1.41  	while (delta_cpu >= NS_PER_TICK) {
    1.42  		delta_cpu -= NS_PER_TICK;
    1.43  		per_cpu(processed_system_time, cpu) += NS_PER_TICK;
    1.44 @@ -590,29 +598,6 @@ static inline void do_timer_interrupt(in
    1.45  		profile_tick(CPU_PROFILING, regs);
    1.46  	}
    1.47  
    1.48 -	if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) {
    1.49 -		update_wallclock();
    1.50 -		clock_was_set();
    1.51 -	}
    1.52 -}
    1.53 -
    1.54 -/*
    1.55 - * This is the same as the above, except we _also_ save the current
    1.56 - * Time Stamp Counter value at the time of the timer interrupt, so that
    1.57 - * we later on can estimate the time of day more exactly.
    1.58 - */
    1.59 -irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
    1.60 -{
    1.61 -	/*
    1.62 -	 * Here we are in the timer irq handler. We just have irqs locally
    1.63 -	 * disabled but we don't know if the timer_bh is running on the other
    1.64 -	 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
    1.65 -	 * the irq version of write_lock because as just said we have irq
    1.66 -	 * locally disabled. -arca
    1.67 -	 */
    1.68 -	write_seqlock(&xtime_lock);
    1.69 -	do_timer_interrupt(irq, NULL, regs);
    1.70 -	write_sequnlock(&xtime_lock);
    1.71  	return IRQ_HANDLED;
    1.72  }
    1.73