diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2008-07-08 10:12:26 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-09 05:03:21 -0400 |
commit | e2079c43861f71b2deb78ee20e247ad954fdd67e (patch) | |
tree | 6d745575d04901d3eba0dd371487d1841fa87bee /arch/x86/kernel/acpi | |
parent | c2e6d65bcea2672788f9bb58ce7606c41388387b (diff) |
x86: fix C1E && nx6325 stability problem
The problems are that, with the ACPI vs timer overring issue _fixed_,
after using the box for some time (between several seconds and 1 hour, at
random) processes get very high CPU loads (once I've got X using 107% of
the CPU, for example) and the system becomes unresponsive, as though there
were interrupts lost or something similar.
Andreas Herrman reproduced similar problems:
> Ok, now I've reproduced the stability problem.
> - Using tip/master,
> - reverting e38502eb8aa82314d5ab0eba45f50e6790dadd88 and
> - applying your patch from this posting
> http://marc.info/?l=linux-kernel&m=121539354224562&w=4
>
> Starting X, firefox, gimp, tuxpaint and doing some drawing in tuxpaint
> results in a slow system. Drawing is almost not possible anymore --
> Selections of new colors, cursors etc. is performed with huge delay
> if it's performed at all.
>
> BTW, the code sets up timer IRQ as Virtual Wire IRQ:
>
> Jul 8 14:57:58 kodscha IO-APIC (apicid-pin) 2-22, 2-23 not connected.
> Jul 8 14:57:58 kodscha ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
> Jul 8 14:57:58 kodscha ...trying to set up timer as Virtual Wire IRQ... works.
>
> and both INT0 and INT2 of IOAPIC are masked:
>
> Jul 8 14:57:58 kodscha NR Dst Mask Trig IRR Pol Stat Dmod Deli Vect:
> Jul 8 14:57:58 kodscha 00 000 1 0 0 0 0 0 0 00
> Jul 8 14:57:58 kodscha 01 003 0 0 0 0 0 1 1 31
> Jul 8 14:57:58 kodscha 02 003 1 0 0 0 0 0 0 30
>
> I've also seen strange CPU utilization -- with syslog-ng:
>
> top - 15:33:06 up 35 min, 4 users, load average: 1.70, 0.68, 0.37
> Tasks: 64 total, 4 running, 60 sleeping, 0 stopped, 0 zombie
> Cpu0 : 0.0%us,100.0%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
> Cpu1 : 6.4%us, 87.2%sy, 0.0%ni, 5.8%id, 0.0%wa, 0.6%hi, 0.0%si, 0.0%st
> Mem: 895384k total, 283568k used, 611816k free, 35492k buffers
> Swap: 1959920k total, 0k used, 1959920k free, 163044k cached
>
> PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
> 4632 root 20 0 17216 800 580 S 104 0.1 0:34.22 syslog-ng
> 28505 root 20 0 205m 11m 4024 S 6 1.3 0:21.16 X
> 28518 root 20 0 56292 5652 4492 S 1 0.6 0:01.80 fluxbox
> 1 root 20 0 3724 608 508 S 0 0.1 0:00.36 init
>
> So far I have no clue why C1E-idle in conjunction with virtual wire
> mode causes this strange behaviour.
>
> ... and I start to think about the root cause of all this.
>
> I've performed similar tests under X with the IRQ0/INT0 configuration and
> I did not see above symptoms.
So lets fall back to the IRQ0/INT0 configuration on this box.
This basically restores the dont-use-the-lapic-timer exception mechanism
that was unconditional on this box prior commit 8750bf5 ("x86: add C1E
aware idle function").
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/acpi')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 5c0107602b62..e1f01394b681 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -1373,8 +1373,6 @@ static void __init acpi_process_madt(void) | |||
1373 | return; | 1373 | return; |
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | #ifdef __i386__ | ||
1377 | |||
1378 | static int __init disable_acpi_irq(const struct dmi_system_id *d) | 1376 | static int __init disable_acpi_irq(const struct dmi_system_id *d) |
1379 | { | 1377 | { |
1380 | if (!acpi_force) { | 1378 | if (!acpi_force) { |
@@ -1436,6 +1434,17 @@ dmi_disable_irq0_through_ioapic(const struct dmi_system_id *d) | |||
1436 | } | 1434 | } |
1437 | 1435 | ||
1438 | /* | 1436 | /* |
1437 | * Force ignoring BIOS IRQ0 pin2 override | ||
1438 | */ | ||
1439 | static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) | ||
1440 | { | ||
1441 | pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n", d->ident); | ||
1442 | acpi_skip_timer_override = 1; | ||
1443 | force_mask_ioapic_irq_2(); | ||
1444 | return 0; | ||
1445 | } | ||
1446 | |||
1447 | /* | ||
1439 | * If your system is blacklisted here, but you find that acpi=force | 1448 | * If your system is blacklisted here, but you find that acpi=force |
1440 | * works for you, please contact acpi-devel@sourceforge.net | 1449 | * works for you, please contact acpi-devel@sourceforge.net |
1441 | */ | 1450 | */ |
@@ -1628,11 +1637,35 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { | |||
1628 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), | 1637 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), |
1629 | }, | 1638 | }, |
1630 | }, | 1639 | }, |
1640 | /* | ||
1641 | * HP laptops which use a DSDT reporting as HP/SB400/10000, | ||
1642 | * which includes some code which overrides all temperature | ||
1643 | * trip points to 16C if the INTIN2 input of the I/O APIC | ||
1644 | * is enabled. This input is incorrectly designated the | ||
1645 | * ISA IRQ 0 via an interrupt source override even though | ||
1646 | * it is wired to the output of the master 8259A and INTIN0 | ||
1647 | * is not connected at all. Force ignoring BIOS IRQ0 pin2 | ||
1648 | * override in that cases. | ||
1649 | */ | ||
1650 | { | ||
1651 | .callback = dmi_ignore_irq0_timer_override, | ||
1652 | .ident = "HP NX6125 laptop", | ||
1653 | .matches = { | ||
1654 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
1655 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6125"), | ||
1656 | }, | ||
1657 | }, | ||
1658 | { | ||
1659 | .callback = dmi_ignore_irq0_timer_override, | ||
1660 | .ident = "HP NX6325 laptop", | ||
1661 | .matches = { | ||
1662 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
1663 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), | ||
1664 | }, | ||
1665 | }, | ||
1631 | {} | 1666 | {} |
1632 | }; | 1667 | }; |
1633 | 1668 | ||
1634 | #endif /* __i386__ */ | ||
1635 | |||
1636 | /* | 1669 | /* |
1637 | * acpi_boot_table_init() and acpi_boot_init() | 1670 | * acpi_boot_table_init() and acpi_boot_init() |
1638 | * called from setup_arch(), always. | 1671 | * called from setup_arch(), always. |
@@ -1660,9 +1693,7 @@ int __init acpi_boot_table_init(void) | |||
1660 | { | 1693 | { |
1661 | int error; | 1694 | int error; |
1662 | 1695 | ||
1663 | #ifdef __i386__ | ||
1664 | dmi_check_system(acpi_dmi_table); | 1696 | dmi_check_system(acpi_dmi_table); |
1665 | #endif | ||
1666 | 1697 | ||
1667 | /* | 1698 | /* |
1668 | * If acpi_disabled, bail out | 1699 | * If acpi_disabled, bail out |