From: Andrew Morton <akpm@linux-foundation.org>
To: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@elte.hu>,
LKML <linux-kernel@vger.kernel.org>,
John Stultz <johnstul@us.ibm.com>,
linux-acpi@vger.kernel.org
Subject: Re: [patch 3/3] clockevents: Fix resume logic - updated version
Date: Fri, 11 May 2007 09:47:50 -0700 [thread overview]
Message-ID: <20070511094750.e91ea55b.akpm@linux-foundation.org> (raw)
In-Reply-To: <200705102212.08046.rjw@sisk.pl>
On Thu, 10 May 2007 22:12:07 +0200 "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> On Thursday, 10 May 2007 11:27, Thomas Gleixner wrote:
> > On Thu, 2007-05-10 at 02:18 -0700, Andrew Morton wrote:
> > > > > > If that patch makes the problem go away, then we should have a quite
> > > > > > good hint what we need to look at.
> > > > >
> > > > > No joy, sorry. It still hangs at the last statement in acpi_evaluate_object().
> > > >
> > > > Can you add "nolapic_timer" to the command line please ?
> > > >
> > >
> > > That works.
> >
> > Ok, that boils it down to the change, which affects the lapic timer
> > resume. It does nothing else, than fiddling in some APIC registers, but
> > I don't see how this affects the ACPI stuff. This smells extremly fishy.
>
> Hmm, I wonder if it might be related to the execution of the _GTS ACPI control
> method in acpi_enter_sleep_state_prep() in violation of the spec.
>
> Andrew, could you please try to apply the following change on top of the
> previous ones and see if the machine still hangs in the same place without
> "nolapic_timer"?
>
> ---
> drivers/acpi/hardware/hwsleep.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> Index: linux-2.6.21/drivers/acpi/hardware/hwsleep.c
> ===================================================================
> --- linux-2.6.21.orig/drivers/acpi/hardware/hwsleep.c
> +++ linux-2.6.21/drivers/acpi/hardware/hwsleep.c
> @@ -200,10 +200,10 @@ acpi_status acpi_enter_sleep_state_prep(
> return_ACPI_STATUS(status);
> }
>
> - status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
> + /*status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
> if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
> return_ACPI_STATUS(status);
> - }
> + }*/
>
> /* Setup the argument to _SST */
>
I tested this against Thomas's original patch (below). Still hangs, in the
same way.
From: Thomas Gleixner <tglx@linutronix.de>
We need to make sure that the clockevent devices are resumed before the
tick is resumed. The current resume logic does not guarantee this.
Add CLOCK_EVT_MODE_RESUME and call the set mode functions of the clock
event devices before resuming the tick / oneshot functionality.
Fixup the existing users.
Fix the PIT handling of CLOCK_EVT_SHUTDOWN by disabling the interrupt
instead of switching to oneshot mode, as this causes slowness on a couple
of systems.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Andi Kleen <ak@suse.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
arch/i386/kernel/apic.c | 3 +
arch/i386/kernel/hpet.c | 71 ++-------------------------------
arch/i386/kernel/i8253.c | 43 +++++++++++++------
include/linux/clockchips.h | 1
kernel/time/tick-broadcast.c | 4 +
kernel/time/tick-common.c | 16 ++++---
6 files changed, 51 insertions(+), 87 deletions(-)
diff -puN arch/i386/kernel/apic.c~clockevents-fix-resume-logic-updated-version arch/i386/kernel/apic.c
--- a/arch/i386/kernel/apic.c~clockevents-fix-resume-logic-updated-version
+++ a/arch/i386/kernel/apic.c
@@ -263,6 +263,9 @@ static void lapic_timer_setup(enum clock
v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
apic_write_around(APIC_LVTT, v);
break;
+ case CLOCK_EVT_MODE_RESUME:
+ /* Nothing to do here */
+ break;
}
local_irq_restore(flags);
diff -puN arch/i386/kernel/hpet.c~clockevents-fix-resume-logic-updated-version arch/i386/kernel/hpet.c
--- a/arch/i386/kernel/hpet.c~clockevents-fix-resume-logic-updated-version
+++ a/arch/i386/kernel/hpet.c
@@ -187,6 +187,10 @@ static void hpet_set_mode(enum clock_eve
cfg &= ~HPET_TN_ENABLE;
hpet_writel(cfg, HPET_T0_CFG);
break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ hpet_enable_int();
+ break;
}
}
@@ -217,6 +221,7 @@ static struct clocksource clocksource_hp
.mask = HPET_MASK,
.shift = HPET_SHIFT,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .resume = hpet_start_counter,
};
/*
@@ -291,7 +296,6 @@ int __init hpet_enable(void)
clocksource_register(&clocksource_hpet);
-
if (id & HPET_ID_LEGSUP) {
hpet_enable_int();
hpet_reserve_platform_timers(id);
@@ -524,68 +528,3 @@ irqreturn_t hpet_rtc_interrupt(int irq,
return IRQ_HANDLED;
}
#endif
-
-
-/*
- * Suspend/resume part
- */
-
-#ifdef CONFIG_PM
-
-static int hpet_suspend(struct sys_device *sys_device, pm_message_t state)
-{
- unsigned long cfg = hpet_readl(HPET_CFG);
-
- cfg &= ~(HPET_CFG_ENABLE|HPET_CFG_LEGACY);
- hpet_writel(cfg, HPET_CFG);
-
- return 0;
-}
-
-static int hpet_resume(struct sys_device *sys_device)
-{
- unsigned int id;
-
- hpet_start_counter();
-
- id = hpet_readl(HPET_ID);
-
- if (id & HPET_ID_LEGSUP)
- hpet_enable_int();
-
- return 0;
-}
-
-static struct sysdev_class hpet_class = {
- set_kset_name("hpet"),
- .suspend = hpet_suspend,
- .resume = hpet_resume,
-};
-
-static struct sys_device hpet_device = {
- .id = 0,
- .cls = &hpet_class,
-};
-
-
-static __init int hpet_register_sysfs(void)
-{
- int err;
-
- if (!is_hpet_capable())
- return 0;
-
- err = sysdev_class_register(&hpet_class);
-
- if (!err) {
- err = sysdev_register(&hpet_device);
- if (err)
- sysdev_class_unregister(&hpet_class);
- }
-
- return err;
-}
-
-device_initcall(hpet_register_sysfs);
-
-#endif
diff -puN arch/i386/kernel/i8253.c~clockevents-fix-resume-logic-updated-version arch/i386/kernel/i8253.c
--- a/arch/i386/kernel/i8253.c~clockevents-fix-resume-logic-updated-version
+++ a/arch/i386/kernel/i8253.c
@@ -3,11 +3,11 @@
*
*/
#include <linux/clockchips.h>
-#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/jiffies.h>
-#include <linux/sysdev.h>
#include <linux/module.h>
-#include <linux/init.h>
+#include <linux/spinlock.h>
#include <asm/smp.h>
#include <asm/delay.h>
@@ -26,6 +26,24 @@ EXPORT_SYMBOL(i8253_lock);
*/
struct clock_event_device *global_clock_event;
+/* Status of the PIT interrupt */
+static int pit_irq_disabled;
+
+/*
+ * Control pit interrupt enable / disable
+ */
+static void pit_control_irq(int disable)
+{
+ if (pit_irq_disabled == disable)
+ return;
+
+ pit_irq_disabled = disable;
+ if (disable)
+ disable_irq(0);
+ else
+ enable_irq(0);
+}
+
/*
* Initialize the PIT timer.
*
@@ -42,26 +60,23 @@ static void init_pit_timer(enum clock_ev
case CLOCK_EVT_MODE_PERIODIC:
/* binary, mode 2, LSB/MSB, ch 0 */
outb_p(0x34, PIT_MODE);
- udelay(10);
outb_p(LATCH & 0xff , PIT_CH0); /* LSB */
- udelay(10);
outb(LATCH >> 8 , PIT_CH0); /* MSB */
+ pit_control_irq(0);
break;
- /*
- * Avoid unnecessary state transitions, as it confuses
- * Geode / Cyrix based boxen.
- */
case CLOCK_EVT_MODE_SHUTDOWN:
- if (evt->mode == CLOCK_EVT_MODE_UNUSED)
- break;
case CLOCK_EVT_MODE_UNUSED:
- if (evt->mode == CLOCK_EVT_MODE_SHUTDOWN)
- break;
+ pit_control_irq(1);
+ break;
case CLOCK_EVT_MODE_ONESHOT:
/* One shot setup */
outb_p(0x38, PIT_MODE);
- udelay(10);
+ pit_control_irq(0);
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ /* Nothing to do here */
break;
}
spin_unlock_irqrestore(&i8253_lock, flags);
diff -puN include/linux/clockchips.h~clockevents-fix-resume-logic-updated-version include/linux/clockchips.h
--- a/include/linux/clockchips.h~clockevents-fix-resume-logic-updated-version
+++ a/include/linux/clockchips.h
@@ -23,6 +23,7 @@ enum clock_event_mode {
CLOCK_EVT_MODE_SHUTDOWN,
CLOCK_EVT_MODE_PERIODIC,
CLOCK_EVT_MODE_ONESHOT,
+ CLOCK_EVT_MODE_RESUME,
};
/* Clock event notification values */
diff -puN kernel/time/tick-broadcast.c~clockevents-fix-resume-logic-updated-version kernel/time/tick-broadcast.c
--- a/kernel/time/tick-broadcast.c~clockevents-fix-resume-logic-updated-version
+++ a/kernel/time/tick-broadcast.c
@@ -292,7 +292,7 @@ void tick_suspend_broadcast(void)
spin_lock_irqsave(&tick_broadcast_lock, flags);
bc = tick_broadcast_device.evtdev;
- if (bc && tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
+ if (bc)
clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
spin_unlock_irqrestore(&tick_broadcast_lock, flags);
@@ -309,6 +309,8 @@ int tick_resume_broadcast(void)
bc = tick_broadcast_device.evtdev;
if (bc) {
+ clockevents_set_mode(bc, CLOCK_EVT_MODE_RESUME);
+
switch (tick_broadcast_device.mode) {
case TICKDEV_MODE_PERIODIC:
if(!cpus_empty(tick_broadcast_mask))
diff -puN kernel/time/tick-common.c~clockevents-fix-resume-logic-updated-version kernel/time/tick-common.c
--- a/kernel/time/tick-common.c~clockevents-fix-resume-logic-updated-version
+++ a/kernel/time/tick-common.c
@@ -318,12 +318,17 @@ static void tick_resume(void)
{
struct tick_device *td = &__get_cpu_var(tick_cpu_device);
unsigned long flags;
+ int broadcast = tick_resume_broadcast();
spin_lock_irqsave(&tick_device_lock, flags);
- if (td->mode == TICKDEV_MODE_PERIODIC)
- tick_setup_periodic(td->evtdev, 0);
- else
- tick_resume_oneshot();
+ clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_RESUME);
+
+ if (!broadcast) {
+ if (td->mode == TICKDEV_MODE_PERIODIC)
+ tick_setup_periodic(td->evtdev, 0);
+ else
+ tick_resume_oneshot();
+ }
spin_unlock_irqrestore(&tick_device_lock, flags);
}
@@ -360,8 +365,7 @@ static int tick_notify(struct notifier_b
break;
case CLOCK_EVT_NOTIFY_RESUME:
- if (!tick_resume_broadcast())
- tick_resume();
+ tick_resume();
break;
default:
_
next prev parent reply other threads:[~2007-05-11 16:48 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20070430102837.748238000@linutronix.de>
2007-05-02 0:33 ` [patch 0/3] Clocksource / clockevent updates Andrew Morton
2007-05-02 6:09 ` Thomas Gleixner
2007-05-02 6:14 ` Andrew Morton
[not found] ` <20070430102852.042964000@linutronix.de>
2007-05-05 7:34 ` [patch 3/3] clockevents: Fix resume logic Andrew Morton
2007-05-05 11:51 ` Ingo Molnar
2007-05-06 15:03 ` [patch 3/3] clockevents: Fix resume logic - updated version Thomas Gleixner
2007-05-08 10:37 ` Andrew Morton
2007-05-09 5:59 ` Andrew Morton
2007-05-09 7:10 ` Andrew Morton
2007-05-09 8:18 ` Thomas Gleixner
2007-05-09 8:22 ` Andrew Morton
2007-05-09 8:31 ` Andrew Morton
2007-05-09 8:59 ` Thomas Gleixner
2007-05-09 11:45 ` Rafael J. Wysocki
2007-05-09 12:24 ` Thomas Gleixner
2007-05-09 13:12 ` Rafael J. Wysocki
2007-05-09 13:19 ` Thomas Gleixner
2007-05-09 17:09 ` Rafael J. Wysocki
2007-05-09 17:15 ` Thomas Gleixner
2007-05-09 18:36 ` Rafael J. Wysocki
2007-05-09 20:45 ` Thomas Gleixner
2007-05-09 20:53 ` Rafael J. Wysocki
2007-05-09 21:26 ` Thomas Gleixner
2007-05-10 8:46 ` Andrew Morton
2007-05-10 8:55 ` Thomas Gleixner
2007-05-10 9:18 ` Andrew Morton
2007-05-10 9:27 ` Thomas Gleixner
2007-05-10 20:12 ` Rafael J. Wysocki
2007-05-11 16:47 ` Andrew Morton [this message]
2007-05-11 20:10 ` Rafael J. Wysocki
2007-05-11 20:28 ` Andrew Morton
2007-05-11 21:02 ` Rafael J. Wysocki
2007-05-11 21:09 ` Rafael J. Wysocki
2007-05-12 6:56 ` Andrew Morton
2007-05-12 8:46 ` Thomas Gleixner
2007-05-12 9:00 ` Andrew Morton
2007-05-12 9:18 ` Thomas Gleixner
2007-05-12 10:07 ` Andrew Morton
2007-05-12 11:44 ` Thomas Gleixner
2007-05-12 16:51 ` Andrew Morton
2007-05-12 17:01 ` Thomas Gleixner
2007-05-12 17:23 ` Andrew Morton
2007-05-12 19:36 ` Thomas Gleixner
2007-05-12 19:36 ` Thomas Gleixner
2007-05-12 19:56 ` Thomas Gleixner
2007-05-13 1:11 ` Andrew Morton
2007-05-13 8:07 ` Thomas Gleixner
2007-05-13 16:48 ` Thomas Gleixner
2007-05-13 19:09 ` Andrew Morton
2007-05-13 20:07 ` Ingo Molnar
2007-05-13 22:35 ` Andrew Morton
2007-05-12 18:49 ` Thomas Gleixner
2007-05-12 11:52 ` Thomas Gleixner
2007-05-15 16:52 ` Pavel Machek
2007-05-15 16:52 ` Pavel Machek
2007-05-13 16:12 ` Thomas Gleixner
2007-05-14 6:42 ` Andrew Morton
2007-05-14 6:58 ` Thomas Gleixner
2007-05-09 12:52 ` Rafael J. Wysocki
2007-05-09 17:14 ` Andrew Morton
2007-05-09 18:55 ` Rafael J. Wysocki
[not found] ` <20070430102851.987296000@linutronix.de>
2007-05-07 6:43 ` [patch 2/3] ACPI: Keep TSC stable, when lapic_timer_c2_ok is set Andrew Morton
2007-05-07 7:01 ` Thomas Gleixner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070511094750.e91ea55b.akpm@linux-foundation.org \
--to=akpm@linux-foundation.org \
--cc=johnstul@us.ibm.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=rjw@sisk.pl \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.