aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>2005-08-16 16:34:46 +0000
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>2005-08-16 16:34:46 +0000
commit62883ada700f62648aba9b182c9d6871fe5f74fb (patch)
tree2bd326c123e55c493054d67b92f785989d228bb5
parent81eb58aedbaa090f3ffbbad047ad42e8c6647c3a (diff)
parenteb72f656ae6128891e67422d68ef132bc70393ac (diff)
downloadxen-62883ada700f62648aba9b182c9d6871fe5f74fb.tar.gz
xen-62883ada700f62648aba9b182c9d6871fe5f74fb.tar.bz2
xen-62883ada700f62648aba9b182c9d6871fe5f74fb.zip
merge?
-rw-r--r--linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c45
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;
}