xen-vtx-unstable
changeset 6193: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>
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