# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1260521413 0
# Node ID 1396dfb8d6badc181cda28364b3b1a9317b2462a
# Parent b2ccd48f2f9bb3747659d85f7c15a0f4fe7d787a
x86: Allow HPET to set timers more sloppily by seeing each CPU's
acceptable deadline range, rather than just deadline start.
Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
xen/arch/x86/acpi/cpuidle_menu.c | 2 +-
xen/arch/x86/hpet.c | 16 ++++++++--------
xen/arch/x86/time.c | 2 +-
xen/common/timer.c | 19 +++++++++++--------
xen/include/xen/timer.h | 3 ++-
5 files changed, 23 insertions(+), 19 deletions(-)
diff -r b2ccd48f2f9b -r 1396dfb8d6ba xen/arch/x86/acpi/cpuidle_menu.c
--- a/xen/arch/x86/acpi/cpuidle_menu.c Fri Dec 11 08:47:51 2009 +0000
+++ b/xen/arch/x86/acpi/cpuidle_menu.c Fri Dec 11 08:50:13 2009 +0000
@@ -49,7 +49,7 @@ static DEFINE_PER_CPU(struct menu_device
static unsigned int get_sleep_length_us(void)
{
- s_time_t us = (per_cpu(timer_deadline, smp_processor_id()) - NOW()) / 1000;
+ s_time_t us = (this_cpu(timer_deadline_start) - NOW()) / 1000;
/*
* while us < 0 or us > (u32)-1, return a large u32,
* choose (unsigned int)-2000 to avoid wrapping while added with exit
diff -r b2ccd48f2f9b -r 1396dfb8d6ba xen/arch/x86/hpet.c
--- a/xen/arch/x86/hpet.c Fri Dec 11 08:47:51 2009 +0000
+++ b/xen/arch/x86/hpet.c Fri Dec 11 08:50:13 2009 +0000
@@ -190,10 +190,10 @@ again:
/* find all expired events */
for_each_cpu_mask(cpu, ch->cpumask)
{
- if ( per_cpu(timer_deadline, cpu) <= now )
+ if ( per_cpu(timer_deadline_start, cpu) <= now )
cpu_set(cpu, mask);
- else if ( per_cpu(timer_deadline, cpu) < next_event )
- next_event = per_cpu(timer_deadline, cpu);
+ else if ( per_cpu(timer_deadline_end, cpu) < next_event )
+ next_event = per_cpu(timer_deadline_end, cpu);
}
/* wakeup the cpus which have an expired event. */
@@ -629,7 +629,7 @@ void hpet_broadcast_enter(void)
int cpu = smp_processor_id();
struct hpet_event_channel *ch = per_cpu(cpu_bc_channel, cpu);
- if ( this_cpu(timer_deadline) == 0 )
+ if ( this_cpu(timer_deadline_start) == 0 )
return;
if ( !ch )
@@ -649,8 +649,8 @@ void hpet_broadcast_enter(void)
cpu_set(cpu, ch->cpumask);
/* reprogram if current cpu expire time is nearer */
- if ( this_cpu(timer_deadline) < ch->next_event )
- reprogram_hpet_evt_channel(ch, this_cpu(timer_deadline), NOW(), 1);
+ if ( this_cpu(timer_deadline_end) < ch->next_event )
+ reprogram_hpet_evt_channel(ch, this_cpu(timer_deadline_end), NOW(), 1);
spin_unlock(&ch->lock);
}
@@ -660,7 +660,7 @@ void hpet_broadcast_exit(void)
int cpu = smp_processor_id();
struct hpet_event_channel *ch = per_cpu(cpu_bc_channel, cpu);
- if ( this_cpu(timer_deadline) == 0 )
+ if ( this_cpu(timer_deadline_start) == 0 )
return;
BUG_ON( !ch );
@@ -671,7 +671,7 @@ void hpet_broadcast_exit(void)
{
/* Reprogram the deadline; trigger timer work now if it has passed. */
enable_APIC_timer();
- if ( !reprogram_timer(per_cpu(timer_deadline, cpu)) )
+ if ( !reprogram_timer(this_cpu(timer_deadline_start)) )
raise_softirq(TIMER_SOFTIRQ);
if ( cpus_empty(ch->cpumask) && ch->next_event != STIME_MAX )
diff -r b2ccd48f2f9b -r 1396dfb8d6ba xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Fri Dec 11 08:47:51 2009 +0000
+++ b/xen/arch/x86/time.c Fri Dec 11 08:50:13 2009 +0000
@@ -1367,7 +1367,7 @@ void pit_broadcast_exit(void)
int cpu = smp_processor_id();
if ( cpu_test_and_clear(cpu, pit_broadcast_mask) )
- reprogram_timer(per_cpu(timer_deadline, cpu));
+ reprogram_timer(per_cpu(timer_deadline_start, cpu));
}
int pit_broadcast_is_available(void)
diff -r b2ccd48f2f9b -r 1396dfb8d6ba xen/common/timer.c
--- a/xen/common/timer.c Fri Dec 11 08:47:51 2009 +0000
+++ b/xen/common/timer.c Fri Dec 11 08:50:13 2009 +0000
@@ -38,7 +38,8 @@ struct timers {
static DEFINE_PER_CPU(struct timers, timers);
-DEFINE_PER_CPU(s_time_t, timer_deadline);
+DEFINE_PER_CPU(s_time_t, timer_deadline_start);
+DEFINE_PER_CPU(s_time_t, timer_deadline_end);
/****************************************************************************
* HEAP OPERATIONS.
@@ -425,10 +426,11 @@ static void timer_softirq_action(void)
if ( unlikely(ts->overflow) )
{
/* Find earliest deadline at head of list or top of heap. */
- this_cpu(timer_deadline) = ts->list->expires;
+ this_cpu(timer_deadline_start) = ts->list->expires;
if ( (GET_HEAP_SIZE(heap) != 0) &&
- ((t = heap[1])->expires < this_cpu(timer_deadline)) )
- this_cpu(timer_deadline) = t->expires;
+ ((t = heap[1])->expires < this_cpu(timer_deadline_start)) )
+ this_cpu(timer_deadline_start) = t->expires;
+ this_cpu(timer_deadline_end) = this_cpu(timer_deadline_start);
}
else
{
@@ -455,10 +457,11 @@ static void timer_softirq_action(void)
end = t->expires_end;
}
- this_cpu(timer_deadline) = start;
- }
-
- if ( !reprogram_timer(this_cpu(timer_deadline)) )
+ this_cpu(timer_deadline_start) = start;
+ this_cpu(timer_deadline_end) = end;
+ }
+
+ if ( !reprogram_timer(this_cpu(timer_deadline_start)) )
raise_softirq(TIMER_SOFTIRQ);
spin_unlock_irq(&ts->lock);
diff -r b2ccd48f2f9b -r 1396dfb8d6ba xen/include/xen/timer.h
--- a/xen/include/xen/timer.h Fri Dec 11 08:47:51 2009 +0000
+++ b/xen/include/xen/timer.h Fri Dec 11 08:50:13 2009 +0000
@@ -117,7 +117,8 @@ extern void timer_init(void);
* Next timer deadline for each CPU.
* Modified only by the local CPU and never in interrupt context.
*/
-DECLARE_PER_CPU(s_time_t, timer_deadline);
+DECLARE_PER_CPU(s_time_t, timer_deadline_start);
+DECLARE_PER_CPU(s_time_t, timer_deadline_end);
/* Arch-defined function to reprogram timer hardware for new deadline. */
extern int reprogram_timer(s_time_t timeout);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|