All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [BUG] APM resume breakage from 2.6.18-rc1 clocksource changes
@ 2006-07-10 23:36 Mikael Pettersson
  2006-07-11 22:49 ` [PATCH] improve timekeeping resume robustness john stultz
  0 siblings, 1 reply; 2+ messages in thread
From: Mikael Pettersson @ 2006-07-10 23:36 UTC (permalink / raw)
  To: johnstul, mikpe; +Cc: linux-kernel, pavel

On Mon, 10 Jul 2006 10:58:47 -0700, john stultz wrote:
>So it seems possible that the timer tick will be enabled before the
>timekeeping resume code runs. I'm not sure why this isn't seen w/ ACPI
>suspend/resume, as I think they're using the same
>sysdev_class .suspend/.resume bits. 
>
>Anyway, I think this patch should fix it (I've only compile tested it,
>as I don't have my laptop on me right now). Would you mind giving it a
>try? 
>
>thanks
>-john

With this patch my Latitude resumes OK from APM suspend again.

Thanks John.

Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>

>diff --git a/kernel/timer.c b/kernel/timer.c
>index 396a3c0..afaa594 100644
>--- a/kernel/timer.c
>+++ b/kernel/timer.c
>@@ -966,7 +966,7 @@ void __init timekeeping_init(void)
> 	write_sequnlock_irqrestore(&xtime_lock, flags);
> }
> 
>-
>+static int timekeeping_suspended;
> /*
>  * timekeeping_resume - Resumes the generic timekeeping subsystem.
>  * @dev:	unused
>@@ -982,6 +982,18 @@ static int timekeeping_resume(struct sys
> 	write_seqlock_irqsave(&xtime_lock, flags);
> 	/* restart the last cycle value */
> 	clock->cycle_last = clocksource_read(clock);
>+	clock->error = 0;
>+	timekeeping_suspended = 0;
>+	write_sequnlock_irqrestore(&xtime_lock, flags);
>+	return 0;
>+}
>+
>+static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
>+{
>+	unsigned long flags;
>+
>+	write_seqlock_irqsave(&xtime_lock, flags);
>+	timekeeping_suspended = 1;
> 	write_sequnlock_irqrestore(&xtime_lock, flags);
> 	return 0;
> }
>@@ -989,6 +1001,7 @@ static int timekeeping_resume(struct sys
> /* sysfs resume/suspend bits for timekeeping */
> static struct sysdev_class timekeeping_sysclass = {
> 	.resume		= timekeeping_resume,
>+	.suspend	= timekeeping_suspend,
> 	set_kset_name("timekeeping"),
> };
> 
>@@ -1090,14 +1103,17 @@ static void clocksource_adjust(struct cl
> static void update_wall_time(void)
> {
> 	cycle_t offset;
>-
>-	clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
>+	
>+	/* avoid timekeeping before we're fully resumed */
>+	if (unlikely(timekeeping_suspended))
>+		return;
> 
> #ifdef CONFIG_GENERIC_TIME
> 	offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
> #else
> 	offset = clock->cycle_interval;
> #endif
>+	clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
> 
> 	/* normally this loop will run just once, however in the
> 	 * case of lost or late ticks, it will accumulate correctly.
>
>

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH] improve timekeeping resume robustness
  2006-07-10 23:36 [BUG] APM resume breakage from 2.6.18-rc1 clocksource changes Mikael Pettersson
@ 2006-07-11 22:49 ` john stultz
  0 siblings, 0 replies; 2+ messages in thread
From: john stultz @ 2006-07-11 22:49 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, pavel, Mikael Pettersson, Roman Zippel

On Tue, 2006-07-11 at 01:36 +0200, Mikael Pettersson wrote:
> With this patch my Latitude resumes OK from APM suspend again.

This patch (against current git tree) resolves problems seen w/ APM
suspend.

Due to resume initialization ordering, its possible we could get a timer
interrupt before the timekeeping resume() function is called. This patch
ensures we don't do any timekeeping accounting before we're fully
resumed.

Signed-off-by: John Stultz <johnstul@us.ibm.com>

diff --git a/kernel/timer.c b/kernel/timer.c
index 2a87430..6ffff03 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -968,6 +968,7 @@ void __init timekeeping_init(void)
 }
 
 
+static int timekeeping_suspended;
 /*
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
  * @dev:	unused
@@ -983,6 +984,18 @@ static int timekeeping_resume(struct sys
 	write_seqlock_irqsave(&xtime_lock, flags);
 	/* restart the last cycle value */
 	clock->cycle_last = clocksource_read(clock);
+	clock->error = 0;
+	timekeeping_suspended = 0;
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+	return 0;
+}
+
+static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
+{
+	unsigned long flags;
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	timekeeping_suspended = 1;
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 	return 0;
 }
@@ -990,6 +1003,7 @@ static int timekeeping_resume(struct sys
 /* sysfs resume/suspend bits for timekeeping */
 static struct sysdev_class timekeeping_sysclass = {
 	.resume		= timekeeping_resume,
+	.suspend	= timekeeping_suspend,
 	set_kset_name("timekeeping"),
 };
 
@@ -1099,14 +1113,17 @@ static void clocksource_adjust(struct cl
 static void update_wall_time(void)
 {
 	cycle_t offset;
-
-	clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
+	
+	/* Make sure we're fully resumed: */
+	if (unlikely(timekeeping_suspended))
+		return;
 
 #ifdef CONFIG_GENERIC_TIME
 	offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
 #else
 	offset = clock->cycle_interval;
 #endif
+	clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
 
 	/* normally this loop will run just once, however in the
 	 * case of lost or late ticks, it will accumulate correctly.



^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-07-11 22:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-10 23:36 [BUG] APM resume breakage from 2.6.18-rc1 clocksource changes Mikael Pettersson
2006-07-11 22:49 ` [PATCH] improve timekeeping resume robustness john stultz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.