Merge branch 'generic-ipi' into generic-ipi-for-linus
authorIngo Molnar <mingo@elte.hu>
Tue, 15 Jul 2008 19:55:59 +0000 (21:55 +0200)
committerIngo Molnar <mingo@elte.hu>
Tue, 15 Jul 2008 19:55:59 +0000 (21:55 +0200)
Conflicts:

arch/powerpc/Kconfig
arch/s390/kernel/time.c
arch/x86/kernel/apic_32.c
arch/x86/kernel/cpu/perfctr-watchdog.c
arch/x86/kernel/i8259_64.c
arch/x86/kernel/ldt.c
arch/x86/kernel/nmi_64.c
arch/x86/kernel/smpboot.c
arch/x86/xen/smp.c
include/asm-x86/hw_irq_32.h
include/asm-x86/hw_irq_64.h
include/asm-x86/mach-default/irq_vectors.h
include/asm-x86/mach-voyager/irq_vectors.h
include/asm-x86/smp.h
kernel/Makefile

Signed-off-by: Ingo Molnar <mingo@elte.hu>
40 files changed:
1  2 
arch/arm/Kconfig
arch/mips/Kconfig
arch/powerpc/Kconfig
arch/s390/appldata/appldata_base.c
arch/s390/kernel/time.c
arch/x86/Kconfig
arch/x86/kernel/apic_32.c
arch/x86/kernel/cpu/mcheck/mce_64.c
arch/x86/kernel/cpu/mtrr/main.c
arch/x86/kernel/cpu/perfctr-watchdog.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/entry_64.S
arch/x86/kernel/io_apic_32.c
arch/x86/kernel/io_apic_64.c
arch/x86/kernel/irqinit_64.c
arch/x86/kernel/ldt.c
arch/x86/kernel/nmi.c
arch/x86/kernel/process.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/tlb_64.c
arch/x86/kernel/vsyscall_64.c
arch/x86/mach-voyager/voyager_smp.c
arch/x86/mm/pageattr.c
arch/x86/oprofile/nmi_int.c
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
arch/x86/xen/smp.c
arch/x86/xen/xen-ops.h
fs/buffer.c
include/asm-x86/hw_irq.h
include/asm-x86/irq_vectors.h
include/asm-x86/smp.h
kernel/Makefile
kernel/hrtimer.c
kernel/softirq.c
kernel/time/tick-broadcast.c
mm/page_alloc.c
mm/slab.c
mm/slub.c
net/iucv/iucv.c

Simple merge
Simple merge
@@@ -111,7 -109,8 +111,8 @@@ config PP
        select HAVE_KPROBES
        select HAVE_KRETPROBES
        select HAVE_LMB
+       select USE_GENERIC_SMP_HELPERS if SMP
 +      select HAVE_OPROFILE
  
  config EARLY_PRINTK
        bool
@@@ -203,9 -209,10 +203,9 @@@ __appldata_vtimer_setup(int cmd
                        per_cpu(appldata_timer, i).expires = per_cpu_interval;
                        smp_call_function_single(i, add_virt_timer_periodic,
                                                 &per_cpu(appldata_timer, i),
-                                                0, 1);
+                                                1);
                }
                appldata_timer_active = 1;
 -              P_INFO("Monitoring timer started.\n");
                break;
        case APPLDATA_DEL_TIMER:
                for_each_online_cpu(i)
@@@ -707,9 -690,9 +707,9 @@@ static int etr_sync_clock(struct etr_ai
         */
        memset(&etr_sync, 0, sizeof(etr_sync));
        preempt_disable();
-       smp_call_function(clock_sync_cpu_start, &etr_sync, 0, 0);
 -      smp_call_function(etr_sync_cpu_start, NULL, 0);
++      smp_call_function(clock_sync_cpu_start, &etr_sync, 0);
        local_irq_disable();
 -      etr_enable_sync_clock();
 +      enable_sync_clock();
  
        /* Set clock to next OTE. */
        __ctl_set_bit(14, 21);
                rc = -EAGAIN;
        }
        local_irq_enable();
