Messages in this thread Patch in this message | | | Date | Fri, 25 Feb 2011 22:47:16 +0100 (CET) | From | Thomas Gleixner <> | Subject | Re: Performance/resume issues on Toshiba NB305 |
| |
On Fri, 25 Feb 2011, Seth Forshee wrote: > On Fri, Feb 25, 2011 at 09:37:39PM +0100, Thomas Gleixner wrote: > > On Fri, 25 Feb 2011, Seth Forshee wrote: > > That seems to be related to low power states. When the machine goes > > idle we switch into lower power states and that requires to use the > > hpet instead of the local apic timer as that one stops. > > > > You could verify that theory by booting with processor.max_cstate=1 > > This fixes the performance in combination with intel_idle.max_cstate=0. > Alternately, intel_idle.max_cstate=1 works. But the resume still hangs.
That was expected :)
> Is the answer to quirk the machine to avoid deep C-states, or is there > some better way I can fix this?
Let's wait for the intel and acpi folks. It would be interesting what the new intel toy says to your BIOS.
http://biosbits.org/
> > > +unlock: > > > raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); > > > } > > > > Why would you need that? We should not call that when the broadcast > > device does not have TICKDEV_MODE_ONESHOT. If we do the bug is > > somewhere else. > > Then there must be a bug. When I cleared CLOCK_EVT_FEAT_ONESHOT for the > HPET without this change the HPET got put into oneshot mode. The local > tick device is checked before switching to nohz, but not the broadcast > device. This change was just a quick hack to get around that and test my > theory.
Indeed. The patch below should cure that.
Thanks,
tglx
-----------> Subject: clockevents-fix-broadcast.patch From: Thomas Gleixner <tglx@linutronix.de> Date: Fri, 25 Feb 2011 22:34:23 +0100
Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- kernel/time/tick-broadcast.c | 10 ++++++++++ kernel/time/tick-common.c | 6 +++++- kernel/time/tick-internal.h | 3 +++ 3 files changed, 18 insertions(+), 1 deletion(-)
Index: linux-2.6/kernel/time/tick-broadcast.c =================================================================== --- linux-2.6.orig/kernel/time/tick-broadcast.c +++ linux-2.6/kernel/time/tick-broadcast.c @@ -600,4 +600,14 @@ int tick_broadcast_oneshot_active(void) return tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT; } +/* + * Check whether the broadcast device supports oneshot. + */ +bool tick_broadcast_oneshot_available(void) +{ + struct clock_event_device *bc = tick_broadcast_device.evtdev; + + return bc ? bc->features & CLOCK_EVT_FEAT_ONESHOT : false; +} + #endif Index: linux-2.6/kernel/time/tick-common.c =================================================================== --- linux-2.6.orig/kernel/time/tick-common.c +++ linux-2.6/kernel/time/tick-common.c @@ -51,7 +51,11 @@ int tick_is_oneshot_available(void) { struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev); - return dev && (dev->features & CLOCK_EVT_FEAT_ONESHOT); + if (!dev || !(dev->features & CLOCK_EVT_FEAT_ONESHOT)) + return 0; + if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) + return 1; + return tick_broadcast_oneshot_available(); } /* Index: linux-2.6/kernel/time/tick-internal.h =================================================================== --- linux-2.6.orig/kernel/time/tick-internal.h +++ linux-2.6/kernel/time/tick-internal.h @@ -36,6 +36,7 @@ extern void tick_shutdown_broadcast_ones extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc); extern int tick_broadcast_oneshot_active(void); extern void tick_check_oneshot_broadcast(int cpu); +bool tick_broadcast_oneshot_available(void); # else /* BROADCAST */ static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { @@ -46,6 +47,7 @@ static inline void tick_broadcast_switch static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } static inline int tick_broadcast_oneshot_active(void) { return 0; } static inline void tick_check_oneshot_broadcast(int cpu) { } +static inline bool tick_broadcast_oneshot_available(void) { return true; } # endif /* !BROADCAST */ #else /* !ONESHOT */ @@ -76,6 +78,7 @@ static inline int tick_resume_broadcast_ return 0; } static inline int tick_broadcast_oneshot_active(void) { return 0; } +static inline bool tick_broadcast_oneshot_available(void) { return true; } #endif /* !TICK_ONESHOT */ /*
| |