Commit e2079c43 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Ingo Molnar

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: default avatarIngo Molnar <mingo@elte.hu>
parent c2e6d65b
...@@ -1373,8 +1373,6 @@ static void __init acpi_process_madt(void) ...@@ -1373,8 +1373,6 @@ static void __init acpi_process_madt(void)
return; return;
} }
#ifdef __i386__
static int __init disable_acpi_irq(const struct dmi_system_id *d) static int __init disable_acpi_irq(const struct dmi_system_id *d)
{ {
if (!acpi_force) { if (!acpi_force) {
...@@ -1435,6 +1433,17 @@ dmi_disable_irq0_through_ioapic(const struct dmi_system_id *d) ...@@ -1435,6 +1433,17 @@ dmi_disable_irq0_through_ioapic(const struct dmi_system_id *d)
return 0; return 0;
} }
/*
* Force ignoring BIOS IRQ0 pin2 override
*/
static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d)
{
pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n", d->ident);
acpi_skip_timer_override = 1;
force_mask_ioapic_irq_2();
return 0;
}
/* /*
* If your system is blacklisted here, but you find that acpi=force * If your system is blacklisted here, but you find that acpi=force
* works for you, please contact acpi-devel@sourceforge.net * works for you, please contact acpi-devel@sourceforge.net
...@@ -1628,11 +1637,35 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { ...@@ -1628,11 +1637,35 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
}, },
}, },
/*
* HP laptops which use a DSDT reporting as HP/SB400/10000,
* which includes some code which overrides all temperature
* trip points to 16C if the INTIN2 input of the I/O APIC
* is enabled. This input is incorrectly designated the
* ISA IRQ 0 via an interrupt source override even though
* it is wired to the output of the master 8259A and INTIN0
* is not connected at all. Force ignoring BIOS IRQ0 pin2
* override in that cases.
*/
{
.callback = dmi_ignore_irq0_timer_override,
.ident = "HP NX6125 laptop",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6125"),
},
},
{
.callback = dmi_ignore_irq0_timer_override,
.ident = "HP NX6325 laptop",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
},
},
{} {}
}; };
#endif /* __i386__ */
/* /*
* acpi_boot_table_init() and acpi_boot_init() * acpi_boot_table_init() and acpi_boot_init()
* called from setup_arch(), always. * called from setup_arch(), always.
...@@ -1660,9 +1693,7 @@ int __init acpi_boot_table_init(void) ...@@ -1660,9 +1693,7 @@ int __init acpi_boot_table_init(void)
{ {
int error; int error;
#ifdef __i386__
dmi_check_system(acpi_dmi_table); dmi_check_system(acpi_dmi_table);
#endif
/* /*
* If acpi_disabled, bail out * If acpi_disabled, bail out
......
...@@ -59,6 +59,13 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; ...@@ -59,6 +59,13 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
static DEFINE_SPINLOCK(ioapic_lock); static DEFINE_SPINLOCK(ioapic_lock);
static DEFINE_SPINLOCK(vector_lock); static DEFINE_SPINLOCK(vector_lock);
static bool mask_ioapic_irq_2 __initdata;
void __init force_mask_ioapic_irq_2(void)
{
mask_ioapic_irq_2 = true;
}
int timer_through_8259 __initdata; int timer_through_8259 __initdata;
/* /*
...@@ -2172,6 +2179,9 @@ static inline void __init check_timer(void) ...@@ -2172,6 +2179,9 @@ static inline void __init check_timer(void)
printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
vector, apic1, pin1, apic2, pin2); vector, apic1, pin1, apic2, pin2);
if (mask_ioapic_irq_2)
mask_IO_APIC_irq(2);
/* /*
* Some BIOS writers are clueless and report the ExtINTA * Some BIOS writers are clueless and report the ExtINTA
* I/O APIC input from the cascaded 8259A as the timer * I/O APIC input from the cascaded 8259A as the timer
......
...@@ -94,6 +94,13 @@ static int no_timer_check; ...@@ -94,6 +94,13 @@ static int no_timer_check;
static int disable_timer_pin_1 __initdata; static int disable_timer_pin_1 __initdata;
static bool mask_ioapic_irq_2 __initdata;
void __init force_mask_ioapic_irq_2(void)
{
mask_ioapic_irq_2 = true;
}
int timer_through_8259 __initdata; int timer_through_8259 __initdata;
/* Where if anywhere is the i8259 connect in external int mode */ /* Where if anywhere is the i8259 connect in external int mode */
...@@ -1698,6 +1705,9 @@ static inline void __init check_timer(void) ...@@ -1698,6 +1705,9 @@ static inline void __init check_timer(void)
apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
cfg->vector, apic1, pin1, apic2, pin2); cfg->vector, apic1, pin1, apic2, pin2);
if (mask_ioapic_irq_2)
mask_IO_APIC_irq(2);
/* /*
* Some BIOS writers are clueless and report the ExtINTA * Some BIOS writers are clueless and report the ExtINTA
* I/O APIC input from the cascaded 8259A as the timer * I/O APIC input from the cascaded 8259A as the timer
......
...@@ -119,5 +119,6 @@ enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; ...@@ -119,5 +119,6 @@ enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC};
#define is_uv_system() 0 #define is_uv_system() 0
#define uv_wakeup_secondary(a, b) 1 #define uv_wakeup_secondary(a, b) 1
extern void force_mask_ioapic_irq_2(void);
#endif #endif
...@@ -46,4 +46,6 @@ extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip); ...@@ -46,4 +46,6 @@ extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip);
extern void setup_apic_routing(void); extern void setup_apic_routing(void);
extern void force_mask_ioapic_irq_2(void);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment