- x86_64-ioapic-improve-the-heuristics-for-when-check_timer-fails.patch removed from -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     x86_64 ioapic: Improve the heuristics for when check_timer fails.
has been removed from the -mm tree.  Its filename was
     x86_64-ioapic-improve-the-heuristics-for-when-check_timer-fails.patch

This patch was dropped because it is obsolete

------------------------------------------------------
Subject: x86_64 ioapic: Improve the heuristics for when check_timer fails.
From: Eric W. Biederman <ebiederm@xxxxxxxxxxxx>

To a large extent this reverts b026872601976f666bae77b609dc490d1834bf77 while
still keeping to the spirits of it's goal, the ability to make smart guesses
about how the timer irq is routed when the BIOS gets it wrong.

The code for testing timer routing of a normal apic pin and and an ExtINT pin
has been moved into functions to make the code easier to read.

I have assumed that we don't want to enable anything with the i8259 unless we
are in ExtINT mode.  Reading the patch log indicates that this seems to be
most if not all of the time.

Compared to the pre b026872601976f666bae77b609dc490d1834bf77 state
two heuristic guess have been added:
-  If we cannot make the BIOS supplied timer on an apic pin work we
   guess apic 0 pin 2. As that is the architectural default.
-  When that fails and the BIOS does not provided us with an ExtINT
   mapping we try apic 0 pin 0 as an ExtINT.

Compared to Andi's previous version:
- I do not turn on irq0 in the i8259 and see if the io_apic
  works.  It is not clear that is ever needed.
- I do not guess that irq0 is connected as an ordinary interrupt
  to ioapic 0 pin 0.  I can't see how misprogramming that pin will buy
  us anything especially as it worked as an ExtINT in my testing, on
  one of the Nvidia boards.
- I guess that ExtINT mode and thus irq0 trough the i8259 works
  through apic 0 pin 0.  As this is the architectural default.

By using the architectural defaults our guesses are as safe as they can be and
are likely to work in most of the cases.  If this still leaves some people out
in the cold we can look at adding some more smart guesses, but my hunch is
that anything more needs to be chipset specific.

Yinghai Lu thanks for your contributions on the infrastructure support.  While
I did not use it directly I did look at your code when double checking mine to
see if looked correct.

Tobias.  I don't have a box with the problem yours does, and this doesn't
quite try any of the cases you have been asked to test so could you please
test this one?

I have tested this on an Nvidia board that reports that apic 0 pin 2 works
when it does not and this code successfully programs apic 0 pin 0 into ExtINT
mode.

I have not addressed the fact the code for local apic ExtINT guesses are a
mess and appear to be broken.  That code appears to have been that way for a
long time and no one has seemed to care.

Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx>
Cc: "Yinghai Lu" <yinghai.lu@xxxxxxx>
Cc: Andi Kleen <ak@xxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 arch/x86_64/kernel/io_apic.c |  164 ++++++++++++++++++++++++---------
 1 files changed, 123 insertions(+), 41 deletions(-)

diff -puN arch/x86_64/kernel/io_apic.c~x86_64-ioapic-improve-the-heuristics-for-when-check_timer-fails arch/x86_64/kernel/io_apic.c
--- a/arch/x86_64/kernel/io_apic.c~x86_64-ioapic-improve-the-heuristics-for-when-check_timer-fails
+++ a/arch/x86_64/kernel/io_apic.c
@@ -1631,23 +1631,16 @@ static inline void unlock_ExtINT_logic(v
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-/*
- * This code may look a bit paranoid, but it's supposed to cooperate with
- * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
- * is so screwy.  Thanks to Brian Perkins for testing/hacking this beast
- * fanatically on his truly buggy board.
- */
-
-static int try_apic_pin(int apic, int pin, char *msg)
+static int do_check_timer_pin(int apic, int pin)
 {
-	apic_printk(APIC_VERBOSE, KERN_INFO
-		    "..TIMER: trying IO-APIC=%d PIN=%d %s",
-		    apic, pin, msg);
-
+	apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER trying IO-APIC=%d PIN=%d",
+			apic, pin);
 	/*
 	 * Ok, does IRQ0 through the IOAPIC work?
 	 */
+	unmask_IO_APIC_irq(0);
 	if (!no_timer_check && timer_irq_works()) {
+		apic_printk(APIC_VERBOSE, " .. success\n");
 		if (nmi_watchdog == NMI_IO_APIC) {
 			disable_8259A_irq(0);
 			setup_nmi();
@@ -1656,11 +1649,87 @@ static int try_apic_pin(int apic, int pi
 		return 1;
 	}
 	clear_IO_APIC_pin(apic, pin);
-	apic_printk(APIC_QUIET, KERN_ERR " .. failed\n");
+	remove_pin_to_irq(0, apic, pin);
+	apic_printk(APIC_VERBOSE, KERN_ERR " .. failed\n");
+	return 0;
+}
+
+static int check_bios_timer_pin(int apic, int pin)
+{
+	/*
+	 * Test the BIOS supplied ioapic pin for the i8254
+	 */
+	if (pin == -1)
+		return 0;
+
+	return do_check_timer_pin(apic, pin);
+}
+
+static int check_timer_pin(int apic, int pin)
+{
+	int irq, idx;
+	/*
+	 * Test the architecture default i8254 timer pin
+	 * of apic 0 pin 2.
+	 */
+
+
+	/* If the apic pin pair is in use by another irq fail */
+	irq = irq_from_pin(apic, pin);
+	if ((irq != -1) && (irq != 0)) {
+		apic_printk(APIC_VERBOSE,KERN_INFO "...apic %d pin % in use by irq %d\n",
+			apic, pin, irq);
+		return 0;
+	}
+
+	/* Add an entry in mp_irqs for irq 0 */
+	idx = update_irq0_entry(apic, pin);
+
+	/* Add an entry in irq_to_pin */
+	add_pin_to_irq(0, apic, pin);
+
+	/* Now setup the irq */
+	setup_IO_APIC_irq(apic, pin, idx, 0);
+
+	/* And finally check to see if the irq works */
+	return do_check_timer_pin(apic, pin);
+}
+
+static int check_ExtINT_pin(int apic, int pin, int vector)
+{
+	if (pin == -1)
+		return 0;
+
+	apic_printk(APIC_VERBOSE,KERN_INFO "..ExtINT trying IO-APIC=%d PIN=%d",
+			apic, pin);
+	/*
+	 * legacy devices should be connected to IO APIC #0
+	 */
+	setup_ExtINT_IRQ0_pin(apic, pin, vector);
+	if (timer_irq_works()) {
+		apic_printk(APIC_VERBOSE, " .. success\n");
+		nmi_watchdog_default();
+		if (nmi_watchdog == NMI_IO_APIC) {
+			setup_nmi();
+		}
+		return 1;
+	}
+	/*
+	 * Cleanup, just in case ...
+	 */
+	clear_IO_APIC_pin(apic, pin);
+	apic_printk(APIC_VERBOSE, " .. failed\n");
 	return 0;
+
 }
 
-/* The function from hell */
+/*
+ * This code may look a bit paranoid, but it's supposed to cooperate with
+ * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
+ * is so screwy.  Thanks to Brian Perkins for testing/hacking this beast
+ * fanatically on his truly buggy board.
+ */
+
 static void check_timer(void)
 {
 	int apic1, pin1, apic2, pin2;
@@ -1688,37 +1757,50 @@ static void check_timer(void)
 	pin2  = ioapic_i8259.pin;
 	apic2 = ioapic_i8259.apic;
 
-	/* Do this first, otherwise we get double interrupts on ATI boards */
-	if ((pin1 != -1) && try_apic_pin(apic1, pin1,"with 8259 IRQ0 disabled"))
-		return;
+	apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
+		vector, apic1, pin1, apic2, pin2);
 
-	/* Now try again with IRQ0 8259A enabled.
-	   Assumes timer is on IO-APIC 0 ?!? */
-	enable_8259A_irq(0);
-	unmask_IO_APIC_irq(0);
-	if (try_apic_pin(apic1, pin1, "with 8259 IRQ0 enabled"))
-		return;
-	disable_8259A_irq(0);
 
-	/* Always try pin0 and pin2 on APIC 0 to handle buggy timer overrides
-	   on Nvidia boards */
-	if (!(apic1 == 0 && pin1 == 0) &&
-	    try_apic_pin(0, 0, "fallback with 8259 IRQ0 disabled"))
-		return;
-	if (!(apic1 == 0 && pin1 == 2) &&
-	    try_apic_pin(0, 2, "fallback with 8259 IRQ0 disabled"))
-		return;
+	/*
+	 * If the BIOS has supplied an ioapic pin for the 8254 try that.
+	 */
+	if (check_bios_timer_pin(apic1, pin1))
+ 		return;
 
-	/* Then try pure 8259A routing on the 8259 as reported by BIOS*/
-	enable_8259A_irq(0);
-	if (pin2 != -1) {
-		setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
-		if (try_apic_pin(apic2,pin2,"8259A broadcast ExtINT from BIOS"))
-			return;
-	}
+	/*
+	 * If the BIOS has not properly supplied the ioapic pin for the 8254
+	 * try the architectural default.  It is a common BIOS implementation
+	 * mistake to forget the ACPI source override for irq 0.
+	 */
+	if (check_timer_pin(0, 2))
+ 		return;
+
+	apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: 8254 timer not "
+				"connected to IO-APIC\n");
 
-	/* Tried all possibilities to go through the IO-APIC. Now come the
-	   really cheesy fallbacks. */
+	/*
+	 * Ok there are no more good canidates for an apic pin.
+	 * Start testing diffeernt ways of enable ExtINT.
+	 */
+	apic_printk(APIC_VERBOSE,KERN_INFO "...trying to set up timer (IRQ0) "
+				"through the 8259A ...\n");
+
+	/*
+	 * If the BIOS has supplied programming information for ExtINT
+	 * or we have derived by looking at the ioapics try that.
+	 */
+	if (check_ExtINT_pin(apic2, pin2, vector))
+ 		return;
+
+	/*
+	 * If the BIOS has not supplied the ExtINT pin to the i8259
+	 * or the BIOS supplied value does not work guess the
+	 * architectural default of apic 0 pin 0.
+	 */
+	if (check_ExtINT_pin(0, 0, vector))
+		return;
+
+	apic_printk(APIC_VERBOSE," failed.\n");
 
 	if (nmi_watchdog == NMI_IO_APIC) {
 		printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
_

Patches currently in -mm which might be from ebiederm@xxxxxxxxxxxx are

origin.patch
kthread-api-conversion-for-dvb_frontend-and-av7110.patch
genapic-optimize-fix-apic-mode-setup-2.patch
genapic-always-use-physical-delivery-mode-on-8-cpus.patch
genapic-remove-es7000-workaround.patch
genapic-remove-clustered-apic-mode.patch
genapic-default-to-physical-mode-on-hotplug-cpu-kernels.patch
i386-make-apic-probe-function-non-init.patch
modpost-add-more-symbols-to-whitelist-pattern2.patch
modpost-whitelist-reference-to-more-symbols-pattern-3.patch
x86_64-ioapic-improve-the-heuristics-for-when-check_timer-fails.patch
x86_64-ioapic-improve-the-heuristics-for-when-check_timer-fails-fix.patch
vt-refactor-console-sak-processing.patch
sysctl_ms_jiffies-fix-oldlen-semantics.patch
9p-use-kthread_stop-instead-of-sending-a-sigkill.patch
procfs-fix-race-between-proc_readdir-and-remove_proc_entry.patch
procfs-fix-race-between-proc_readdir-and-remove_proc_entry-fix.patch
kill_pid_info-kill-acquired_tasklist_lock.patch
clone-flag-clone_parent_tidptr-leaves-invalid-results-in-memory.patch
tty-make-__proc_set_tty-static.patch
tty-clarify-disassociate_ctty.patch
tty-fix-the-locking-for-signal-session-in-disassociate_ctty.patch
signal-use-kill_pgrp-not-kill_pg-in-the-sunos-compatibility-code.patch
signal-rewrite-kill_something_info-so-it-uses-newer-helpers.patch
pid-make-session_of_pgrp-use-struct-pid-instead-of-pid_t.patch
pid-use-struct-pid-for-talking-about-process-groups-in-exitc.patch
pid-replace-is_orphaned_pgrp-with-is_current_pgrp_orphaned.patch
tty-update-the-tty-layer-to-work-with-struct-pid.patch
pid-replace-do-while_each_task_pid-with-do-while_each_pid_task.patch
pid-remove-now-unused-do_each_task_pid-and-while_each_task_pid.patch
pid-remove-the-now-unused-kill_pg-kill_pg_info-and-__kill_pg_info.patch
i386-apic-clean-up-the-apic-code.patch
i386-apic-rework-and-fix-local-apic-calibration.patch
dynticks-i386-prepare-nmi-watchdog.patch
edac-e752x-bit-mask-fix.patch
edac-e752x-byte-access-fix.patch
edac-k8-driver-coding-tidy.patch
sched2-sched-domain-sysctl-use-ctl_unnumbered.patch
mm-implement-swap-prefetching-use-ctl_unnumbered.patch
nsproxy-externalizes-exit_task_namespaces.patch
user-namespace-add-the-framework.patch
user-namespace-add-the-framework-fix.patch
user-ns-add-user_namespace-ptr-to-vfsmount.patch
user-ns-hook-permission.patch
user-ns-prepare-copy_tree-copy_mnt-and-their-callers-to-handle-errs.patch
user-ns-prepare-copy_tree-copy_mnt-and-their-callers-to-handle-errs-fix.patch
user-ns-implement-shared-mounts.patch
user_ns-handle-file-sigio.patch
user-ns-implement-user-ns-unshare.patch
user-ns-implement-user-ns-unshare-tidy.patch
readahead-sysctl-parameters-use-ctl_unnumbered.patch
vdso-print-fatal-signals-use-ctl_unnumbered.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux