diff options
Diffstat (limited to 'include/asm-x86/topology.h')
| -rw-r--r-- | include/asm-x86/topology.h | 157 |
1 files changed, 96 insertions, 61 deletions
diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index dcf3f8131d6b..90ac7718469a 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h | |||
| @@ -35,79 +35,93 @@ | |||
| 35 | # endif | 35 | # endif |
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | /* Node not present */ | ||
| 39 | #define NUMA_NO_NODE (-1) | ||
| 40 | |||
| 38 | #ifdef CONFIG_NUMA | 41 | #ifdef CONFIG_NUMA |
| 39 | #include <linux/cpumask.h> | 42 | #include <linux/cpumask.h> |
| 40 | #include <asm/mpspec.h> | 43 | #include <asm/mpspec.h> |
| 41 | 44 | ||
| 42 | /* Mappings between logical cpu number and node number */ | ||
| 43 | #ifdef CONFIG_X86_32 | 45 | #ifdef CONFIG_X86_32 |
| 44 | extern int cpu_to_node_map[]; | ||
| 45 | #else | ||
| 46 | /* Returns the number of the current Node. */ | ||
| 47 | #define numa_node_id() (early_cpu_to_node(raw_smp_processor_id())) | ||
| 48 | #endif | ||
| 49 | |||
| 50 | DECLARE_PER_CPU(int, x86_cpu_to_node_map); | ||
| 51 | |||
| 52 | #ifdef CONFIG_SMP | ||
| 53 | extern int x86_cpu_to_node_map_init[]; | ||
| 54 | extern void *x86_cpu_to_node_map_early_ptr; | ||
| 55 | #else | ||
| 56 | #define x86_cpu_to_node_map_early_ptr NULL | ||
| 57 | #endif | ||
| 58 | 46 | ||
| 47 | /* Mappings between node number and cpus on that node. */ | ||
| 59 | extern cpumask_t node_to_cpumask_map[]; | 48 | extern cpumask_t node_to_cpumask_map[]; |
| 60 | 49 | ||
| 61 | #define NUMA_NO_NODE (-1) | 50 | /* Mappings between logical cpu number and node number */ |
| 51 | extern int cpu_to_node_map[]; | ||
| 62 | 52 | ||
| 63 | /* Returns the number of the node containing CPU 'cpu' */ | 53 | /* Returns the number of the node containing CPU 'cpu' */ |
| 64 | #ifdef CONFIG_X86_32 | ||
| 65 | #define early_cpu_to_node(cpu) cpu_to_node(cpu) | ||
| 66 | static inline int cpu_to_node(int cpu) | 54 | static inline int cpu_to_node(int cpu) |
| 67 | { | 55 | { |
| 68 | return cpu_to_node_map[cpu]; | 56 | return cpu_to_node_map[cpu]; |
| 69 | } | 57 | } |
| 58 | #define early_cpu_to_node(cpu) cpu_to_node(cpu) | ||
| 70 | 59 | ||
| 71 | #else /* CONFIG_X86_64 */ | 60 | /* Returns a bitmask of CPUs on Node 'node'. |
| 72 | 61 | * | |
| 73 | #ifdef CONFIG_SMP | 62 | * Side note: this function creates the returned cpumask on the stack |
| 74 | static inline int early_cpu_to_node(int cpu) | 63 | * so with a high NR_CPUS count, excessive stack space is used. The |
| 64 | * node_to_cpumask_ptr function should be used whenever possible. | ||
| 65 | */ | ||
| 66 | static inline cpumask_t node_to_cpumask(int node) | ||
| 75 | { | 67 | { |
| 76 | int *cpu_to_node_map = x86_cpu_to_node_map_early_ptr; | 68 | return node_to_cpumask_map[node]; |
| 77 | |||
| 78 | if (cpu_to_node_map) | ||
| 79 | return cpu_to_node_map[cpu]; | ||
| 80 | else if (per_cpu_offset(cpu)) | ||
| 81 | return per_cpu(x86_cpu_to_node_map, cpu); | ||
| 82 | else | ||
| 83 | return NUMA_NO_NODE; | ||
| 84 | } | 69 | } |
| 85 | #else | ||
| 86 | #define early_cpu_to_node(cpu) cpu_to_node(cpu) | ||
| 87 | #endif | ||
| 88 | 70 | ||
| 71 | #else /* CONFIG_X86_64 */ | ||
| 72 | |||
| 73 | /* Mappings between node number and cpus on that node. */ | ||
| 74 | extern cpumask_t *node_to_cpumask_map; | ||
| 75 | |||
| 76 | /* Mappings between logical cpu number and node number */ | ||
| 77 | DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map); | ||
| 78 | |||
| 79 | /* Returns the number of the current Node. */ | ||
| 80 | #define numa_node_id() read_pda(nodenumber) | ||
| 81 | |||
| 82 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | ||
| 83 | extern int cpu_to_node(int cpu); | ||
| 84 | extern int early_cpu_to_node(int cpu); | ||
| 85 | extern const cpumask_t *_node_to_cpumask_ptr(int node); | ||
| 86 | extern cpumask_t node_to_cpumask(int node); | ||
| 87 | |||
| 88 | #else /* !CONFIG_DEBUG_PER_CPU_MAPS */ | ||
| 89 | |||
| 90 | /* Returns the number of the node containing CPU 'cpu' */ | ||
| 89 | static inline int cpu_to_node(int cpu) | 91 | static inline int cpu_to_node(int cpu) |
| 90 | { | 92 | { |
| 91 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | ||
| 92 | if (x86_cpu_to_node_map_early_ptr) { | ||
| 93 | printk("KERN_NOTICE cpu_to_node(%d): usage too early!\n", | ||
| 94 | (int)cpu); | ||
| 95 | dump_stack(); | ||
| 96 | return ((int *)x86_cpu_to_node_map_early_ptr)[cpu]; | ||
| 97 | } | ||
| 98 | #endif | ||
| 99 | return per_cpu(x86_cpu_to_node_map, cpu); | 93 | return per_cpu(x86_cpu_to_node_map, cpu); |
| 100 | } | 94 | } |
| 101 | 95 | ||
| 102 | #ifdef CONFIG_NUMA | 96 | /* Same function but used if called before per_cpu areas are setup */ |
| 97 | static inline int early_cpu_to_node(int cpu) | ||
| 98 | { | ||
| 99 | if (early_per_cpu_ptr(x86_cpu_to_node_map)) | ||
| 100 | return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu]; | ||
| 101 | |||
| 102 | return per_cpu(x86_cpu_to_node_map, cpu); | ||
| 103 | } | ||
| 103 | 104 | ||
| 104 | /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ | 105 | /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ |
| 106 | static inline const cpumask_t *_node_to_cpumask_ptr(int node) | ||
| 107 | { | ||
| 108 | return &node_to_cpumask_map[node]; | ||
| 109 | } | ||
| 110 | |||
| 111 | /* Returns a bitmask of CPUs on Node 'node'. */ | ||
| 112 | static inline cpumask_t node_to_cpumask(int node) | ||
| 113 | { | ||
| 114 | return node_to_cpumask_map[node]; | ||
| 115 | } | ||
| 116 | |||
| 117 | #endif /* !CONFIG_DEBUG_PER_CPU_MAPS */ | ||
| 118 | |||
| 119 | /* Replace default node_to_cpumask_ptr with optimized version */ | ||
| 105 | #define node_to_cpumask_ptr(v, node) \ | 120 | #define node_to_cpumask_ptr(v, node) \ |
| 106 | cpumask_t *v = &(node_to_cpumask_map[node]) | 121 | const cpumask_t *v = _node_to_cpumask_ptr(node) |
| 107 | 122 | ||
| 108 | #define node_to_cpumask_ptr_next(v, node) \ | 123 | #define node_to_cpumask_ptr_next(v, node) \ |
| 109 | v = &(node_to_cpumask_map[node]) | 124 | v = _node_to_cpumask_ptr(node) |
| 110 | #endif | ||
| 111 | 125 | ||
| 112 | #endif /* CONFIG_X86_64 */ | 126 | #endif /* CONFIG_X86_64 */ |
| 113 | 127 | ||
| @@ -117,20 +131,6 @@ static inline int cpu_to_node(int cpu) | |||
| 117 | */ | 131 | */ |
| 118 | #define parent_node(node) (node) | 132 | #define parent_node(node) (node) |
| 119 | 133 | ||
| 120 | /* Returns a bitmask of CPUs on Node 'node'. */ | ||
| 121 | static inline cpumask_t node_to_cpumask(int node) | ||
| 122 | { | ||
| 123 | return node_to_cpumask_map[node]; | ||
| 124 | } | ||
| 125 | |||
| 126 | /* Returns the number of the first CPU on Node 'node'. */ | ||
| 127 | static inline int node_to_first_cpu(int node) | ||
| 128 | { | ||
| 129 | cpumask_t mask = node_to_cpumask(node); | ||
| 130 | |||
| 131 | return first_cpu(mask); | ||
| 132 | } | ||
| 133 | |||
| 134 | #define pcibus_to_node(bus) __pcibus_to_node(bus) | 134 | #define pcibus_to_node(bus) __pcibus_to_node(bus) |
| 135 | #define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus) | 135 | #define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus) |
| 136 | 136 | ||
| @@ -180,12 +180,44 @@ extern int __node_distance(int, int); | |||
| 180 | #define node_distance(a, b) __node_distance(a, b) | 180 | #define node_distance(a, b) __node_distance(a, b) |
| 181 | #endif | 181 | #endif |
| 182 | 182 | ||
| 183 | #else /* CONFIG_NUMA */ | 183 | #else /* !CONFIG_NUMA */ |
| 184 | 184 | ||
| 185 | #define numa_node_id() 0 | ||
| 186 | #define cpu_to_node(cpu) 0 | ||
| 187 | #define early_cpu_to_node(cpu) 0 | ||
| 188 | |||
| 189 | static inline const cpumask_t *_node_to_cpumask_ptr(int node) | ||
| 190 | { | ||
| 191 | return &cpu_online_map; | ||
| 192 | } | ||
| 193 | static inline cpumask_t node_to_cpumask(int node) | ||
| 194 | { | ||
| 195 | return cpu_online_map; | ||
| 196 | } | ||
| 197 | static inline int node_to_first_cpu(int node) | ||
| 198 | { | ||
| 199 | return first_cpu(cpu_online_map); | ||
| 200 | } | ||
| 201 | |||
| 202 | /* Replace default node_to_cpumask_ptr with optimized version */ | ||
| 203 | #define node_to_cpumask_ptr(v, node) \ | ||
| 204 | const cpumask_t *v = _node_to_cpumask_ptr(node) | ||
| 205 | |||
| 206 | #define node_to_cpumask_ptr_next(v, node) \ | ||
| 207 | v = _node_to_cpumask_ptr(node) | ||
| 185 | #endif | 208 | #endif |
| 186 | 209 | ||
| 187 | #include <asm-generic/topology.h> | 210 | #include <asm-generic/topology.h> |
| 188 | 211 | ||
| 212 | #ifdef CONFIG_NUMA | ||
| 213 | /* Returns the number of the first CPU on Node 'node'. */ | ||
| 214 | static inline int node_to_first_cpu(int node) | ||
| 215 | { | ||
| 216 | node_to_cpumask_ptr(mask, node); | ||
| 217 | return first_cpu(*mask); | ||
| 218 | } | ||
| 219 | #endif | ||
| 220 | |||
| 189 | extern cpumask_t cpu_coregroup_map(int cpu); | 221 | extern cpumask_t cpu_coregroup_map(int cpu); |
| 190 | 222 | ||
| 191 | #ifdef ENABLE_TOPO_DEFINES | 223 | #ifdef ENABLE_TOPO_DEFINES |
| @@ -193,6 +225,9 @@ extern cpumask_t cpu_coregroup_map(int cpu); | |||
| 193 | #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) | 225 | #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) |
| 194 | #define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu)) | 226 | #define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu)) |
| 195 | #define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) | 227 | #define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) |
| 228 | |||
| 229 | /* indicates that pointers to the topology cpumask_t maps are valid */ | ||
| 230 | #define arch_provides_topology_pointers yes | ||
| 196 | #endif | 231 | #endif |
| 197 | 232 | ||
| 198 | static inline void arch_fix_phys_package_id(int num, u32 slot) | 233 | static inline void arch_fix_phys_package_id(int num, u32 slot) |
| @@ -220,4 +255,4 @@ static inline void set_mp_bus_to_node(int busnum, int node) | |||
| 220 | } | 255 | } |
| 221 | #endif | 256 | #endif |
| 222 | 257 | ||
| 223 | #endif | 258 | #endif /* _ASM_X86_TOPOLOGY_H */ |