-       smp_call_function(clock_sync_cpu_end, NULL, 0, 0);
 -      smp_call_function(etr_sync_cpu_end,NULL,0);
++      smp_call_function(clock_sync_cpu_end, NULL, 0);
        preempt_enable();
        return rc;
  }
@@@ -926,10 -909,10 +926,10 @@@ static void etr_work_fn(struct work_str
        if (!eacr.ea) {
                /* Both ports offline. Reset everything. */
                eacr.dp = eacr.es = eacr.sl = 0;
-               on_each_cpu(disable_sync_clock, NULL, 0, 1);
 -              on_each_cpu(etr_disable_sync_clock, NULL, 1);
++              on_each_cpu(disable_sync_clock, NULL, 1);
                del_timer_sync(&etr_timer);
                etr_update_eacr(eacr);
 -              set_bit(ETR_FLAG_EACCES, &etr_flags);
 +              clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
                return;
        }
  
Simple merge
@@@ -1333,13 -1351,17 +1333,17 @@@ void __init smp_intr_init(void
         * The reschedule interrupt is a CPU-to-CPU reschedule-helper
         * IPI, driven by wakeup.
         */
 -      set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
 +      alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
  
        /* IPI for invalidation */
 -      set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
 +      alloc_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
  
        /* IPI for generic function call */
 -      set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
 +      alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
+       /* IPI for single call function */
+       set_intr_gate(CALL_FUNCTION_SINGLE_VECTOR,
+                               call_function_single_interrupt);
  }
  #endif
  
Simple merge
Simple merge
@@@ -189,10 -180,8 +189,10 @@@ void disable_lapic_nmi_watchdog(void
        if (atomic_read(&nmi_active) <= 0)
                return;
  
-       on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1);
+       on_each_cpu(stop_apic_nmi_watchdog, NULL, 1);
 -      wd_ops->unreserve();
 +
 +      if (wd_ops)
 +              wd_ops->unreserve();
  
        BUG_ON(atomic_read(&nmi_active) != 0);
  }
Simple merge
Simple merge
@@@ -1567,9 -1563,9 +1567,9 @@@ void /*__init*/ print_local_APIC(void *
        printk("\n");
  }
  
 -void print_all_local_APICs (void)
 +void print_all_local_APICs(void)
  {
-       on_each_cpu(print_local_APIC, NULL, 1, 1);
+       on_each_cpu(print_local_APIC, NULL, 1);
  }
  
  void /*__init*/ print_PIC(void)
