From 21efd48ef5a7884243f9acebbf05bc08d6f1a27c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Aug 2010 14:37:49 -0700 Subject: [PATCH] .34 patches --- queue-2.6.34/series | 1 + ...l-pending-irqs-when-crashed-on-kexec.patch | 140 ++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 queue-2.6.34/x86-apic-ack-all-pending-irqs-when-crashed-on-kexec.patch diff --git a/queue-2.6.34/series b/queue-2.6.34/series index 5c771bfdeae..304ba9acbfc 100644 --- a/queue-2.6.34/series +++ b/queue-2.6.34/series @@ -88,3 +88,4 @@ usb-xhci-remove-buggy-assignment-in-next_trb.patch usb-ftdi_sio-add-id-for-ionics-plugcomputer.patch usb-ftdi_sio-add-product-id-for-lenz-li-usb.patch tracing-fix-timer-tracing.patch +x86-apic-ack-all-pending-irqs-when-crashed-on-kexec.patch diff --git a/queue-2.6.34/x86-apic-ack-all-pending-irqs-when-crashed-on-kexec.patch b/queue-2.6.34/x86-apic-ack-all-pending-irqs-when-crashed-on-kexec.patch new file mode 100644 index 00000000000..f4dd31b1d76 --- /dev/null +++ b/queue-2.6.34/x86-apic-ack-all-pending-irqs-when-crashed-on-kexec.patch @@ -0,0 +1,140 @@ +From 8c3ba8d049247dc06b6dcee1711a11b26647aa44 Mon Sep 17 00:00:00 2001 +From: Kerstin Jonsson +Date: Mon, 24 May 2010 12:13:15 -0700 +Subject: x86, apic: ack all pending irqs when crashed/on kexec + +From: Kerstin Jonsson + +commit 8c3ba8d049247dc06b6dcee1711a11b26647aa44 upstream. + +When the SMP kernel decides to crash_kexec() the local APICs may have +pending interrupts in their vector tables. + +The setup routine for the local APIC has a deficient mechanism for +clearing these interrupts, it only handles interrupts that has already +been dispatched to the local core for servicing (the ISR register) safely, +it doesn't consider lower prioritized queued interrupts stored in the IRR +register. + +If you have more than one pending interrupt within the same 32 bit word in +the LAPIC vector table registers you may find yourself entering the IO +APIC setup with pending interrupts left in the LAPIC. This is a situation +for wich the IO APIC setup is not prepared. Depending of what/which +interrupt vector/vectors are stuck in the APIC tables your system may show +various degrees of malfunctioning. That was the reason why the +check_timer() failed in our system, the timer interrupts was blocked by +pending interrupts from the old kernel when routed trough the IO APIC. + +Additional comment from Jiri Bohac: +============== +If this should go into stable release, +I'd add some kind of limit on the number of iterations, just to be safe from +hard to debug lock-ups: + ++if (loops++ > MAX_LOOPS) { ++ printk("LAPIC pending clean-up") ++ break; ++} + while (queued); + +with MAX_LOOPS something like 1E9 this would leave plenty of time for the +pending IRQs to be cleared and would and still cause at most a second of delay +if the loop were to lock-up for whatever reason. + +[trenn@suse.de: + +V2: Use tsc if avail to bail out after 1 sec due to possible virtual + apic_read calls which may take rather long (suggested by: Avi Kivity + ) If no tsc is available bail out quickly after + cpu_khz, if we broke out too early and still have irqs pending (which + should never happen?) we still get a WARN_ON... + +V3: - Fixed indentation -> checkpatch clean + - max_loops must be signed + +V4: - Fix typo, mixed up tsc and ntsc in first rdtscll() call + +V5: Adjust WARN_ON() condition to also catch error in cpu_has_tsc case] + +Cc: +Cc: Yinghai Lu +Cc: Kerstin Jonsson +Cc: Avi Kivity +Cc: Suresh Siddha +Tested-by: Eric W. Biederman +Signed-off-by: Thomas Renninger +LKML-Reference: <201005241913.o4OJDGWM010865@imap1.linux-foundation.org> +Signed-off-by: Andrew Morton +Signed-off-by: H. Peter Anvin +Cc: Thomas Renninger +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/apic/apic.c | 41 +++++++++++++++++++++++++++++++++-------- + 1 file changed, 33 insertions(+), 8 deletions(-) + +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include + + unsigned int num_processors; + +@@ -1151,8 +1152,13 @@ static void __cpuinit lapic_setup_esr(vo + */ + void __cpuinit setup_local_APIC(void) + { +- unsigned int value; +- int i, j; ++ unsigned int value, queued; ++ int i, j, acked = 0; ++ unsigned long long tsc = 0, ntsc; ++ long long max_loops = cpu_khz; ++ ++ if (cpu_has_tsc) ++ rdtscll(tsc); + + if (disable_apic) { + arch_disable_smp_support(); +@@ -1204,13 +1210,32 @@ void __cpuinit setup_local_APIC(void) + * the interrupt. Hence a vector might get locked. It was noticed + * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. + */ +- for (i = APIC_ISR_NR - 1; i >= 0; i--) { +- value = apic_read(APIC_ISR + i*0x10); +- for (j = 31; j >= 0; j--) { +- if (value & (1<= 0; i--) ++ queued |= apic_read(APIC_IRR + i*0x10); ++ ++ for (i = APIC_ISR_NR - 1; i >= 0; i--) { ++ value = apic_read(APIC_ISR + i*0x10); ++ for (j = 31; j >= 0; j--) { ++ if (value & (1< 256) { ++ printk(KERN_ERR "LAPIC pending interrupts after %d EOI\n", ++ acked); ++ break; ++ } ++ if (cpu_has_tsc) { ++ rdtscll(ntsc); ++ max_loops = (cpu_khz << 10) - (ntsc - tsc); ++ } else ++ max_loops--; ++ } while (queued && max_loops > 0); ++ WARN_ON(max_loops <= 0); + + /* + * Now that we are all set up, enable the APIC -- 2.47.3