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: Mike Travis <travis@sgi.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jack Steiner <steiner@sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Mike Travis 2008-07-24 18:21:29 -07:00 committed by Ingo Molnar
parent 024e8ac044
commit b8d317d10c
2 changed files with 112 additions and 38 deletions

View File

@ -62,15 +62,7 @@
* 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
*ifdef CONFIG_HAS_CPUMASK_OF_CPU
* 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
* (can be used as an lvalue)
* CPU_MASK_ALL Initializer - all bits set
* CPU_MASK_NONE Initializer - no bits set
* 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,
}
#ifdef CONFIG_HAVE_CPUMASK_OF_CPU_MAP
extern cpumask_t *cpumask_of_cpu_map;
/* cpumask_of_cpu_map[] is in kernel/cpu.c */
extern const cpumask_t *cpumask_of_cpu_map;
#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)

View File

@ -461,3 +461,112 @@ void __ref enable_nonboot_cpus(void)
#endif /* CONFIG_PM_SLEEP_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 */