Simple merge
index 31f49e8,0000000..0373e88
mode 100644,000000..100644
--- /dev/null
@@@ -1,217 -1,0 +1,221 @@@
 +#include <linux/linkage.h>
 +#include <linux/errno.h>
 +#include <linux/signal.h>
 +#include <linux/sched.h>
 +#include <linux/ioport.h>
 +#include <linux/interrupt.h>
 +#include <linux/timex.h>
 +#include <linux/slab.h>
 +#include <linux/random.h>
 +#include <linux/init.h>
 +#include <linux/kernel_stat.h>
 +#include <linux/sysdev.h>
 +#include <linux/bitops.h>
 +
 +#include <asm/acpi.h>
 +#include <asm/atomic.h>
 +#include <asm/system.h>
 +#include <asm/io.h>
 +#include <asm/hw_irq.h>
 +#include <asm/pgtable.h>
 +#include <asm/delay.h>
 +#include <asm/desc.h>
 +#include <asm/apic.h>
 +#include <asm/i8259.h>
 +
 +/*
 + * Common place to define all x86 IRQ vectors
 + *
 + * This builds up the IRQ handler stubs using some ugly macros in irq.h
 + *
 + * These macros create the low-level assembly IRQ routines that save
 + * register context and call do_IRQ(). do_IRQ() then does all the
 + * operations that are needed to keep the AT (or SMP IOAPIC)
 + * interrupt-controller happy.
 + */
 +
 +#define IRQ_NAME2(nr) nr##_interrupt(void)
 +#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
 +
 +/*
 + *    SMP has a few special interrupts for IPI messages
 + */
 +
 +#define BUILD_IRQ(nr)                         \
 +      asmlinkage void IRQ_NAME(nr);           \
 +      asm("\n.p2align\n"                      \
 +          "IRQ" #nr "_interrupt:\n\t"         \
 +          "push $~(" #nr ") ; "               \
 +          "jmp common_interrupt");
 +
 +#define BI(x,y) \
 +      BUILD_IRQ(x##y)
 +
 +#define BUILD_16_IRQS(x) \
 +      BI(x,0) BI(x,1) BI(x,2) BI(x,3) \
 +      BI(x,4) BI(x,5) BI(x,6) BI(x,7) \
 +      BI(x,8) BI(x,9) BI(x,a) BI(x,b) \
 +      BI(x,c) BI(x,d) BI(x,e) BI(x,f)
 +
 +/*
 + * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
 + * (these are usually mapped to vectors 0x30-0x3f)
 + */
 +
 +/*
 + * The IO-APIC gives us many more interrupt sources. Most of these
 + * are unused but an SMP system is supposed to have enough memory ...
 + * sometimes (mostly wrt. hw bugs) we get corrupted vectors all
 + * across the spectrum, so we really want to be prepared to get all
 + * of these. Plus, more powerful systems might have more than 64
 + * IO-APIC registers.
 + *
 + * (these are usually mapped into the 0x30-0xff vector range)
 + */
 +                                    BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3)
 +BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7)
 +BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb)
 +BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) BUILD_16_IRQS(0xe) BUILD_16_IRQS(0xf)
 +
 +#undef BUILD_16_IRQS
 +#undef BI
 +
 +
 +#define IRQ(x,y) \
 +      IRQ##x##y##_interrupt
 +
 +#define IRQLIST_16(x) \
 +      IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \
 +      IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \
 +      IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \
 +      IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f)
 +
 +/* for the irq vectors */
 +static void (*__initdata interrupt[NR_VECTORS - FIRST_EXTERNAL_VECTOR])(void) = {
 +                                        IRQLIST_16(0x2), IRQLIST_16(0x3),
 +      IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
 +      IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
 +      IRQLIST_16(0xc), IRQLIST_16(0xd), IRQLIST_16(0xe), IRQLIST_16(0xf)
 +};
 +
 +#undef IRQ
 +#undef IRQLIST_16
 +
 +
 +
 +
 +/*
 + * IRQ2 is cascade interrupt to second interrupt controller
 + */
 +
 +static struct irqaction irq2 = {
 +      .handler = no_action,
 +      .mask = CPU_MASK_NONE,
 +      .name = "cascade",
 +};
 +DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
 +      [0 ... IRQ0_VECTOR - 1] = -1,
 +      [IRQ0_VECTOR] = 0,
 +      [IRQ1_VECTOR] = 1,
 +      [IRQ2_VECTOR] = 2,
 +      [IRQ3_VECTOR] = 3,
 +      [IRQ4_VECTOR] = 4,
 +      [IRQ5_VECTOR] = 5,
 +      [IRQ6_VECTOR] = 6,
 +      [IRQ7_VECTOR] = 7,
 +      [IRQ8_VECTOR] = 8,
 +      [IRQ9_VECTOR] = 9,
 +      [IRQ10_VECTOR] = 10,
 +      [IRQ11_VECTOR] = 11,
 +      [IRQ12_VECTOR] = 12,
 +      [IRQ13_VECTOR] = 13,
 +      [IRQ14_VECTOR] = 14,
 +      [IRQ15_VECTOR] = 15,
 +      [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
 +};
 +
 +static void __init init_ISA_irqs (void)
 +{
 +      int i;
 +
 +      init_bsp_APIC();
 +      init_8259A(0);
 +
 +      for (i = 0; i < NR_IRQS; i++) {
 +              irq_desc[i].status = IRQ_DISABLED;
 +              irq_desc[i].action = NULL;
 +              irq_desc[i].depth = 1;
 +
 +              if (i < 16) {
 +                      /*
 +                       * 16 old-style INTA-cycle interrupts:
 +                       */
 +                      set_irq_chip_and_handler_name(i, &i8259A_chip,
 +                                                    handle_level_irq, "XT");
 +              } else {
 +                      /*
 +                       * 'high' PCI IRQs filled in on demand
 +                       */
 +                      irq_desc[i].chip = &no_irq_chip;
 +              }
 +      }
 +}
 +
 +void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
 +
 +void __init native_init_IRQ(void)
 +{
 +      int i;
 +
 +      init_ISA_irqs();
 +      /*
 +       * Cover the whole vector space, no vector can escape
 +       * us. (some of these will be overridden and become
 +       * 'special' SMP interrupts)
 +       */
 +      for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
 +              int vector = FIRST_EXTERNAL_VECTOR + i;
 +              if (vector != IA32_SYSCALL_VECTOR)
 +                      set_intr_gate(vector, interrupt[i]);
 +      }
 +
 +#ifdef CONFIG_SMP
 +      /*
 +       * The reschedule interrupt is a CPU-to-CPU reschedule-helper
 +       * IPI, driven by wakeup.
 +       */
 +      alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
 +
 +      /* IPIs for invalidation */
 +      alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0);
 +      alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1);
 +      alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2);
 +      alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3);
 +      alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4);
 +      alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5);
 +      alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6);
 +      alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7);
 +
 +      /* IPI for generic function call */
 +      alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
 +
