diff options
author | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-08-16 16:34:46 +0000 |
---|---|---|
committer | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-08-16 16:34:46 +0000 |
commit | 62883ada700f62648aba9b182c9d6871fe5f74fb (patch) | |
tree | 2bd326c123e55c493054d67b92f785989d228bb5 | |
parent | 81eb58aedbaa090f3ffbbad047ad42e8c6647c3a (diff) | |
parent | eb72f656ae6128891e67422d68ef132bc70393ac (diff) | |
download | xen-62883ada700f62648aba9b182c9d6871fe5f74fb.tar.gz xen-62883ada700f62648aba9b182c9d6871fe5f74fb.tar.bz2 xen-62883ada700f62648aba9b182c9d6871fe5f74fb.zip |
merge?
-rw-r--r-- | linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c | 45 |
1 files changed, 15 insertions, 30 deletions
diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c index ea421f080b..4ceded947a 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c @@ -540,17 +540,14 @@ unsigned long profile_pc(struct pt_regs *regs) EXPORT_SYMBOL(profile_pc); #endif -/* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick - */ -static inline void do_timer_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { s64 delta, delta_cpu; int cpu = smp_processor_id(); struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu); + write_seqlock(&xtime_lock); + do { get_time_values_from_xen(); @@ -582,7 +579,18 @@ static inline void do_timer_interrupt(int irq, void *dev_id, do_timer(regs); } - /* Local CPU jiffy work. */ + if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) { + update_wallclock(); + clock_was_set(); + } + + write_sequnlock(&xtime_lock); + + /* + * Local CPU jiffy work. No need to hold xtime_lock, and I'm not sure + * if there is risk of deadlock if we do (since update_process_times + * may do scheduler rebalancing work and thus acquire runqueue locks). + */ while (delta_cpu >= NS_PER_TICK) { delta_cpu -= NS_PER_TICK; per_cpu(processed_system_time, cpu) += NS_PER_TICK; @@ -590,29 +598,6 @@ static inline void do_timer_interrupt(int irq, void *dev_id, profile_tick(CPU_PROFILING, regs); } - if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) { - update_wallclock(); - clock_was_set(); - } -} - -/* - * This is the same as the above, except we _also_ save the current - * Time Stamp Counter value at the time of the timer interrupt, so that - * we later on can estimate the time of day more exactly. - */ -irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - /* - * Here we are in the timer irq handler. We just have irqs locally - * disabled but we don't know if the timer_bh is running on the other - * CPU. We need to avoid to SMP race with it. NOTE: we don' t need - * the irq version of write_lock because as just said we have irq - * locally disabled. -arca - */ - write_seqlock(&xtime_lock); - do_timer_interrupt(irq, NULL, regs); - write_sequnlock(&xtime_lock); return IRQ_HANDLED; } |