[<prev] [next>] [day] [month] [year] [list]
Message-ID: <87y6krkjue.fsf@devron.myhome.or.jp>
Date: Sat, 26 Dec 2009 03:08:09 +0900
From: OGAWA Hirofumi <hirofumi@...l.parknet.co.jp>
To: Thomas Gleixner <tglx@...utronix.de>
Cc: linux-kernel@...r.kernel.org
Subject: Oops in clockevents_notify()'s BUG_ON
Hi,
In poweroff process, I've got Oops in clockevents_notify()'s
BUG_ON. After some investigation, "hpet" clockevent hits BUG_ON().
On x86_64, hpet_legacy_clockevent_register() registers clockevent as
hpet_legacy_clockevent_register()
[...]
/*
* Start hpet with the boot cpu mask and make it
* global after the IO_APIC has been initialized.
*/
hpet_clockevent.cpumask = cpumask_of(smp_processor_id());
clockevents_register_device(&hpet_clockevent);
The comment says "boot cpu". But it's not true on x86_64, and one of my
machine is "second cpu" actually. [This might be one of problems]
And on that machine, hpet is used as oneshot_broadcast.
Then, in poweroff process, it calls cpu_down() for the nonboot cpus if
CONFIG_HOTPLUG_CPU is y. And clockevents_notify() checks clockevent
in clockevent_devices
So, the following code see hpet for broadcast on clockevent_devices. And
like mentioned above, hpet has cpumask like percpu clockevent, but it
is using as broadcast. So, this hits BUG_ON().
clockevents_notify()
[...]
list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) {
if (cpumask_test_cpu(cpu, dev->cpumask) &&
cpumask_weight(dev->cpumask) == 1) {
BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED);
list_del(&dev->list);
}
}
Well, so, attached patch fixes the problem on my machine. But I'm not
sure if it's right thing. Can you check it?
Thanks.
--
OGAWA Hirofumi <hirofumi@...l.parknet.co.jp>
Signed-off-by: OGAWA Hirofumi <hirofumi@...l.parknet.co.jp>
---
kernel/time/clockevents.c | 3 +++
1 file changed, 3 insertions(+)
diff -puN kernel/time/clockevents.c~hpet-shutdown-fix kernel/time/clockevents.c
--- linux-2.6/kernel/time/clockevents.c~hpet-shutdown-fix 2009-12-26 02:47:07.000000000 +0900
+++ linux-2.6-hirofumi/kernel/time/clockevents.c 2009-12-26 02:47:07.000000000 +0900
@@ -258,6 +258,9 @@ void clockevents_notify(unsigned long re
*/
cpu = *((int *)arg);
list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) {
+ if (tick_is_broadcast_device(dev))
+ continue;
+
if (cpumask_test_cpu(cpu, dev->cpumask) &&
cpumask_weight(dev->cpumask) == 1) {
BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED);
_
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists