Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+3 −38
Original line number Diff line number Diff line
@@ -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)

+109 −0
Original line number Diff line number Diff line
@@ -461,3 +461,112 @@ out:
#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 */