SMP pre2-2.3.43 is pretty unstable due to the x86 SMP TLB flush changes.
This patch fixes these bugs and cleans up the TLB changes so that it fits
nicer into the existing x86/SMP framework.

Changes in smp-2.3.43-B5:

  - send IPIs only to CPUs which are affected. This ment that
    send_IPI_single() was replaced by send_IPI_mask() (no slowdown at all
    in smp_send_reschedule()), and that send_IPI_mask() from now on can
    send IPIs to an arbitrary group of CPUs. This change was enabled by
    the mm->cpu_vm_mask & recent TLB-changes and by the transition to
    logical APIC addressing mode. Quad and 8-way systems should see a
    noticeable cross-CPU TLB-flush cost reduction from this.

  - got rid of the cpu_online_mask check - with the above change it's
    unnecessery. (not online CPUs cannot have bits set in any
    mm->cpu_vm_mask.)

  - exported the check for cpu_mask into the global flush functions.
    !cpu_mask is actually the common case, no need to call
    flush_tlb_others() just to discover in 99% of the cases that we have
    to return immediately. (inlining flush_tlb_others() is not good
    either, it's a rather long function and is called from several
    functions.)

  - (small cleanups)

pre2-2.3.43 is now completely stable here.

-- mingo

Changes in smp-2.3.43-B1:

  - reverses parts of the pgtable.h flush_tlb optimization. It's just too
    complex to try to be too smart about flushing TLBs in an IRQ context.
    This bug causes frequent SMP crashes on vanilla 2.3.42 and
    pre2-2.3.43.

  - adds Linus' suggested 'fuzzy parsing' fix to
    IO_APIC_get_PCI_irq_vector() - this should fix some of the SMP + USB
    problems reported. It might also introduce problems on other systems
    so we'll see.

-- mingo
--- linux/include/asm-i386/pgtable.h.orig2      Tue Feb  8 02:30:13 2000
+++ linux/include/asm-i386/pgtable.h    Tue Feb  8 02:56:32 2000
@@ -29,12 +29,13 @@
 
 #define __flush_tlb()                                                  \
        do {                                                            \
-               __asm__ __volatile__                                    \
-                       ("movl %0, %%cr3;"                              \
-                               :                                       \
-                               : "r" __pa(current->active_mm->pgd)     \
-                               : "memory"                              \
-               );                                                      \
+               unsigned int tmpreg;                                    \
+                                                                       \
+               __asm__ __volatile__(                                   \
+                       "movl %%cr3, %0;  # flush TLB \n"               \
+                       "movl %0, %%cr3;              \n"               \
+                       : "=r" (tmpreg)                                 \
+                       :: "memory");                                   \
        } while (0)
 
 /*
@@ -43,14 +44,16 @@
  */
 #define __flush_tlb_global()                                           \
        do {                                                            \
+               unsigned int tmpreg;                                    \
+                                                                       \
                __asm__ __volatile__(                                   \
-                       "movl %0, %%cr4; # turn off PGE \n"             \
-                       "mov %2, %%cr3;  # flush TLB \n"                \
-                       "mov %1, %%cr4;  # turn PGE back on \n"         \
-                       :                                               \
-                       : "r" (mmu_cr4_features),                       \
-                         "r" (mmu_cr4_features & ~X86_CR4_PGE),        \
-                         "r" (__pa(current->active_mm->pgd))           \
+                       "movl %1, %%cr4;  # turn off PGE     \n"        \
+                       "movl %%cr3, %0;  # flush TLB        \n"        \
+                       "movl %0, %%cr3;                     \n"        \
+                       "movl %2, %%cr4;  # turn PGE back on \n"        \
+                       : "=r" (tmpreg)                                 \
+                       : "r" (mmu_cr4_features & ~X86_CR4_PGE),        \
+                         "r" (mmu_cr4_features)                        \
                        : "memory");                                    \
        } while (0)
 
--- linux/arch/i386/kernel/io_apic.c.orig2      Tue Feb  8 02:26:07 2000
+++ linux/arch/i386/kernel/io_apic.c    Tue Feb  8 02:31:26 2000
@@ -223,7 +223,7 @@
 static int __init pin_2_irq(int idx, int apic, int pin);
 int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pci_pin)
 {
-       int apic, i;
+       int apic, i, best_guess = -1;
 
        for (i = 0; i < mp_irq_entries; i++) {
                int lbus = mp_irqs[i].mpc_srcbus;
@@ -236,10 +236,18 @@
                    (mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
                    !mp_irqs[i].mpc_irqtype &&
                    (bus == mp_bus_id_to_pci_bus[mp_irqs[i].mpc_srcbus]) &&
-                   (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f)) &&
-                   (pci_pin == (mp_irqs[i].mpc_srcbusirq & 3)))
+                   (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) {
+                       int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq);
 
-                       return pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq);
+                       if (pci_pin == (mp_irqs[i].mpc_srcbusirq & 3))
+                               return irq;
+                       /*
+                        * Use the first all-but-pin matching entry as a
+                        * best-guess fuzzy result for broken mptables.
+                        */
+                       if (best_guess < 0)
+                               best_guess = irq;
+               }
        }
        return -1;
 }
--- linux/arch/i386/kernel/pci-pc.c.orig2       Tue Feb  8 02:25:45 2000
+++ linux/arch/i386/kernel/pci-pc.c     Tue Feb  8 02:29:55 2000
@@ -1132,6 +1132,10 @@
                        if (pin) {
                                pin--;          /* interrupt pins are numbered 
starting from 1 */
                                irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, 
PCI_SLOT(dev->devfn), pin);
+/*
+ * Will be removed completely if things work out well with fuzzy parsing
+ */
+#if 0
                                if (irq < 0 && dev->bus->parent) { /* go back to the 
bridge */
                                        struct pci_dev * bridge = dev->bus->self;
 
@@ -1142,6 +1146,7 @@
                                                printk(KERN_WARNING "PCI: using 
PPB(B%d,I%d,P%d) to get irq %d\n", 
                                                        bridge->bus->number, 
PCI_SLOT(bridge->devfn), pin, irq);
                                }
+#endif
                                if (irq >= 0) {
                                        printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) 
-> %d\n",
                                                dev->bus->number, 
PCI_SLOT(dev->devfn), pin, irq);

Reply via email to