Commit b8d317d1 authored by Mike Travis's avatar Mike Travis Committed by Ingo Molnar

cpumask: make cpumask_of_cpu_map generic

If an arch doesn't define cpumask_of_cpu_map, create a generic
statically-initialized one for them.  This allows removal of the buggy
cpumask_of_cpu() macro (&cpumask_of_cpu() gives address of
out-of-scope var).

An arch with NR_CPUS of 4096 probably wants to allocate this itself
based on the actual number of CPUs, since otherwise they're using 2MB
of rodata (1024 cpus means 128k).  That's what
CONFIG_HAVE_CPUMASK_OF_CPU_MAP is for (only x86/64 does so at the
moment).

In future as we support more CPUs, we'll need to resort to a
get_cpu_map()/put_cpu_map() allocation scheme.
Signed-off-by: default avatarMike Travis <travis@sgi.com>
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jack Steiner <steiner@sgi.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 024e8ac0
...@@ -62,15 +62,7 @@ ...@@ -62,15 +62,7 @@
* int next_cpu_nr(cpu, mask) Next cpu past 'cpu', or nr_cpu_ids * int next_cpu_nr(cpu, mask) Next cpu past 'cpu', or nr_cpu_ids
* *
* cpumask_t cpumask_of_cpu(cpu) Return cpumask with bit 'cpu' set * cpumask_t cpumask_of_cpu(cpu) Return cpumask with bit 'cpu' set
*ifdef CONFIG_HAS_CPUMASK_OF_CPU * (can be used as an lvalue)
* cpumask_of_cpu_ptr_declare(v) Declares cpumask_t *v
* cpumask_of_cpu_ptr_next(v, cpu) Sets v = &cpumask_of_cpu_map[cpu]
* cpumask_of_cpu_ptr(v, cpu) Combines above two operations
*else
* cpumask_of_cpu_ptr_declare(v) Declares cpumask_t _v and *v = &_v
* cpumask_of_cpu_ptr_next(v, cpu) Sets _v = cpumask_of_cpu(cpu)
* cpumask_of_cpu_ptr(v, cpu) Combines above two operations
*endif
* CPU_MASK_ALL Initializer - all bits set * CPU_MASK_ALL Initializer - all bits set
* CPU_MASK_NONE Initializer - no bits set * CPU_MASK_NONE Initializer - no bits set
* unsigned long *cpus_addr(mask) Array of unsigned long's in mask * unsigned long *cpus_addr(mask) Array of unsigned long's in mask
...@@ -274,36 +266,9 @@ static inline void __cpus_shift_left(cpumask_t *dstp, ...@@ -274,36 +266,9 @@ static inline void __cpus_shift_left(cpumask_t *dstp,
} }
#ifdef CONFIG_HAVE_CPUMASK_OF_CPU_MAP /* cpumask_of_cpu_map[] is in kernel/cpu.c */
extern cpumask_t *cpumask_of_cpu_map; extern const cpumask_t *cpumask_of_cpu_map;
#define cpumask_of_cpu(cpu) (cpumask_of_cpu_map[cpu]) #define cpumask_of_cpu(cpu) (cpumask_of_cpu_map[cpu])
#define cpumask_of_cpu_ptr(v, cpu) \
const cpumask_t *v = &cpumask_of_cpu(cpu)
#define cpumask_of_cpu_ptr_declare(v) \
const cpumask_t *v
#define cpumask_of_cpu_ptr_next(v, cpu) \
v = &cpumask_of_cpu(cpu)
#else
#define cpumask_of_cpu(cpu) \
({ \
typeof(_unused_cpumask_arg_) m; \
if (sizeof(m) == sizeof(unsigned long)) { \
m.bits[0] = 1UL<<(cpu); \
} else { \
cpus_clear(m); \
cpu_set((cpu), m); \
} \
m; \
})
#define cpumask_of_cpu_ptr(v, cpu) \
cpumask_t _##v = cpumask_of_cpu(cpu); \
const cpumask_t *v = &_##v
#define cpumask_of_cpu_ptr_declare(v) \
cpumask_t _##v; \
const cpumask_t *v = &_##v
#define cpumask_of_cpu_ptr_next(v, cpu) \
_##v = cpumask_of_cpu(cpu)
#endif
#define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS) #define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS)
......
...@@ -461,3 +461,112 @@ void __ref enable_nonboot_cpus(void) ...@@ -461,3 +461,112 @@ void __ref enable_nonboot_cpus(void)
#endif /* CONFIG_PM_SLEEP_SMP */ #endif /* CONFIG_PM_SLEEP_SMP */
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
#ifndef CONFIG_HAVE_CPUMASK_OF_CPU_MAP
/* 64 bits of zeros, for initializers. */
#if BITS_PER_LONG == 32
#define Z64 0, 0
#else
#define Z64 0
#endif
/* Initializer macros. */
#define CMI0(n) { .bits = { 1UL << (n) } }
#define CMI(n, ...) { .bits = { __VA_ARGS__, 1UL << ((n) % BITS_PER_LONG) } }
#define CMI8(n, ...) \
CMI((n), __VA_ARGS__), CMI((n)+1, __VA_ARGS__), \
CMI((n)+2, __VA_ARGS__), CMI((n)+3, __VA_ARGS__), \
CMI((n)+4, __VA_ARGS__), CMI((n)+5, __VA_ARGS__), \
CMI((n)+6, __VA_ARGS__), CMI((n)+7, __VA_ARGS__)
#if BITS_PER_LONG == 32
#define CMI64(n, ...) \
CMI8((n), __VA_ARGS__), CMI8((n)+8, __VA_ARGS__), \
CMI8((n)+16, __VA_ARGS__), CMI8((n)+24, __VA_ARGS__), \
CMI8((n)+32, 0, __VA_ARGS__), CMI8((n)+40, 0, __VA_ARGS__), \
CMI8((n)+48, 0, __VA_ARGS__), CMI8((n)+56, 0, __VA_ARGS__)
#else
#define CMI64(n, ...) \
CMI8((n), __VA_ARGS__), CMI8((n)+8, __VA_ARGS__), \
CMI8((n)+16, __VA_ARGS__), CMI8((n)+24, __VA_ARGS__), \
CMI8((n)+32, __VA_ARGS__), CMI8((n)+40, __VA_ARGS__), \
CMI8((n)+48, __VA_ARGS__), CMI8((n)+56, __VA_ARGS__)
#endif
#define CMI256(n, ...) \
CMI64((n), __VA_ARGS__), CMI64((n)+64, Z64, __VA_ARGS__), \
CMI64((n)+128, Z64, Z64, __VA_ARGS__), \
CMI64((n)+192, Z64, Z64, Z64, __VA_ARGS__)
#define Z256 Z64, Z64, Z64, Z64
#define CMI1024(n, ...) \
CMI256((n), __VA_ARGS__), \
CMI256((n)+256, Z256, __VA_ARGS__), \
CMI256((n)+512, Z256, Z256, __VA_ARGS__), \
CMI256((n)+768, Z256, Z256, Z256, __VA_ARGS__)
#define Z1024 Z256, Z256, Z256, Z256
/* We want this statically initialized, just to be safe. We try not
* to waste too much space, either. */
static const cpumask_t cpumask_map[] = {
CMI0(0), CMI0(1), CMI0(2), CMI0(3),
#if NR_CPUS > 4
CMI0(4), CMI0(5), CMI0(6), CMI0(7),
#endif
#if NR_CPUS > 8
CMI0(8), CMI0(9), CMI0(10), CMI0(11),
CMI0(12), CMI0(13), CMI0(14), CMI0(15),
#endif
#if NR_CPUS > 16
CMI0(16), CMI0(17), CMI0(18), CMI0(19),
CMI0(20), CMI0(21), CMI0(22), CMI0(23),
CMI0(24), CMI0(25), CMI0(26), CMI0(27),
CMI0(28), CMI0(29), CMI0(30), CMI0(31),
#endif
#if NR_CPUS > 32
#if BITS_PER_LONG == 32
CMI(32, 0), CMI(33, 0), CMI(34, 0), CMI(35, 0),
CMI(36, 0), CMI(37, 0), CMI(38, 0), CMI(39, 0),
CMI(40, 0), CMI(41, 0), CMI(42, 0), CMI(43, 0),
CMI(44, 0), CMI(45, 0), CMI(46, 0), CMI(47, 0),
CMI(48, 0), CMI(49, 0), CMI(50, 0), CMI(51, 0),
CMI(52, 0), CMI(53, 0), CMI(54, 0), CMI(55, 0),
CMI(56, 0), CMI(57, 0), CMI(58, 0), CMI(59, 0),
CMI(60, 0), CMI(61, 0), CMI(62, 0), CMI(63, 0),
#else
CMI0(32), CMI0(33), CMI0(34), CMI0(35),
CMI0(36), CMI0(37), CMI0(38), CMI0(39),
CMI0(40), CMI0(41), CMI0(42), CMI0(43),
CMI0(44), CMI0(45), CMI0(46), CMI0(47),
CMI0(48), CMI0(49), CMI0(50), CMI0(51),
CMI0(52), CMI0(53), CMI0(54), CMI0(55),
CMI0(56), CMI0(57), CMI0(58), CMI0(59),
CMI0(60), CMI0(61), CMI0(62), CMI0(63),
#endif /* BITS_PER_LONG == 64 */
#endif
#if NR_CPUS > 64
CMI64(64, Z64),
#endif
#if NR_CPUS > 128
CMI64(128, Z64, Z64), CMI64(192, Z64, Z64, Z64),
#endif
#if NR_CPUS > 256
CMI256(256, Z256),
#endif
#if NR_CPUS > 512
CMI256(512, Z256, Z256), CMI256(768, Z256, Z256, Z256),
#endif
#if NR_CPUS > 1024
CMI1024(1024, Z1024),
#endif
#if NR_CPUS > 2048
CMI1024(2048, Z1024, Z1024), CMI1024(3072, Z1024, Z1024, Z1024),
#endif
#if NR_CPUS > 4096
#error NR_CPUS too big. Fix initializers or set CONFIG_HAVE_CPUMASK_OF_CPU_MAP
#endif
};
const cpumask_t *cpumask_of_cpu_map = cpumask_map;
#endif /* !CONFIG_HAVE_CPUMASK_OF_CPU_MAP */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment