]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'x86-x2apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Oct 2010 20:54:05 +0000 (13:54 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Oct 2010 20:54:05 +0000 (13:54 -0700)
* 'x86-x2apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, x2apic: Simplify apic init in SMP and UP builds
  x86, intr-remap: Remove IRTE setup duplicate code
  x86, intr-remap: Set redirection hint in the IRTE

1  2 
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/smpboot.c

index f1e78940d90831627382e0fe5232b3441b9641a4,e8c95a22614a26a982398f69ab6cff328c32707f..9508811e8448b2d147386758605a6bc214839926
@@@ -162,7 -162,7 +162,7 @@@ int __init arch_early_irq_init(void
  
        cfg = irq_cfgx;
        count = ARRAY_SIZE(irq_cfgx);
 -      node= cpu_to_node(boot_cpu_id);
 +      node = cpu_to_node(0);
  
        for (i = 0; i < count; i++) {
                desc = irq_to_desc(i);
@@@ -306,19 -306,14 +306,19 @@@ void arch_init_copy_chip_data(struct ir
  
        old_cfg = old_desc->chip_data;
  
 -      memcpy(cfg, old_cfg, sizeof(struct irq_cfg));
 +      cfg->vector = old_cfg->vector;
 +      cfg->move_in_progress = old_cfg->move_in_progress;
 +      cpumask_copy(cfg->domain, old_cfg->domain);
 +      cpumask_copy(cfg->old_domain, old_cfg->old_domain);
  
        init_copy_irq_2_pin(old_cfg, cfg, node);
  }
  
 -static void free_irq_cfg(struct irq_cfg *old_cfg)
 +static void free_irq_cfg(struct irq_cfg *cfg)
  {
 -      kfree(old_cfg);
 +      free_cpumask_var(cfg->domain);
 +      free_cpumask_var(cfg->old_domain);
 +      kfree(cfg);
  }
  
  void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
@@@ -1382,21 -1377,7 +1382,7 @@@ int setup_ioapic_entry(int apic_id, in
                if (index < 0)
                        panic("Failed to allocate IRTE for ioapic %d\n", apic_id);
  
-               memset(&irte, 0, sizeof(irte));
-               irte.present = 1;
-               irte.dst_mode = apic->irq_dest_mode;
-               /*
-                * Trigger mode in the IRTE will always be edge, and the
-                * actual level or edge trigger will be setup in the IO-APIC
-                * RTE. This will help simplify level triggered irq migration.
-                * For more details, see the comments above explainig IO-APIC
-                * irq migration in the presence of interrupt-remapping.
-                */
-               irte.trigger_mode = 0;
-               irte.dlvry_mode = apic->irq_delivery_mode;
-               irte.vector = vector;
-               irte.dest_id = IRTE_DEST(destination);
+               prepare_irte(&irte, vector, destination);
  
                /* Set source-id of interrupt request */
                set_ioapic_sid(&irte, apic_id);
@@@ -1488,7 -1469,7 +1474,7 @@@ static void __init setup_IO_APIC_irqs(v
        int notcon = 0;
        struct irq_desc *desc;
        struct irq_cfg *cfg;
 -      int node = cpu_to_node(boot_cpu_id);
 +      int node = cpu_to_node(0);
  
        apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
  
  void setup_IO_APIC_irq_extra(u32 gsi)
  {
        int apic_id = 0, pin, idx, irq;
 -      int node = cpu_to_node(boot_cpu_id);
 +      int node = cpu_to_node(0);
        struct irq_desc *desc;
        struct irq_cfg *cfg;
  
@@@ -2932,7 -2913,7 +2918,7 @@@ static inline void __init check_timer(v
  {
        struct irq_desc *desc = irq_to_desc(0);
        struct irq_cfg *cfg = desc->chip_data;
 -      int node = cpu_to_node(boot_cpu_id);
 +      int node = cpu_to_node(0);
        int apic1, pin1, apic2, pin2;
        unsigned long flags;
        int no_pin1 = 0;
@@@ -3286,7 -3267,7 +3272,7 @@@ unsigned int create_irq_nr(unsigned in
  
  int create_irq(void)
  {
 -      int node = cpu_to_node(boot_cpu_id);
 +      int node = cpu_to_node(0);
        unsigned int irq_want;
        int irq;
  
@@@ -3340,14 -3321,7 +3326,7 @@@ static int msi_compose_msg(struct pci_d
                ir_index = map_irq_to_irte_handle(irq, &sub_handle);
                BUG_ON(ir_index == -1);
  
-               memset (&irte, 0, sizeof(irte));
-               irte.present = 1;
-               irte.dst_mode = apic->irq_dest_mode;
-               irte.trigger_mode = 0; /* edge */
-               irte.dlvry_mode = apic->irq_delivery_mode;
-               irte.vector = cfg->vector;
-               irte.dest_id = IRTE_DEST(dest);
+               prepare_irte(&irte, cfg->vector, dest);
  
                /* Set source-id of interrupt request */
                if (pdev)
@@@ -3908,7 -3882,7 +3887,7 @@@ static int __io_apic_set_pci_routing(st
        if (dev)
                node = dev_to_node(dev);
        else
 -              node = cpu_to_node(boot_cpu_id);
 +              node = cpu_to_node(0);
  
        desc = irq_to_desc_alloc_node(irq, node);
        if (!desc) {
index a3df9f8300375c7b7bef68d5ccd715d98cc9a2fc,87a8c6b00f8d90cac4d889c5aab6aff19b05ee05..2ced73ba048c2af73a242952739bb7b26ea4ff55
@@@ -62,7 -62,7 +62,7 @@@
  #include <asm/pgtable.h>
  #include <asm/tlbflush.h>
  #include <asm/mtrr.h>
 -#include <asm/vmi.h>
 +#include <asm/mwait.h>
  #include <asm/apic.h>
  #include <asm/setup.h>
  #include <asm/uv/uv.h>
@@@ -311,6 -311,7 +311,6 @@@ notrace static void __cpuinit start_sec
        __flush_tlb_all();
  #endif
  
 -      vmi_bringup();
        cpu_init();
        preempt_disable();
        smp_callin();
@@@ -396,19 -397,6 +396,19 @@@ void __cpuinit smp_store_cpu_info(int i
                identify_secondary_cpu(c);
  }
  
 +static void __cpuinit link_thread_siblings(int cpu1, int cpu2)
 +{
 +      struct cpuinfo_x86 *c1 = &cpu_data(cpu1);
 +      struct cpuinfo_x86 *c2 = &cpu_data(cpu2);
 +
 +      cpumask_set_cpu(cpu1, cpu_sibling_mask(cpu2));
 +      cpumask_set_cpu(cpu2, cpu_sibling_mask(cpu1));
 +      cpumask_set_cpu(cpu1, cpu_core_mask(cpu2));
 +      cpumask_set_cpu(cpu2, cpu_core_mask(cpu1));
 +      cpumask_set_cpu(cpu1, c2->llc_shared_map);
 +      cpumask_set_cpu(cpu2, c1->llc_shared_map);
 +}
 +
  
  void __cpuinit set_cpu_sibling_map(int cpu)
  {
                for_each_cpu(i, cpu_sibling_setup_mask) {
                        struct cpuinfo_x86 *o = &cpu_data(i);
  
 -                      if (c->phys_proc_id == o->phys_proc_id &&
 -                          c->cpu_core_id == o->cpu_core_id) {
 -                              cpumask_set_cpu(i, cpu_sibling_mask(cpu));
 -                              cpumask_set_cpu(cpu, cpu_sibling_mask(i));
 -                              cpumask_set_cpu(i, cpu_core_mask(cpu));
 -                              cpumask_set_cpu(cpu, cpu_core_mask(i));
 -                              cpumask_set_cpu(i, c->llc_shared_map);
 -                              cpumask_set_cpu(cpu, o->llc_shared_map);
 +                      if (cpu_has(c, X86_FEATURE_TOPOEXT)) {
 +                              if (c->phys_proc_id == o->phys_proc_id &&
 +                                  c->compute_unit_id == o->compute_unit_id)
 +                                      link_thread_siblings(cpu, i);
 +                      } else if (c->phys_proc_id == o->phys_proc_id &&
 +                                 c->cpu_core_id == o->cpu_core_id) {
 +                              link_thread_siblings(cpu, i);
                        }
                }
        } else {
@@@ -1120,8 -1109,6 +1120,6 @@@ void __init native_smp_prepare_cpus(uns
        }
        set_cpu_sibling_map(0);
  
-       enable_IR_x2apic();
-       default_setup_apic_routing();
  
        if (smp_sanity_check(max_cpus) < 0) {
                printk(KERN_INFO "SMP disabled\n");
                goto out;
        }
  
+       default_setup_apic_routing();
        preempt_disable();
        if (read_apic_id() != boot_cpu_physical_apicid) {
                panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
@@@ -1394,88 -1383,11 +1394,88 @@@ void play_dead_common(void
        local_irq_disable();
  }
  
 +/*
 + * We need to flush the caches before going to sleep, lest we have
 + * dirty data in our caches when we come back up.
 + */
 +static inline void mwait_play_dead(void)
 +{
 +      unsigned int eax, ebx, ecx, edx;
 +      unsigned int highest_cstate = 0;
 +      unsigned int highest_subcstate = 0;
 +      int i;
 +      void *mwait_ptr;
 +
 +      if (!cpu_has(&current_cpu_data, X86_FEATURE_MWAIT))
 +              return;
 +      if (!cpu_has(&current_cpu_data, X86_FEATURE_CLFLSH))
 +              return;
 +      if (current_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
 +              return;
 +
 +      eax = CPUID_MWAIT_LEAF;
 +      ecx = 0;
 +      native_cpuid(&eax, &ebx, &ecx, &edx);
 +
 +      /*
 +       * eax will be 0 if EDX enumeration is not valid.
 +       * Initialized below to cstate, sub_cstate value when EDX is valid.
 +       */
 +      if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED)) {
 +              eax = 0;
 +      } else {
 +              edx >>= MWAIT_SUBSTATE_SIZE;
 +              for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) {
 +                      if (edx & MWAIT_SUBSTATE_MASK) {
 +                              highest_cstate = i;
 +                              highest_subcstate = edx & MWAIT_SUBSTATE_MASK;
 +                      }
 +              }
 +              eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
 +                      (highest_subcstate - 1);
 +      }
 +
 +      /*
 +       * This should be a memory location in a cache line which is
 +       * unlikely to be touched by other processors.  The actual
 +       * content is immaterial as it is not actually modified in any way.
 +       */
 +      mwait_ptr = &current_thread_info()->flags;
 +
 +      wbinvd();
 +
 +      while (1) {
 +              /*
 +               * The CLFLUSH is a workaround for erratum AAI65 for
 +               * the Xeon 7400 series.  It's not clear it is actually
 +               * needed, but it should be harmless in either case.
 +               * The WBINVD is insufficient due to the spurious-wakeup
 +               * case where we return around the loop.
 +               */
 +              clflush(mwait_ptr);
 +              __monitor(mwait_ptr, 0, 0);
 +              mb();
 +              __mwait(eax, 0);
 +      }
 +}
 +
 +static inline void hlt_play_dead(void)
 +{
 +      if (current_cpu_data.x86 >= 4)
 +              wbinvd();
 +
 +      while (1) {
 +              native_halt();
 +      }
 +}
 +
  void native_play_dead(void)
  {
        play_dead_common();
        tboot_shutdown(TB_SHUTDOWN_WFS);
 -      wbinvd_halt();
 +
 +      mwait_play_dead();      /* Only returns on failure */
 +      hlt_play_dead();
  }
  
  #else /* ... !CONFIG_HOTPLUG_CPU */