++      /* IPI for generic single function call */
++      alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR,
++                      call_function_single_interrupt);
++
 +      /* Low priority IPI to cleanup after moving an irq */
 +      set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
 +#endif
 +      alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
 +      alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
 +
 +      /* self generated IPI for local APIC timer */
 +      alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
 +
 +      /* IPI vectors for APIC spurious and error interrupts */
 +      alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
 +      alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
 +
 +      if (!acpi_ioapic)
 +              setup_irq(2, &irq2);
 +}
@@@ -68,7 -68,7 +68,7 @@@ static int alloc_ldt(mm_context_t *pc, 
                load_LDT(pc);
                mask = cpumask_of_cpu(smp_processor_id());
                if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-                       smp_call_function(flush_ldt, current->mm, 1, 1);
 -                      smp_call_function(flush_ldt, NULL, 1);
++                      smp_call_function(flush_ldt, current->mm, 1);
                preempt_enable();
  #else
                load_LDT(pc);
Simple merge
Simple merge
@@@ -327,12 -345,19 +327,12 @@@ static void __cpuinit start_secondary(v
         * lock helps us to not include this cpu in a currently in progress
         * smp_call_function().
         */
-       lock_ipi_call_lock();
+       ipi_call_lock_irq();
 -#ifdef CONFIG_X86_64
 -      spin_lock(&vector_lock);
 -
 -      /* Setup the per cpu irq handling data structures */
 -      __setup_vector_irq(smp_processor_id());
 -      /*
 -       * Allow the master to continue.
 -       */
 -      spin_unlock(&vector_lock);
 +#ifdef CONFIG_X86_IO_APIC
 +      setup_vector_irq(smp_processor_id());
  #endif
        cpu_set(smp_processor_id(), cpu_online_map);
-       unlock_ipi_call_lock();
+       ipi_call_unlock_irq();
        per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
  
        setup_secondary_clock();
Simple merge
Simple merge
@@@ -1129,9 -1072,18 +1067,9 @@@ static void do_flush_tlb_all(void *info
  /* flush the TLB of every active CPU in the system */
  void flush_tlb_all(void)
  {
-       on_each_cpu(do_flush_tlb_all, 0, 1, 1);
+       on_each_cpu(do_flush_tlb_all, 0, 1);
  }
  
 -/* used to set up the trampoline for other CPUs when the memory manager
 - * is sorted out */
 -void __init smp_alloc_memory(void)
 -{
 -      trampoline_base = alloc_bootmem_low_pages(PAGE_SIZE);
 -      if (__pa(trampoline_base) >= 0x93000)
 -              BUG();
 -}
 -
  /* send a reschedule CPI to one CPU by physical CPU number*/
  static void voyager_smp_send_reschedule(int cpu)
  {
Simple merge
@@@ -269,9 -269,9 +269,9 @@@ static void nmi_cpu_shutdown(void *dumm
  
  static void nmi_shutdown(void)
  {
 -      struct op_msrs *msrs = &__get_cpu_var(cpu_msrs);
 +      struct op_msrs *msrs = &get_cpu_var(cpu_msrs);
        nmi_enabled = 0;
-       on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
+       on_each_cpu(nmi_cpu_shutdown, NULL, 1);
        unregister_die_notifier(&profile_exceptions_nb);
        model->shutdown(msrs);
        free_msrs();
Simple merge
Simple merge
  #include "xen-ops.h"
  #include "mmu.h"
  
 -static cpumask_t xen_cpu_initialized_map;
 +cpumask_t xen_cpu_initialized_map;
- static DEFINE_PER_CPU(int, resched_irq) = -1;
- static DEFINE_PER_CPU(int, callfunc_irq) = -1;
- static DEFINE_PER_CPU(int, debug_irq) = -1;
- /*
-  * Structure and data for smp_call_function(). This is designed to minimise
-  * static memory requirements. It also looks cleaner.
-  */
- static DEFINE_SPINLOCK(call_lock);
  
- struct call_data_struct {
-       void (*func) (void *info);
-       void *info;
-       atomic_t started;
-       atomic_t finished;
-       int wait;
- };
+ static DEFINE_PER_CPU(int, resched_irq);
+ static DEFINE_PER_CPU(int, callfunc_irq);
+ static DEFINE_PER_CPU(int, callfuncsingle_irq);
+ static DEFINE_PER_CPU(int, debug_irq) = -1;
  
  static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id);
- static struct call_data_struct *call_data;
+ static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id);
  
  /*
   * Reschedule call back. Nothing to do,
@@@ -55,16 -46,9 +55,11 @@@ void xen_smp_cpus_done(unsigned int max
  
  void xen_smp_send_stop(void);
  void xen_smp_send_reschedule(int cpu);
- int xen_smp_call_function (void (*func) (void *info), void *info, int nonatomic,
-                          int wait);
- int xen_smp_call_function_single(int cpu, void (*func) (void *info), void *info,
-                                int nonatomic, int wait);
- int xen_smp_call_function_mask(cpumask_t mask, void (*func)(void *),
-                              void *info, int wait);
+ void xen_smp_send_call_function_ipi(cpumask_t mask);
+ void xen_smp_send_call_function_single_ipi(int cpu);
  
 +extern cpumask_t xen_cpu_initialized_map;
 +
  
  /* Declare an asm function, along with symbols needed to make it
     inlineable */
diff --cc fs/buffer.c
Simple merge
 +#ifndef _ASM_HW_IRQ_H
 +#define _ASM_HW_IRQ_H
 +
 +/*
 + * (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
 + *
 + * moved some of the old arch/i386/kernel/irq.h to here. VY
 + *
 + * IRQ/IPI changes taken from work by Thomas Radke
 + * <tomsoft@informatik.tu-chemnitz.de>
 + *
 + * hacked by Andi Kleen for x86-64.
 + * unified by tglx
 + */
 +
 +#include <asm/irq_vectors.h>
 +
 +#ifndef __ASSEMBLY__
 +
 +#include <linux/percpu.h>
 +#include <linux/profile.h>
 +#include <linux/smp.h>
 +
 +#include <asm/atomic.h>
 +#include <asm/irq.h>
 +#include <asm/sections.h>
 +
 +#define platform_legacy_irq(irq)      ((irq) < 16)
 +
 +/* Interrupt handlers registered during init_IRQ */
 +extern void apic_timer_interrupt(void);
 +extern void error_interrupt(void);
 +extern void spurious_interrupt(void);
 +extern void thermal_interrupt(void);
 +extern void reschedule_interrupt(void);
 +
 +extern void invalidate_interrupt(void);
 +extern void invalidate_interrupt0(void);
 +extern void invalidate_interrupt1(void);
 +extern void invalidate_interrupt2(void);
 +extern void invalidate_interrupt3(void);
 +extern void invalidate_interrupt4(void);
 +extern void invalidate_interrupt5(void);
 +extern void invalidate_interrupt6(void);
 +extern void invalidate_interrupt7(void);
 +
 +extern void irq_move_cleanup_interrupt(void);
 +extern void threshold_interrupt(void);
 +
 +extern void call_function_interrupt(void);
++extern void call_function_single_interrupt(void);
 +
 +/* PIC specific functions */
 +extern void disable_8259A_irq(unsigned int irq);
 +extern void enable_8259A_irq(unsigned int irq);
 +extern int i8259A_irq_pending(unsigned int irq);
 +extern void make_8259A_irq(unsigned int irq);
 +extern void init_8259A(int aeoi);
 +
 +/* IOAPIC */
 +#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
 +extern unsigned long io_apic_irqs;
 +
 +extern void init_VISWS_APIC_irqs(void);
 +extern void setup_IO_APIC(void);
 +extern void disable_IO_APIC(void);
 +extern void print_IO_APIC(void);
 +extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
 +extern void setup_ioapic_dest(void);
 +
 +#ifdef CONFIG_X86_64
 +extern void enable_IO_APIC(void);
 +#endif
 +
 +/* IPI functions */
 +extern void send_IPI_self(int vector);
 +extern void send_IPI(int dest, int vector);
 +
 +/* Statistics */
 +extern atomic_t irq_err_count;
 +extern atomic_t irq_mis_count;
 +
 +/* EISA */
 +extern void eisa_set_level_irq(unsigned int irq);
 +
 +/* Voyager functions */
 +extern asmlinkage void vic_cpi_interrupt(void);
 +extern asmlinkage void vic_sys_interrupt(void);
 +extern asmlinkage void vic_cmn_interrupt(void);
 +extern asmlinkage void qic_timer_interrupt(void);
 +extern asmlinkage void qic_invalidate_interrupt(void);
 +extern asmlinkage void qic_reschedule_interrupt(void);
 +extern asmlinkage void qic_enable_irq_interrupt(void);
 +extern asmlinkage void qic_call_function_interrupt(void);
 +
  #ifdef CONFIG_X86_32
 -# include "hw_irq_32.h"
 +extern void (*const interrupt[NR_IRQS])(void);
  #else
 -# include "hw_irq_64.h"
 +typedef int vector_irq_t[NR_VECTORS];
 +DECLARE_PER_CPU(vector_irq_t, vector_irq);
 +extern spinlock_t vector_lock;
 +#endif
 +extern void setup_vector_irq(int cpu);
 +
 +#endif /* !ASSEMBLY_ */
 +
  #endif
index 0ac864e,0000000..90b1d1f
mode 100644,000000..100644
--- /dev/null
@@@ -1,169 -1,0 +1,173 @@@
- #define VIC_END_FAKE_CPI              VIC_CALL_FUNCTION_CPI
 +#ifndef _ASM_IRQ_VECTORS_H
 +#define _ASM_IRQ_VECTORS_H
 +
 +#include <linux/threads.h>
 +
 +#define NMI_VECTOR            0x02
 +
 +/*
 + * IDT vectors usable for external interrupt sources start
 + * at 0x20:
 + */
 +#define FIRST_EXTERNAL_VECTOR 0x20
 +
 +#ifdef CONFIG_X86_32
 +# define SYSCALL_VECTOR               0x80
 +#else
 +# define IA32_SYSCALL_VECTOR  0x80
 +#endif
 +
 +/*
 + * Reserve the lowest usable priority level 0x20 - 0x2f for triggering
 + * cleanup after irq migration on 64 bit.
 + */
 +#define IRQ_MOVE_CLEANUP_VECTOR       FIRST_EXTERNAL_VECTOR
 +
 +/*
 + * Vectors 0x20-0x2f are used for ISA interrupts on 32 bit.
 + * Vectors 0x30-0x3f are used for ISA interrupts on 64 bit.
 + */
 +#ifdef CONFIG_X86_32
 +#define IRQ0_VECTOR           (FIRST_EXTERNAL_VECTOR)
 +#else
 +#define IRQ0_VECTOR           (FIRST_EXTERNAL_VECTOR + 0x10)
 +#endif
 +#define IRQ1_VECTOR           (IRQ0_VECTOR + 1)
 +#define IRQ2_VECTOR           (IRQ0_VECTOR + 2)
 +#define IRQ3_VECTOR           (IRQ0_VECTOR + 3)
 +#define IRQ4_VECTOR           (IRQ0_VECTOR + 4)
 +#define IRQ5_VECTOR           (IRQ0_VECTOR + 5)
 +#define IRQ6_VECTOR           (IRQ0_VECTOR + 6)
 +#define IRQ7_VECTOR           (IRQ0_VECTOR + 7)
 +#define IRQ8_VECTOR           (IRQ0_VECTOR + 8)
 +#define IRQ9_VECTOR           (IRQ0_VECTOR + 9)
 +#define IRQ10_VECTOR          (IRQ0_VECTOR + 10)
 +#define IRQ11_VECTOR          (IRQ0_VECTOR + 11)
 +#define IRQ12_VECTOR          (IRQ0_VECTOR + 12)
 +#define IRQ13_VECTOR          (IRQ0_VECTOR + 13)
 +#define IRQ14_VECTOR          (IRQ0_VECTOR + 14)
 +#define IRQ15_VECTOR          (IRQ0_VECTOR + 15)
 +
 +/*
 + * Special IRQ vectors used by the SMP architecture, 0xf0-0xff
 + *
 + *  some of the following vectors are 'rare', they are merged
 + *  into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
 + *  TLB, reschedule and local APIC vectors are performance-critical.
 + *
 + *  Vectors 0xf0-0xfa are free (reserved for future Linux use).
 + */
 +#ifdef CONFIG_X86_32
 +
 +# define SPURIOUS_APIC_VECTOR         0xff
 +# define ERROR_APIC_VECTOR            0xfe
 +# define INVALIDATE_TLB_VECTOR                0xfd
 +# define RESCHEDULE_VECTOR            0xfc
 +# define CALL_FUNCTION_VECTOR         0xfb
++# define CALL_FUNCTION_SINGLE_VECTOR  0xfa
 +# define THERMAL_APIC_VECTOR          0xf0
 +
 +#else
 +
 +#define SPURIOUS_APIC_VECTOR          0xff
 +#define ERROR_APIC_VECTOR             0xfe
 +#define RESCHEDULE_VECTOR             0xfd
 +#define CALL_FUNCTION_VECTOR          0xfc
++#define CALL_FUNCTION_SINGLE_VECTOR   0xfb
 +#define THERMAL_APIC_VECTOR           0xfa
 +#define THRESHOLD_APIC_VECTOR         0xf9
 +#define INVALIDATE_TLB_VECTOR_END     0xf7
 +#define INVALIDATE_TLB_VECTOR_START   0xf0    /* f0-f7 used for TLB flush */
 +
 +#define NUM_INVALIDATE_TLB_VECTORS    8
 +
 +#endif
 +
 +/*
 + * Local APIC timer IRQ vector is on a different priority level,
 + * to work around the 'lost local interrupt if more than 2 IRQ
 + * sources per level' errata.
 + */
 +#define LOCAL_TIMER_VECTOR    0xef
 +
 +/*
 + * First APIC vector available to drivers: (vectors 0x30-0xee) we
 + * start at 0x31(0x41) to spread out vectors evenly between priority
 + * levels. (0x80 is the syscall vector)
 + */
 +#ifdef CONFIG_X86_32
 +# define FIRST_DEVICE_VECTOR  0x31
 +#else
 +# define FIRST_DEVICE_VECTOR  (IRQ15_VECTOR + 2)
 +#endif
 +
 +#define NR_VECTORS            256
 +
 +#define FPU_IRQ                       13
 +
 +#define       FIRST_VM86_IRQ          3
 +#define LAST_VM86_IRQ         15
 +#define invalid_vm86_irq(irq) ((irq) < 3 || (irq) > 15)
 +
 +#if !defined(CONFIG_X86_VOYAGER)
 +
 +# if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_PARAVIRT) || defined(CONFIG_X86_VISWS)
 +
 +#  define NR_IRQS             224
 +
 +#  if (224 >= 32 * NR_CPUS)
 +#   define NR_IRQ_VECTORS     NR_IRQS
 +#  else
 +#   define NR_IRQ_VECTORS     (32 * NR_CPUS)
 +#  endif
 +
 +# else /* IO_APIC || PARAVIRT */
 +
 +#  define NR_IRQS             16
 +#  define NR_IRQ_VECTORS      NR_IRQS
 +
 +# endif
 +
 +#else /* !VISWS && !VOYAGER */
 +
 +# define NR_IRQS              224
 +# define NR_IRQ_VECTORS               NR_IRQS
 +
 +#endif /* VISWS */
 +
 +/* Voyager specific defines */
 +/* These define the CPIs we use in linux */
 +#define VIC_CPI_LEVEL0                        0
 +#define VIC_CPI_LEVEL1                        1
 +/* now the fake CPIs */
 +#define VIC_TIMER_CPI                 2
 +#define VIC_INVALIDATE_CPI            3
 +#define VIC_RESCHEDULE_CPI            4
 +#define VIC_ENABLE_IRQ_CPI            5
 +#define VIC_CALL_FUNCTION_CPI         6
++#define VIC_CALL_FUNCTION_SINGLE_CPI  7
 +
 +/* Now the QIC CPIs:  Since we don't need the two initial levels,
 + * these are 2 less than the VIC CPIs */
 +#define QIC_CPI_OFFSET                        1
 +#define QIC_TIMER_CPI                 (VIC_TIMER_CPI - QIC_CPI_OFFSET)
 +#define QIC_INVALIDATE_CPI            (VIC_INVALIDATE_CPI - QIC_CPI_OFFSET)
 +#define QIC_RESCHEDULE_CPI            (VIC_RESCHEDULE_CPI - QIC_CPI_OFFSET)
 +#define QIC_ENABLE_IRQ_CPI            (VIC_ENABLE_IRQ_CPI - QIC_CPI_OFFSET)
 +#define QIC_CALL_FUNCTION_CPI         (VIC_CALL_FUNCTION_CPI - QIC_CPI_OFFSET)
++#define QIC_CALL_FUNCTION_SINGLE_CPI  (VIC_CALL_FUNCTION_SINGLE_CPI - QIC_CPI_OFFSET)
 +
 +#define VIC_START_FAKE_CPI            VIC_TIMER_CPI
++#define VIC_END_FAKE_CPI              VIC_CALL_FUNCTION_SINGLE_CPI
 +
 +/* this is the SYS_INT CPI. */
 +#define VIC_SYS_INT                   8
 +#define VIC_CMN_INT                   15
 +
 +/* This is the boot CPI for alternate processors.  It gets overwritten
 + * by the above once the system has activated all available processors */
 +#define VIC_CPU_BOOT_CPI              VIC_CPI_LEVEL0
 +#define VIC_CPU_BOOT_ERRATA_CPI               (VIC_CPI_LEVEL0 + 8)
 +
 +
 +#endif /* _ASM_IRQ_VECTORS_H */
@@@ -197,7 -205,7 +202,5 @@@ static inline int hard_smp_processor_id
  extern void cpu_uninit(void);
  #endif
  
- extern void lock_ipi_call_lock(void);
- extern void unlock_ipi_call_lock(void);
 -extern void smp_alloc_memory(void);
  #endif /* __ASSEMBLY__ */
  #endif
diff --cc kernel/Makefile
@@@ -39,7 -27,8 +39,8 @@@ obj-$(CONFIG_RT_MUTEXES) += rtmutex.
  obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o
  obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o
  obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 -obj-$(CONFIG_SMP) += cpu.o spinlock.o
+ obj-$(CONFIG_USE_GENERIC_SMP_HELPERS) += smp.o
 +obj-$(CONFIG_SMP) += spinlock.o
  obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
  obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
  obj-$(CONFIG_UID16) += uid16.o
Simple merge
Simple merge
Simple merge
diff --cc mm/page_alloc.c
Simple merge
diff --cc mm/slab.c
Simple merge
diff --cc mm/slub.c
Simple merge
diff --cc net/iucv/iucv.c
Simple merge