Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 20 May 2011 01:07:31 +0000 (18:07 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 20 May 2011 01:07:31 +0000 (18:07 -0700)
* 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (50 commits)
  x86, mm: Allow ZONE_DMA to be configurable
  x86, NUMA: Trim numa meminfo with max_pfn in a separate loop
  x86, NUMA: Rename setup_node_bootmem() to setup_node_data()
  x86, NUMA: Enable emulation on 32bit too
  x86, NUMA: Enable CONFIG_AMD_NUMA on 32bit too
  x86, NUMA: Rename amdtopology_64.c to amdtopology.c
  x86, NUMA: Make numa_init_array() static
  x86, NUMA: Make 32bit use common NUMA init path
  x86, NUMA: Initialize and use remap allocator from setup_node_bootmem()
  x86-32, NUMA: Add @start and @end to init_alloc_remap()
  x86, NUMA: Remove long 64bit assumption from numa.c
  x86, NUMA: Enable build of generic NUMA init code on 32bit
  x86, NUMA: Move NUMA init logic from numa_64.c to numa.c
  x86-32, NUMA: Update numaq to use new NUMA init protocol
  x86-32, NUMA: Replace srat_32.c with srat.c
  x86-32, NUMA: implement temporary NUMA init shims
  x86, NUMA: Move numa_nodes_parsed to numa.[hc]
  x86-32, NUMA: Move get_memcfg_numa() into numa_32.c
  x86, NUMA: make srat.c 32bit safe
  x86, NUMA: rename srat_64.c to srat.c
  ...

1  2 
arch/x86/Kconfig
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/percpu.h
arch/x86/kernel/apic/apic.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/mpparse.c

diff --combined arch/x86/Kconfig
@@@ -8,7 -8,6 +8,7 @@@ config 64BI
  
  config X86_32
        def_bool !64BIT
 +      select CLKSRC_I8253
  
  config X86_64
        def_bool 64BIT
@@@ -72,6 -71,7 +72,6 @@@ config X8
        select GENERIC_IRQ_SHOW
        select IRQ_FORCED_THREADING
        select USE_GENERIC_SMP_HELPERS if SMP
 -      select ARCH_NO_SYSDEV_OPS
  
  config INSTRUCTION_DECODER
        def_bool (KPROBES || PERF_EVENTS)
@@@ -112,7 -112,14 +112,14 @@@ config MM
        def_bool y
  
  config ZONE_DMA
-       def_bool y
+       bool "DMA memory allocation support" if EXPERT
+       default y
+       help
+         DMA memory allocation support allows devices with less than 32-bit
+         addressing to allocate within the first 16MB of address space.
+         Disable if no such devices will be used.
+         If unsure, say Y.
  
  config SBUS
        bool
@@@ -365,6 -372,17 +372,6 @@@ config X86_U
  # Following is an alphabetically sorted list of 32 bit extended platforms
  # Please maintain the alphabetic order if and when there are additions
  
 -config X86_ELAN
 -      bool "AMD Elan"
 -      depends on X86_32
 -      depends on X86_EXTENDED_PLATFORM
 -      ---help---
 -        Select this for an AMD Elan processor.
 -
 -        Do not use this option for K6/Athlon/Opteron processors!
 -
 -        If unsure, choose "PC-compatible" instead.
 -
  config X86_INTEL_CE
        bool "CE4100 TV platform"
        depends on PCI
@@@ -679,7 -697,6 +686,7 @@@ config AMD_IOMM
        bool "AMD IOMMU support"
        select SWIOTLB
        select PCI_MSI
 +      select PCI_IOV
        depends on X86_64 && PCI && ACPI
        ---help---
          With this option you can enable support for AMD IOMMU hardware in
@@@ -1164,7 -1181,7 +1171,7 @@@ comment "NUMA (Summit) requires SMP, 64
  config AMD_NUMA
        def_bool y
        prompt "Old style AMD Opteron NUMA detection"
-       depends on X86_64 && NUMA && PCI
+       depends on NUMA && PCI
        ---help---
          Enable AMD NUMA node topology detection.  You should say Y here if
          you have a multi processor AMD system. This uses an old method to
@@@ -1191,7 -1208,7 +1198,7 @@@ config NODES_SPAN_OTHER_NODE
  
  config NUMA_EMU
        bool "NUMA emulation"
-       depends on X86_64 && NUMA
+       depends on NUMA
        ---help---
          Enable NUMA emulation. A flat machine will be split
          into virtual nodes when booted with "numa=fake=N", where N is the
@@@ -1213,6 -1230,10 +1220,10 @@@ config HAVE_ARCH_BOOTME
        def_bool y
        depends on X86_32 && NUMA
  
+ config HAVE_ARCH_ALLOC_REMAP
+       def_bool y
+       depends on X86_32 && NUMA
  config ARCH_HAVE_MEMORY_PRESENT
        def_bool y
        depends on X86_32 && DISCONTIGMEM
@@@ -1221,13 -1242,9 +1232,9 @@@ config NEED_NODE_MEMMAP_SIZ
        def_bool y
        depends on X86_32 && (DISCONTIGMEM || SPARSEMEM)
  
- config HAVE_ARCH_ALLOC_REMAP
-       def_bool y
-       depends on X86_32 && NUMA
  config ARCH_FLATMEM_ENABLE
        def_bool y
-       depends on X86_32 && ARCH_SELECT_MEMORY_MODEL && !NUMA
+       depends on X86_32 && !NUMA
  
  config ARCH_DISCONTIGMEM_ENABLE
        def_bool y
@@@ -1237,20 -1254,16 +1244,16 @@@ config ARCH_DISCONTIGMEM_DEFAUL
        def_bool y
        depends on NUMA && X86_32
  
- config ARCH_PROC_KCORE_TEXT
-       def_bool y
-       depends on X86_64 && PROC_KCORE
- config ARCH_SPARSEMEM_DEFAULT
-       def_bool y
-       depends on X86_64
  config ARCH_SPARSEMEM_ENABLE
        def_bool y
        depends on X86_64 || NUMA || (EXPERIMENTAL && X86_32) || X86_32_NON_STANDARD
        select SPARSEMEM_STATIC if X86_32
        select SPARSEMEM_VMEMMAP_ENABLE if X86_64
  
+ config ARCH_SPARSEMEM_DEFAULT
+       def_bool y
+       depends on X86_64
  config ARCH_SELECT_MEMORY_MODEL
        def_bool y
        depends on ARCH_SPARSEMEM_ENABLE
@@@ -1259,6 -1272,10 +1262,10 @@@ config ARCH_MEMORY_PROB
        def_bool X86_64
        depends on MEMORY_HOTPLUG
  
+ config ARCH_PROC_KCORE_TEXT
+       def_bool y
+       depends on X86_64 && PROC_KCORE
  config ILLEGAL_POINTER_VALUE
         hex
         default 0 if X86_32
@@@ -1693,10 -1710,6 +1700,6 @@@ config ARCH_ENABLE_MEMORY_HOTREMOV
        def_bool y
        depends on MEMORY_HOTPLUG
  
- config HAVE_ARCH_EARLY_PFN_TO_NID
-       def_bool X86_64
-       depends on NUMA
  config USE_PERCPU_NUMA_NODE_ID
        def_bool y
        depends on NUMA
@@@ -1838,7 -1851,7 +1841,7 @@@ config APM_ALLOW_INT
  
  endif # APM
  
 -source "arch/x86/kernel/cpu/cpufreq/Kconfig"
 +source "drivers/cpufreq/Kconfig"
  
  source "drivers/cpuidle/Kconfig"
  
  
  /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
  #define X86_FEATURE_FSGSBASE  (9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
 +#define X86_FEATURE_ERMS      (9*32+ 9) /* Enhanced REP MOVSB/STOSB */
  
  #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
  
@@@ -208,8 -207,7 +208,7 @@@ extern const char * const x86_power_fla
  #define test_cpu_cap(c, bit)                                          \
         test_bit(bit, (unsigned long *)((c)->x86_capability))
  
- #define cpu_has(c, bit)                                                       \
-       (__builtin_constant_p(bit) &&                                   \
+ #define REQUIRED_MASK_BIT_SET(bit)                                    \
         ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) ||     \
           (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) ||     \
           (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) ||     \
           (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) ||     \
           (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) ||     \
           (((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8)) ||     \
-          (((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9)) )      \
-         ? 1 :                                                         \
+          (((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9)) )
+ #define cpu_has(c, bit)                                                       \
+       (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :  \
         test_cpu_cap(c, bit))
  
+ #define this_cpu_has(bit)                                             \
+       (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :  \
+        x86_this_cpu_test_bit(bit, (unsigned long *)&cpu_info.x86_capability))
  #define boot_cpu_has(bit)     cpu_has(&boot_cpu_data, bit)
  
  #define set_cpu_cap(c, bit)   set_bit(bit, (unsigned long *)((c)->x86_capability))
@@@ -517,7 -517,7 +517,7 @@@ do {                                                                       
        typeof(o2) __o2 = o2;                                           \
        typeof(o2) __n2 = n2;                                           \
        typeof(o2) __dummy;                                             \
 -      alternative_io("call this_cpu_cmpxchg16b_emu\n\t" P6_NOP4,      \
 +      alternative_io("call this_cpu_cmpxchg16b_emu\n\t" ASM_NOP4,     \
                       "cmpxchg16b " __percpu_prefix "(%%rsi)\n\tsetz %0\n\t",  \
                       X86_FEATURE_CX16,                                \
                       ASM_OUTPUT2("=a"(__ret), "=d"(__dummy)),         \
        old__;                                                          \
  })
  
+ static __always_inline int x86_this_cpu_constant_test_bit(unsigned int nr,
+                         const unsigned long __percpu *addr)
+ {
+       unsigned long __percpu *a = (unsigned long *)addr + nr / BITS_PER_LONG;
+       return ((1UL << (nr % BITS_PER_LONG)) & percpu_read(*a)) != 0;
+ }
+ static inline int x86_this_cpu_variable_test_bit(int nr,
+                         const unsigned long __percpu *addr)
+ {
+       int oldbit;
+       asm volatile("bt "__percpu_arg(2)",%1\n\t"
+                       "sbb %0,%0"
+                       : "=r" (oldbit)
+                       : "m" (*(unsigned long *)addr), "Ir" (nr));
+       return oldbit;
+ }
+ #define x86_this_cpu_test_bit(nr, addr)                       \
+       (__builtin_constant_p((nr))                     \
+        ? x86_this_cpu_constant_test_bit((nr), (addr)) \
+        : x86_this_cpu_variable_test_bit((nr), (addr)))
  #include <asm-generic/percpu.h>
  
  /* We can use this directly for local CPU (faster). */
@@@ -505,7 -505,7 +505,7 @@@ static void __cpuinit setup_APIC_timer(
  {
        struct clock_event_device *levt = &__get_cpu_var(lapic_events);
  
-       if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_ARAT)) {
+       if (this_cpu_has(X86_FEATURE_ARAT)) {
                lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP;
                /* Make LAPIC timer preferrable over percpu HPET */
                lapic_clockevent.rating = 150;
@@@ -1237,6 -1237,17 +1237,17 @@@ void __cpuinit setup_local_APIC(void
        /* always use the value from LDR */
        early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
                logical_smp_processor_id();
+       /*
+        * Some NUMA implementations (NUMAQ) don't initialize apicid to
+        * node mapping during NUMA init.  Now that logical apicid is
+        * guaranteed to be known, give it another chance.  This is already
+        * a bit too late - percpu allocation has already happened without
+        * proper NUMA affinity.
+        */
+       if (apic->x86_32_numa_cpu_node)
+               set_apicid_to_node(early_per_cpu(x86_cpu_to_apicid, cpu),
+                                  apic->x86_32_numa_cpu_node(cpu));
  #endif
  
        /*
@@@ -1812,41 -1823,30 +1823,41 @@@ void smp_spurious_interrupt(struct pt_r
   */
  void smp_error_interrupt(struct pt_regs *regs)
  {
 -      u32 v, v1;
 +      u32 v0, v1;
 +      u32 i = 0;
 +      static const char * const error_interrupt_reason[] = {
 +              "Send CS error",                /* APIC Error Bit 0 */
 +              "Receive CS error",             /* APIC Error Bit 1 */
 +              "Send accept error",            /* APIC Error Bit 2 */
 +              "Receive accept error",         /* APIC Error Bit 3 */
 +              "Redirectable IPI",             /* APIC Error Bit 4 */
 +              "Send illegal vector",          /* APIC Error Bit 5 */
 +              "Received illegal vector",      /* APIC Error Bit 6 */
 +              "Illegal register address",     /* APIC Error Bit 7 */
 +      };
  
        exit_idle();
        irq_enter();
        /* First tickle the hardware, only then report what went on. -- REW */
 -      v = apic_read(APIC_ESR);
 +      v0 = apic_read(APIC_ESR);
        apic_write(APIC_ESR, 0);
        v1 = apic_read(APIC_ESR);
        ack_APIC_irq();
        atomic_inc(&irq_err_count);
  
 -      /*
 -       * Here is what the APIC error bits mean:
 -       * 0: Send CS error
 -       * 1: Receive CS error
 -       * 2: Send accept error
 -       * 3: Receive accept error
 -       * 4: Reserved
 -       * 5: Send illegal vector
 -       * 6: Received illegal vector
 -       * 7: Illegal register address
 -       */
 -      pr_debug("APIC error on CPU%d: %02x(%02x)\n",
 -              smp_processor_id(), v , v1);
 +      apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x(%02x)",
 +                  smp_processor_id(), v0 , v1);
 +
 +      v1 = v1 & 0xff;
 +      while (v1) {
 +              if (v1 & 0x1)
 +                      apic_printk(APIC_DEBUG, KERN_CONT " : %s", error_interrupt_reason[i]);
 +              i++;
 +              v1 >>= 1;
 +      };
 +
 +      apic_printk(APIC_DEBUG, KERN_CONT "\n");
 +
        irq_exit();
  }
  
@@@ -2014,21 -2014,6 +2025,6 @@@ void default_init_apic_ldr(void
        apic_write(APIC_LDR, val);
  }
  
- #ifdef CONFIG_X86_32
- int default_x86_32_numa_cpu_node(int cpu)
- {
- #ifdef CONFIG_NUMA
-       int apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
-       if (apicid != BAD_APICID)
-               return __apicid_to_node[apicid];
-       return NUMA_NO_NODE;
- #else
-       return 0;
- #endif
- }
- #endif
  /*
   * Power management
   */
@@@ -187,6 -187,8 +187,6 @@@ static int therm_throt_process(bool new
                                this_cpu,
                                level == CORE_LEVEL ? "Core" : "Package",
                                state->count);
 -
 -              add_taint(TAINT_MACHINE_CHECK);
                return 1;
        }
        if (old_event) {
@@@ -353,7 -355,6 +353,6 @@@ static void notify_thresholds(__u64 msr
  static void intel_thermal_interrupt(void)
  {
        __u64 msr_val;
-       struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
  
        rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
  
                                CORE_LEVEL) != 0)
                mce_log_therm_throt_event(CORE_THROTTLED | msr_val);
  
-       if (cpu_has(c, X86_FEATURE_PLN))
+       if (this_cpu_has(X86_FEATURE_PLN))
                if (therm_throt_process(msr_val & THERM_STATUS_POWER_LIMIT,
                                        POWER_LIMIT_EVENT,
                                        CORE_LEVEL) != 0)
                        mce_log_therm_throt_event(CORE_POWER_LIMIT | msr_val);
  
-       if (cpu_has(c, X86_FEATURE_PTS)) {
+       if (this_cpu_has(X86_FEATURE_PTS)) {
                rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
                if (therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT,
                                        THERMAL_THROTTLING_EVENT,
                                        PACKAGE_LEVEL) != 0)
                        mce_log_therm_throt_event(PACKAGE_THROTTLED | msr_val);
-               if (cpu_has(c, X86_FEATURE_PLN))
+               if (this_cpu_has(X86_FEATURE_PLN))
                        if (therm_throt_process(msr_val &
                                        PACKAGE_THERM_STATUS_POWER_LIMIT,
                                        POWER_LIMIT_EVENT,
@@@ -391,6 -392,7 +390,6 @@@ static void unexpected_thermal_interrup
  {
        printk(KERN_ERR "CPU%d: Unexpected LVT thermal interrupt!\n",
                        smp_processor_id());
 -      add_taint(TAINT_MACHINE_CHECK);
  }
  
  static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt;
@@@ -443,20 -445,18 +442,20 @@@ void intel_init_thermal(struct cpuinfo_
         */
        rdmsr(MSR_IA32_MISC_ENABLE, l, h);
  
 +      h = lvtthmr_init;
        /*
         * The initial value of thermal LVT entries on all APs always reads
         * 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI
         * sequence to them and LVT registers are reset to 0s except for
         * the mask bits which are set to 1s when APs receive INIT IPI.
 -       * Always restore the value that BIOS has programmed on AP based on
 -       * BSP's info we saved since BIOS is always setting the same value
 -       * for all threads/cores
 +       * If BIOS takes over the thermal interrupt and sets its interrupt
 +       * delivery mode to SMI (not fixed), it restores the value that the
 +       * BIOS has programmed on AP based on BSP's info we saved since BIOS
 +       * is always setting the same value for all threads/cores.
         */
 -      apic_write(APIC_LVTTHMR, lvtthmr_init);
 +      if ((h & APIC_DM_FIXED_MASK) != APIC_DM_FIXED)
 +              apic_write(APIC_LVTTHMR, lvtthmr_init);
  
 -      h = lvtthmr_init;
  
        if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
                printk(KERN_DEBUG
@@@ -715,15 -715,17 +715,15 @@@ static void __init check_irq_src(struc
        }
  }
  
- static int
+ static int __init
  check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, int count)
  {
 -      int ret = 0;
 -
        if (!mpc_new_phys || count <= mpc_new_length) {
                WARN(1, "update_mptable: No spare slots (length: %x)\n", count);
                return -1;
        }
  
 -      return ret;
 +      return 0;
  }
  #else /* CONFIG_X86_IO_APIC */
  static