aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/cpumask.h
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2008-07-15 17:14:30 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-18 16:02:57 -0400
commit65c011845316d3c1381f478ca0d8265c43b3b039 (patch)
treea7e29e92a1ad0440ef5fe16dc16d73e8bf7983d2 /include/linux/cpumask.h
parentbb2c018b09b681d43f5e08124b83e362647ea82b (diff)
cpumask: Replace cpumask_of_cpu with cpumask_of_cpu_ptr
* This patch replaces the dangerous lvalue version of cpumask_of_cpu with new cpumask_of_cpu_ptr macros. These are patterned after the node_to_cpumask_ptr macros. In general terms, if there is a cpumask_of_cpu_map[] then a pointer to the cpumask_of_cpu_map[cpu] entry is used. The cpumask_of_cpu_map is provided when there is a large NR_CPUS count, reducing greatly the amount of code generated and stack space used for cpumask_of_cpu(). The pointer to the cpumask_t value is needed for calling set_cpus_allowed_ptr() to reduce the amount of stack space needed to pass the cpumask_t value. If there isn't a cpumask_of_cpu_map[], then a temporary variable is declared and filled in with value from cpumask_of_cpu(cpu) as well as a pointer variable pointing to this temporary variable. Afterwards, the pointer is used to reference the cpumask value. The compiler will optimize out the extra dereference through the pointer as well as the stack space used for the pointer, resulting in identical code. A good example of the orthogonal usages is in net/sunrpc/svc.c: case SVC_POOL_PERCPU: { unsigned int cpu = m->pool_to[pidx]; cpumask_of_cpu_ptr(cpumask, cpu); *oldmask = current->cpus_allowed; set_cpus_allowed_ptr(current, cpumask); return 1; } case SVC_POOL_PERNODE: { unsigned int node = m->pool_to[pidx]; node_to_cpumask_ptr(nodecpumask, node); *oldmask = current->cpus_allowed; set_cpus_allowed_ptr(current, nodecpumask); return 1; } Signed-off-by: Mike Travis <travis@sgi.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux/cpumask.h')
-rw-r--r--include/linux/cpumask.h32
1 files changed, 27 insertions, 5 deletions
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 80226e776143..2dbd9a287e77 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -62,6 +62,15 @@
62 * int next_cpu_nr(cpu, mask) Next cpu past 'cpu', or nr_cpu_ids 62 * int next_cpu_nr(cpu, mask) Next cpu past 'cpu', or nr_cpu_ids
63 * 63 *
64 * cpumask_t cpumask_of_cpu(cpu) Return cpumask with bit 'cpu' set 64 * cpumask_t cpumask_of_cpu(cpu) Return cpumask with bit 'cpu' set
65 *ifdef CONFIG_HAS_CPUMASK_OF_CPU
66 * cpumask_of_cpu_ptr_declare(v) Declares cpumask_t *v
67 * cpumask_of_cpu_ptr_next(v, cpu) Sets v = &cpumask_of_cpu_map[cpu]
68 * cpumask_of_cpu_ptr(v, cpu) Combines above two operations
69 *else
70 * cpumask_of_cpu_ptr_declare(v) Declares cpumask_t _v and *v = &_v
71 * cpumask_of_cpu_ptr_next(v, cpu) Sets _v = cpumask_of_cpu(cpu)
72 * cpumask_of_cpu_ptr(v, cpu) Combines above two operations
73 *endif
65 * CPU_MASK_ALL Initializer - all bits set 74 * CPU_MASK_ALL Initializer - all bits set
66 * CPU_MASK_NONE Initializer - no bits set 75 * CPU_MASK_NONE Initializer - no bits set
67 * unsigned long *cpus_addr(mask) Array of unsigned long's in mask 76 * unsigned long *cpus_addr(mask) Array of unsigned long's in mask
@@ -236,11 +245,16 @@ static inline void __cpus_shift_left(cpumask_t *dstp,
236 245
237#ifdef CONFIG_HAVE_CPUMASK_OF_CPU_MAP 246#ifdef CONFIG_HAVE_CPUMASK_OF_CPU_MAP
238extern cpumask_t *cpumask_of_cpu_map; 247extern cpumask_t *cpumask_of_cpu_map;
239#define cpumask_of_cpu(cpu) (cpumask_of_cpu_map[cpu]) 248#define cpumask_of_cpu(cpu) (cpumask_of_cpu_map[cpu])
240 249#define cpumask_of_cpu_ptr(v, cpu) \
250 const cpumask_t *v = &cpumask_of_cpu(cpu)
251#define cpumask_of_cpu_ptr_declare(v) \
252 const cpumask_t *v
253#define cpumask_of_cpu_ptr_next(v, cpu) \
254 v = &cpumask_of_cpu(cpu)
241#else 255#else
242#define cpumask_of_cpu(cpu) \ 256#define cpumask_of_cpu(cpu) \
243(*({ \ 257({ \
244 typeof(_unused_cpumask_arg_) m; \ 258 typeof(_unused_cpumask_arg_) m; \
245 if (sizeof(m) == sizeof(unsigned long)) { \ 259 if (sizeof(m) == sizeof(unsigned long)) { \
246 m.bits[0] = 1UL<<(cpu); \ 260 m.bits[0] = 1UL<<(cpu); \
@@ -248,8 +262,16 @@ extern cpumask_t *cpumask_of_cpu_map;
248 cpus_clear(m); \ 262 cpus_clear(m); \
249 cpu_set((cpu), m); \ 263 cpu_set((cpu), m); \
250 } \ 264 } \
251 &m; \ 265 m; \
252})) 266})
267#define cpumask_of_cpu_ptr(v, cpu) \
268 cpumask_t _##v = cpumask_of_cpu(cpu); \
269 const cpumask_t *v = &_##v
270#define cpumask_of_cpu_ptr_declare(v) \
271 cpumask_t _##v; \
272 const cpumask_t *v = &_##v
273#define cpumask_of_cpu_ptr_next(v, cpu) \
274 _##v = cpumask_of_cpu(cpu)
253#endif 275#endif
254 276
255#define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS) 277#define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS)