linux/arch/x86/kernel/apic
Kerstin Jonsson 8c3ba8d049 x86, apic: ack all pending irqs when crashed/on kexec
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
    <avi@redhat.com>) 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: <jbohac@novell.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Kerstin Jonsson <kerstin.jonsson@ericsson.com>
Cc: Avi Kivity <avi@redhat.com>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Tested-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Thomas Renninger <trenn@suse.de>
LKML-Reference: <201005241913.o4OJDGWM010865@imap1.linux-foundation.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
2010-05-24 13:31:35 -07:00
..
apic_flat_64.c arch/x86/kernel/apic/apic_flat_64.c: Make comment match the code 2010-02-04 11:55:47 +01:00
apic_noop.c x86: Fix bogus warning in apic_noop.apic_write() 2009-12-07 13:16:37 +01:00
apic.c x86, apic: ack all pending irqs when crashed/on kexec 2010-05-24 13:31:35 -07:00
bigsmp_32.c x86, irq: Allow 0xff for /proc/irq/[n]/smp_affinity on an 8-cpu system 2009-12-17 22:03:06 -08:00
es7000_32.c x86, irq: Kill io_apic_renumber_irq 2010-05-04 13:35:20 -07:00
io_apic.c Merge branch 'x86-irq-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2010-05-18 09:15:57 -07:00
ipi.c Merge commit 'v2.6.31-rc7' into x86/cleanups 2009-08-24 12:25:54 +02:00
Makefile x86, apic: Introduce the NOOP apic driver 2009-10-14 09:17:00 +02:00
nmi.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
numaq_32.c Merge branch 'x86-mrst-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2010-03-07 15:59:39 -08:00
probe_32.c x86, apic: Don't use logical-flat mode when CPU hotplug may exceed 8 CPUs 2010-02-09 20:51:11 -08:00
probe_64.c x86, apic: Don't use logical-flat mode when CPU hotplug may exceed 8 CPUs 2010-02-09 20:51:11 -08:00
summit_32.c x86: apic: Do not use stacked physid_mask_t 2009-11-10 05:52:07 +01:00
x2apic_cluster.c x86, irq: Allow 0xff for /proc/irq/[n]/smp_affinity on an 8-cpu system 2009-12-17 22:03:06 -08:00
x2apic_phys.c x86, irq: Allow 0xff for /proc/irq/[n]/smp_affinity on an 8-cpu system 2009-12-17 22:03:06 -08:00
x2apic_uv_x.c Merge branch 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2010-05-18 09:46:35 -07:00