File: /Users/paulross/dev/linux/linux-3.13/arch/x86/include/asm/smp.h

Green shading in the line number column means the source is part of the translation unit, red means it is conditionally excluded. Highlighted line numbers link to the translation unit page. Highlighted macros link to the macro page.

       1: #ifndef _ASM_X86_SMP_H
       2: #define _ASM_X86_SMP_H
       3: #ifndef __ASSEMBLY__
       4: #include <linux/cpumask.h>
       5: #include <linux/init.h>
       6: #include <asm/percpu.h>
       7: 
       8: /*
       9:  * We need the APIC definitions automatically as part of 'smp.h'
      10:  */
      11: #ifdef CONFIG_X86_LOCAL_APIC
      12: # include <asm/mpspec.h>
      13: # include <asm/apic.h>
      14: # ifdef CONFIG_X86_IO_APIC
      15: #  include <asm/io_apic.h>
      16: # endif
      17: #endif
      18: #include <asm/thread_info.h>
      19: #include <asm/cpumask.h>
      20: #include <asm/cpufeature.h>
      21: 
      22: extern int smp_num_siblings;
      23: extern unsigned int num_processors;
      24: 
      25: static inline bool cpu_has_ht_siblings(void)
      26: {
      27:     bool has_siblings = false;
      28: #ifdef CONFIG_SMP
      29:     has_siblings = cpu_has_ht && smp_num_siblings > 1;
      30: #endif
      31:     return has_siblings;
      32: }
      33: 
      34: DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map);
      35: DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map);
      36: /* cpus sharing the last level cache: */
      37: DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
      38: DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id);
      39: DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number);
      40: 
      41: static inline struct cpumask *cpu_sibling_mask(int cpu)
      42: {
      43:     return per_cpu(cpu_sibling_map, cpu);
      44: }
      45: 
      46: static inline struct cpumask *cpu_core_mask(int cpu)
      47: {
      48:     return per_cpu(cpu_core_map, cpu);
      49: }
      50: 
      51: static inline struct cpumask *cpu_llc_shared_mask(int cpu)
      52: {
      53:     return per_cpu(cpu_llc_shared_map, cpu);
      54: }
      55: 
      56: DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid);
      57: DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid);
      58: #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
      59: DECLARE_EARLY_PER_CPU_READ_MOSTLY(int, x86_cpu_to_logical_apicid);
      60: #endif
      61: 
      62: /* Static state in head.S used to set up a CPU */
      63: extern unsigned long stack_start; /* Initial stack pointer address */
      64: 
      65: struct task_struct;
      66: 
      67: struct smp_ops {
      68:     void (*smp_prepare_boot_cpu)(void);
      69:     void (*smp_prepare_cpus)(unsigned max_cpus);
      70:     void (*smp_cpus_done)(unsigned max_cpus);
      71: 
      72:     void (*stop_other_cpus)(int wait);
      73:     void (*smp_send_reschedule)(int cpu);
      74: 
      75:     int (*cpu_up)(unsigned cpu, struct task_struct *tidle);
      76:     int (*cpu_disable)(void);
      77:     void (*cpu_die)(unsigned int cpu);
      78:     void (*play_dead)(void);
      79: 
      80:     void (*send_call_func_ipi)(const struct cpumask *mask);
      81:     void (*send_call_func_single_ipi)(int cpu);
      82: };
      83: 
      84: /* Globals due to paravirt */
      85: extern void set_cpu_sibling_map(int cpu);
      86: 
      87: #ifdef CONFIG_SMP
      88: #ifndef CONFIG_PARAVIRT
      89: #define startup_ipi_hook(phys_apicid, start_eip, start_esp) do { } while (0)
      90: #endif
      91: extern struct smp_ops smp_ops;
      92: 
      93: static inline void smp_send_stop(void)
      94: {
      95:     smp_ops.stop_other_cpus(0);
      96: }
      97: 
      98: static inline void stop_other_cpus(void)
      99: {
     100:     smp_ops.stop_other_cpus(1);
     101: }
     102: 
     103: static inline void smp_prepare_boot_cpu(void)
     104: {
     105:     smp_ops.smp_prepare_boot_cpu();
     106: }
     107: 
     108: static inline void smp_prepare_cpus(unsigned int max_cpus)
     109: {
     110:     smp_ops.smp_prepare_cpus(max_cpus);
     111: }
     112: 
     113: static inline void smp_cpus_done(unsigned int max_cpus)
     114: {
     115:     smp_ops.smp_cpus_done(max_cpus);
     116: }
     117: 
     118: static inline int __cpu_up(unsigned int cpu, struct task_struct *tidle)
     119: {
     120:     return smp_ops.cpu_up(cpu, tidle);
     121: }
     122: 
     123: static inline int __cpu_disable(void)
     124: {
     125:     return smp_ops.cpu_disable();
     126: }
     127: 
     128: static inline void __cpu_die(unsigned int cpu)
     129: {
     130:     smp_ops.cpu_die(cpu);
     131: }
     132: 
     133: static inline void play_dead(void)
     134: {
     135:     smp_ops.play_dead();
     136: }
     137: 
     138: static inline void smp_send_reschedule(int cpu)
     139: {
     140:     smp_ops.smp_send_reschedule(cpu);
     141: }
     142: 
     143: static inline void arch_send_call_function_single_ipi(int cpu)
     144: {
     145:     smp_ops.send_call_func_single_ipi(cpu);
     146: }
     147: 
     148: static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
     149: {
     150:     smp_ops.send_call_func_ipi(mask);
     151: }
     152: 
     153: void cpu_disable_common(void);
     154: void native_smp_prepare_boot_cpu(void);
     155: void native_smp_prepare_cpus(unsigned int max_cpus);
     156: void native_smp_cpus_done(unsigned int max_cpus);
     157: int native_cpu_up(unsigned int cpunum, struct task_struct *tidle);
     158: int native_cpu_disable(void);
     159: void native_cpu_die(unsigned int cpu);
     160: void native_play_dead(void);
     161: void play_dead_common(void);
     162: void wbinvd_on_cpu(int cpu);
     163: int wbinvd_on_all_cpus(void);
     164: 
     165: void native_send_call_func_ipi(const struct cpumask *mask);
     166: void native_send_call_func_single_ipi(int cpu);
     167: void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle);
     168: 
     169: void smp_store_boot_cpu_info(void);
     170: void smp_store_cpu_info(int id);
     171: #define cpu_physical_id(cpu)    per_cpu(x86_cpu_to_apicid, cpu)
     172: 
     173: #else /* !CONFIG_SMP */
     174: #define wbinvd_on_cpu(cpu)     wbinvd()
     175: static inline int wbinvd_on_all_cpus(void)
     176: {
     177:     wbinvd();
     178:     return 0;
     179: }
     180: #endif /* CONFIG_SMP */
     181: 
     182: extern unsigned disabled_cpus;
     183: 
     184: #ifdef CONFIG_X86_32_SMP
     185: /*
     186:  * This function is needed by all SMP systems. It must _always_ be valid
     187:  * from the initial startup. We map APIC_BASE very early in page_setup(),
     188:  * so this is correct in the x86 case.
     189:  */
     190: #define raw_smp_processor_id() (this_cpu_read(cpu_number))
     191: extern int safe_smp_processor_id(void);
     192: 
     193: #elif defined(CONFIG_X86_64_SMP)
     194: #define raw_smp_processor_id() (this_cpu_read(cpu_number))
     195: 
     196: #define stack_smp_processor_id()                    \
     197: ({                                \
     198:     struct thread_info *ti;                        \
     199:     __asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK));    \
     200:     ti->cpu;                            \
     201: })
     202: #define safe_smp_processor_id()        smp_processor_id()
     203: 
     204: #endif
     205: 
     206: #ifdef CONFIG_X86_LOCAL_APIC
     207: 
     208: #ifndef CONFIG_X86_64
     209: static inline int logical_smp_processor_id(void)
     210: {
     211:     /* we don't want to mark this access volatile - bad code generation */
     212:     return GET_APIC_LOGICAL_ID(apic_read(APIC_LDR));
     213: }
     214: 
     215: #endif
     216: 
     217: extern int hard_smp_processor_id(void);
     218: 
     219: #else /* CONFIG_X86_LOCAL_APIC */
     220: 
     221: # ifndef CONFIG_SMP
     222: #  define hard_smp_processor_id()    0
     223: # endif
     224: 
     225: #endif /* CONFIG_X86_LOCAL_APIC */
     226: 
     227: #ifdef CONFIG_DEBUG_NMI_SELFTEST
     228: extern void nmi_selftest(void);
     229: #else
     230: #define nmi_selftest() do { } while (0)
     231: #endif
     232: 
     233: #endif /* __ASSEMBLY__ */
     234: #endif /* _ASM_X86_SMP_H */
     235: