aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig3
-rw-r--r--arch/x86/kernel/setup.c28
-rw-r--r--include/linux/cpumask.h12
3 files changed, 39 insertions, 4 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2a59dbb28248..7f30b754bfc3 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -117,6 +117,9 @@ config ARCH_HAS_CPU_RELAX
117config HAVE_SETUP_PER_CPU_AREA 117config HAVE_SETUP_PER_CPU_AREA
118 def_bool X86_64 || (X86_SMP && !X86_VOYAGER) 118 def_bool X86_64 || (X86_SMP && !X86_VOYAGER)
119 119
120config HAVE_CPUMASK_OF_CPU_MAP
121 def_bool X86_64_SMP
122
120config ARCH_HIBERNATION_POSSIBLE 123config ARCH_HIBERNATION_POSSIBLE
121 def_bool y 124 def_bool y
122 depends on !SMP || !X86_VOYAGER 125 depends on !SMP || !X86_VOYAGER
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index ed157c90412e..0d1f44ae6eea 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -54,6 +54,24 @@ static void __init setup_per_cpu_maps(void)
54#endif 54#endif
55} 55}
56 56
57#ifdef CONFIG_HAVE_CPUMASK_OF_CPU_MAP
58cpumask_t *cpumask_of_cpu_map __read_mostly;
59EXPORT_SYMBOL(cpumask_of_cpu_map);
60
61/* requires nr_cpu_ids to be initialized */
62static void __init setup_cpumask_of_cpu(void)
63{
64 int i;
65
66 /* alloc_bootmem zeroes memory */
67 cpumask_of_cpu_map = alloc_bootmem_low(sizeof(cpumask_t) * nr_cpu_ids);
68 for (i = 0; i < nr_cpu_ids; i++)
69 cpu_set(i, cpumask_of_cpu_map[i]);
70}
71#else
72static inline void setup_cpumask_of_cpu(void) { }
73#endif
74
57#ifdef CONFIG_X86_32 75#ifdef CONFIG_X86_32
58/* 76/*
59 * Great future not-so-futuristic plan: make i386 and x86_64 do it 77 * Great future not-so-futuristic plan: make i386 and x86_64 do it
@@ -70,7 +88,7 @@ EXPORT_SYMBOL(__per_cpu_offset);
70 */ 88 */
71void __init setup_per_cpu_areas(void) 89void __init setup_per_cpu_areas(void)
72{ 90{
73 int i; 91 int i, highest_cpu = 0;
74 unsigned long size; 92 unsigned long size;
75 93
76#ifdef CONFIG_HOTPLUG_CPU 94#ifdef CONFIG_HOTPLUG_CPU
@@ -104,10 +122,18 @@ void __init setup_per_cpu_areas(void)
104 __per_cpu_offset[i] = ptr - __per_cpu_start; 122 __per_cpu_offset[i] = ptr - __per_cpu_start;
105#endif 123#endif
106 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); 124 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
125
126 highest_cpu = i;
107 } 127 }
108 128
129 nr_cpu_ids = highest_cpu + 1;
130 printk(KERN_DEBUG "NR_CPUS: %d, nr_cpu_ids: %d\n", NR_CPUS, nr_cpu_ids);
131
109 /* Setup percpu data maps */ 132 /* Setup percpu data maps */
110 setup_per_cpu_maps(); 133 setup_per_cpu_maps();
134
135 /* Setup cpumask_of_cpu map */
136 setup_cpumask_of_cpu();
111} 137}
112 138
113#endif 139#endif
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 629102feaa66..259c8051155d 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -222,8 +222,13 @@ int __next_cpu(int n, const cpumask_t *srcp);
222#define next_cpu(n, src) ({ (void)(src); 1; }) 222#define next_cpu(n, src) ({ (void)(src); 1; })
223#endif 223#endif
224 224
225#ifdef CONFIG_HAVE_CPUMASK_OF_CPU_MAP
226extern cpumask_t *cpumask_of_cpu_map;
227#define cpumask_of_cpu(cpu) (cpumask_of_cpu_map[cpu])
228
229#else
225#define cpumask_of_cpu(cpu) \ 230#define cpumask_of_cpu(cpu) \
226({ \ 231(*({ \
227 typeof(_unused_cpumask_arg_) m; \ 232 typeof(_unused_cpumask_arg_) m; \
228 if (sizeof(m) == sizeof(unsigned long)) { \ 233 if (sizeof(m) == sizeof(unsigned long)) { \
229 m.bits[0] = 1UL<<(cpu); \ 234 m.bits[0] = 1UL<<(cpu); \
@@ -231,8 +236,9 @@ int __next_cpu(int n, const cpumask_t *srcp);
231 cpus_clear(m); \ 236 cpus_clear(m); \
232 cpu_set((cpu), m); \ 237 cpu_set((cpu), m); \
233 } \ 238 } \
234 m; \ 239 &m; \
235}) 240}))
241#endif
236 242
237#define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS) 243#define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS)
238 244