diff options
Diffstat (limited to 'include/linux/cpumask.h')
-rw-r--r-- | include/linux/cpumask.h | 172 |
1 files changed, 133 insertions, 39 deletions
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index c24875bd9c5b..1b5c98e7fef7 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h | |||
@@ -17,6 +17,20 @@ | |||
17 | * For details of cpus_onto(), see bitmap_onto in lib/bitmap.c. | 17 | * For details of cpus_onto(), see bitmap_onto in lib/bitmap.c. |
18 | * For details of cpus_fold(), see bitmap_fold in lib/bitmap.c. | 18 | * For details of cpus_fold(), see bitmap_fold in lib/bitmap.c. |
19 | * | 19 | * |
20 | * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | ||
21 | * Note: The alternate operations with the suffix "_nr" are used | ||
22 | * to limit the range of the loop to nr_cpu_ids instead of | ||
23 | * NR_CPUS when NR_CPUS > 64 for performance reasons. | ||
24 | * If NR_CPUS is <= 64 then most assembler bitmask | ||
25 | * operators execute faster with a constant range, so | ||
26 | * the operator will continue to use NR_CPUS. | ||
27 | * | ||
28 | * Another consideration is that nr_cpu_ids is initialized | ||
29 | * to NR_CPUS and isn't lowered until the possible cpus are | ||
30 | * discovered (including any disabled cpus). So early uses | ||
31 | * will span the entire range of NR_CPUS. | ||
32 | * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | ||
33 | * | ||
20 | * The available cpumask operations are: | 34 | * The available cpumask operations are: |
21 | * | 35 | * |
22 | * void cpu_set(cpu, mask) turn on bit 'cpu' in mask | 36 | * void cpu_set(cpu, mask) turn on bit 'cpu' in mask |
@@ -38,18 +52,60 @@ | |||
38 | * int cpus_empty(mask) Is mask empty (no bits sets)? | 52 | * int cpus_empty(mask) Is mask empty (no bits sets)? |
39 | * int cpus_full(mask) Is mask full (all bits sets)? | 53 | * int cpus_full(mask) Is mask full (all bits sets)? |
40 | * int cpus_weight(mask) Hamming weigh - number of set bits | 54 | * int cpus_weight(mask) Hamming weigh - number of set bits |
55 | * int cpus_weight_nr(mask) Same using nr_cpu_ids instead of NR_CPUS | ||
41 | * | 56 | * |
42 | * void cpus_shift_right(dst, src, n) Shift right | 57 | * void cpus_shift_right(dst, src, n) Shift right |
43 | * void cpus_shift_left(dst, src, n) Shift left | 58 | * void cpus_shift_left(dst, src, n) Shift left |
44 | * | 59 | * |
45 | * int first_cpu(mask) Number lowest set bit, or NR_CPUS | 60 | * int first_cpu(mask) Number lowest set bit, or NR_CPUS |
46 | * int next_cpu(cpu, mask) Next cpu past 'cpu', or NR_CPUS | 61 | * int next_cpu(cpu, mask) Next cpu past 'cpu', or NR_CPUS |
62 | * int next_cpu_nr(cpu, mask) Next cpu past 'cpu', or nr_cpu_ids | ||
47 | * | 63 | * |
48 | * 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 | ||
49 | * CPU_MASK_ALL Initializer - all bits set | 74 | * CPU_MASK_ALL Initializer - all bits set |
50 | * CPU_MASK_NONE Initializer - no bits set | 75 | * CPU_MASK_NONE Initializer - no bits set |
51 | * 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 |
52 | * | 77 | * |
78 | * CPUMASK_ALLOC kmalloc's a structure that is a composite of many cpumask_t | ||
79 | * variables, and CPUMASK_PTR provides pointers to each field. | ||
80 | * | ||
81 | * The structure should be defined something like this: | ||
82 | * struct my_cpumasks { | ||
83 | * cpumask_t mask1; | ||
84 | * cpumask_t mask2; | ||
85 | * }; | ||
86 | * | ||
87 | * Usage is then: | ||
88 | * CPUMASK_ALLOC(my_cpumasks); | ||
89 | * CPUMASK_PTR(mask1, my_cpumasks); | ||
90 | * CPUMASK_PTR(mask2, my_cpumasks); | ||
91 | * | ||
92 | * --- DO NOT reference cpumask_t pointers until this check --- | ||
93 | * if (my_cpumasks == NULL) | ||
94 | * "kmalloc failed"... | ||
95 | * | ||
96 | * References are now pointers to the cpumask_t variables (*mask1, ...) | ||
97 | * | ||
98 | *if NR_CPUS > BITS_PER_LONG | ||
99 | * CPUMASK_ALLOC(m) Declares and allocates struct m *m = | ||
100 | * kmalloc(sizeof(*m), GFP_KERNEL) | ||
101 | * CPUMASK_FREE(m) Macro for kfree(m) | ||
102 | *else | ||
103 | * CPUMASK_ALLOC(m) Declares struct m _m, *m = &_m | ||
104 | * CPUMASK_FREE(m) Nop | ||
105 | *endif | ||
106 | * CPUMASK_PTR(v, m) Declares cpumask_t *v = &(m->v) | ||
107 | * ------------------------------------------------------------------------ | ||
108 | * | ||
53 | * int cpumask_scnprintf(buf, len, mask) Format cpumask for printing | 109 | * int cpumask_scnprintf(buf, len, mask) Format cpumask for printing |
54 | * int cpumask_parse_user(ubuf, ulen, mask) Parse ascii string as cpumask | 110 | * int cpumask_parse_user(ubuf, ulen, mask) Parse ascii string as cpumask |
55 | * int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing | 111 | * int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing |
@@ -59,7 +115,8 @@ | |||
59 | * void cpus_onto(dst, orig, relmap) *dst = orig relative to relmap | 115 | * void cpus_onto(dst, orig, relmap) *dst = orig relative to relmap |
60 | * void cpus_fold(dst, orig, sz) dst bits = orig bits mod sz | 116 | * void cpus_fold(dst, orig, sz) dst bits = orig bits mod sz |
61 | * | 117 | * |
62 | * for_each_cpu_mask(cpu, mask) for-loop cpu over mask | 118 | * for_each_cpu_mask(cpu, mask) for-loop cpu over mask using NR_CPUS |
119 | * for_each_cpu_mask_nr(cpu, mask) for-loop cpu over mask using nr_cpu_ids | ||
63 | * | 120 | * |
64 | * int num_online_cpus() Number of online CPUs | 121 | * int num_online_cpus() Number of online CPUs |
65 | * int num_possible_cpus() Number of all possible CPUs | 122 | * int num_possible_cpus() Number of all possible CPUs |
@@ -216,23 +273,19 @@ static inline void __cpus_shift_left(cpumask_t *dstp, | |||
216 | bitmap_shift_left(dstp->bits, srcp->bits, n, nbits); | 273 | bitmap_shift_left(dstp->bits, srcp->bits, n, nbits); |
217 | } | 274 | } |
218 | 275 | ||
219 | #ifdef CONFIG_SMP | ||
220 | int __first_cpu(const cpumask_t *srcp); | ||
221 | #define first_cpu(src) __first_cpu(&(src)) | ||
222 | int __next_cpu(int n, const cpumask_t *srcp); | ||
223 | #define next_cpu(n, src) __next_cpu((n), &(src)) | ||
224 | #else | ||
225 | #define first_cpu(src) ({ (void)(src); 0; }) | ||
226 | #define next_cpu(n, src) ({ (void)(src); 1; }) | ||
227 | #endif | ||
228 | 276 | ||
229 | #ifdef CONFIG_HAVE_CPUMASK_OF_CPU_MAP | 277 | #ifdef CONFIG_HAVE_CPUMASK_OF_CPU_MAP |
230 | extern cpumask_t *cpumask_of_cpu_map; | 278 | extern cpumask_t *cpumask_of_cpu_map; |
231 | #define cpumask_of_cpu(cpu) (cpumask_of_cpu_map[cpu]) | 279 | #define cpumask_of_cpu(cpu) (cpumask_of_cpu_map[cpu]) |
232 | 280 | #define cpumask_of_cpu_ptr(v, cpu) \ | |
281 | const cpumask_t *v = &cpumask_of_cpu(cpu) | ||
282 | #define cpumask_of_cpu_ptr_declare(v) \ | ||
283 | const cpumask_t *v | ||
284 | #define cpumask_of_cpu_ptr_next(v, cpu) \ | ||
285 | v = &cpumask_of_cpu(cpu) | ||
233 | #else | 286 | #else |
234 | #define cpumask_of_cpu(cpu) \ | 287 | #define cpumask_of_cpu(cpu) \ |
235 | (*({ \ | 288 | ({ \ |
236 | typeof(_unused_cpumask_arg_) m; \ | 289 | typeof(_unused_cpumask_arg_) m; \ |
237 | if (sizeof(m) == sizeof(unsigned long)) { \ | 290 | if (sizeof(m) == sizeof(unsigned long)) { \ |
238 | m.bits[0] = 1UL<<(cpu); \ | 291 | m.bits[0] = 1UL<<(cpu); \ |
@@ -240,8 +293,16 @@ extern cpumask_t *cpumask_of_cpu_map; | |||
240 | cpus_clear(m); \ | 293 | cpus_clear(m); \ |
241 | cpu_set((cpu), m); \ | 294 | cpu_set((cpu), m); \ |
242 | } \ | 295 | } \ |
243 | &m; \ | 296 | m; \ |
244 | })) | 297 | }) |
298 | #define cpumask_of_cpu_ptr(v, cpu) \ | ||
299 | cpumask_t _##v = cpumask_of_cpu(cpu); \ | ||
300 | const cpumask_t *v = &_##v | ||
301 | #define cpumask_of_cpu_ptr_declare(v) \ | ||
302 | cpumask_t _##v; \ | ||
303 | const cpumask_t *v = &_##v | ||
304 | #define cpumask_of_cpu_ptr_next(v, cpu) \ | ||
305 | _##v = cpumask_of_cpu(cpu) | ||
245 | #endif | 306 | #endif |
246 | 307 | ||
247 | #define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS) | 308 | #define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS) |
@@ -281,6 +342,15 @@ extern cpumask_t cpu_mask_all; | |||
281 | 342 | ||
282 | #define cpus_addr(src) ((src).bits) | 343 | #define cpus_addr(src) ((src).bits) |
283 | 344 | ||
345 | #if NR_CPUS > BITS_PER_LONG | ||
346 | #define CPUMASK_ALLOC(m) struct m *m = kmalloc(sizeof(*m), GFP_KERNEL) | ||
347 | #define CPUMASK_FREE(m) kfree(m) | ||
348 | #else | ||
349 | #define CPUMASK_ALLOC(m) struct m _m, *m = &_m | ||
350 | #define CPUMASK_FREE(m) | ||
351 | #endif | ||
352 | #define CPUMASK_PTR(v, m) cpumask_t *v = &(m->v) | ||
353 | |||
284 | #define cpumask_scnprintf(buf, len, src) \ | 354 | #define cpumask_scnprintf(buf, len, src) \ |
285 | __cpumask_scnprintf((buf), (len), &(src), NR_CPUS) | 355 | __cpumask_scnprintf((buf), (len), &(src), NR_CPUS) |
286 | static inline int __cpumask_scnprintf(char *buf, int len, | 356 | static inline int __cpumask_scnprintf(char *buf, int len, |
@@ -343,29 +413,59 @@ static inline void __cpus_fold(cpumask_t *dstp, const cpumask_t *origp, | |||
343 | bitmap_fold(dstp->bits, origp->bits, sz, nbits); | 413 | bitmap_fold(dstp->bits, origp->bits, sz, nbits); |
344 | } | 414 | } |
345 | 415 | ||
346 | #if NR_CPUS > 1 | 416 | #if NR_CPUS == 1 |
347 | #define for_each_cpu_mask(cpu, mask) \ | 417 | |
348 | for ((cpu) = first_cpu(mask); \ | 418 | #define nr_cpu_ids 1 |
349 | (cpu) < NR_CPUS; \ | 419 | #define first_cpu(src) ({ (void)(src); 0; }) |
350 | (cpu) = next_cpu((cpu), (mask))) | 420 | #define next_cpu(n, src) ({ (void)(src); 1; }) |
351 | #else /* NR_CPUS == 1 */ | 421 | #define any_online_cpu(mask) 0 |
352 | #define for_each_cpu_mask(cpu, mask) \ | 422 | #define for_each_cpu_mask(cpu, mask) \ |
353 | for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) | 423 | for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) |
354 | #endif /* NR_CPUS */ | 424 | |
425 | #else /* NR_CPUS > 1 */ | ||
426 | |||
427 | extern int nr_cpu_ids; | ||
428 | int __first_cpu(const cpumask_t *srcp); | ||
429 | int __next_cpu(int n, const cpumask_t *srcp); | ||
430 | int __any_online_cpu(const cpumask_t *mask); | ||
431 | |||
432 | #define first_cpu(src) __first_cpu(&(src)) | ||
433 | #define next_cpu(n, src) __next_cpu((n), &(src)) | ||
434 | #define any_online_cpu(mask) __any_online_cpu(&(mask)) | ||
435 | #define for_each_cpu_mask(cpu, mask) \ | ||
436 | for ((cpu) = -1; \ | ||
437 | (cpu) = next_cpu((cpu), (mask)), \ | ||
438 | (cpu) < NR_CPUS; ) | ||
439 | #endif | ||
440 | |||
441 | #if NR_CPUS <= 64 | ||
355 | 442 | ||
356 | #define next_cpu_nr(n, src) next_cpu(n, src) | 443 | #define next_cpu_nr(n, src) next_cpu(n, src) |
357 | #define cpus_weight_nr(cpumask) cpus_weight(cpumask) | 444 | #define cpus_weight_nr(cpumask) cpus_weight(cpumask) |
358 | #define for_each_cpu_mask_nr(cpu, mask) for_each_cpu_mask(cpu, mask) | 445 | #define for_each_cpu_mask_nr(cpu, mask) for_each_cpu_mask(cpu, mask) |
359 | 446 | ||
447 | #else /* NR_CPUS > 64 */ | ||
448 | |||
449 | int __next_cpu_nr(int n, const cpumask_t *srcp); | ||
450 | #define next_cpu_nr(n, src) __next_cpu_nr((n), &(src)) | ||
451 | #define cpus_weight_nr(cpumask) __cpus_weight(&(cpumask), nr_cpu_ids) | ||
452 | #define for_each_cpu_mask_nr(cpu, mask) \ | ||
453 | for ((cpu) = -1; \ | ||
454 | (cpu) = next_cpu_nr((cpu), (mask)), \ | ||
455 | (cpu) < nr_cpu_ids; ) | ||
456 | |||
457 | #endif /* NR_CPUS > 64 */ | ||
458 | |||
360 | /* | 459 | /* |
361 | * The following particular system cpumasks and operations manage | 460 | * The following particular system cpumasks and operations manage |
362 | * possible, present and online cpus. Each of them is a fixed size | 461 | * possible, present, active and online cpus. Each of them is a fixed size |
363 | * bitmap of size NR_CPUS. | 462 | * bitmap of size NR_CPUS. |
364 | * | 463 | * |
365 | * #ifdef CONFIG_HOTPLUG_CPU | 464 | * #ifdef CONFIG_HOTPLUG_CPU |
366 | * cpu_possible_map - has bit 'cpu' set iff cpu is populatable | 465 | * cpu_possible_map - has bit 'cpu' set iff cpu is populatable |
367 | * cpu_present_map - has bit 'cpu' set iff cpu is populated | 466 | * cpu_present_map - has bit 'cpu' set iff cpu is populated |
368 | * cpu_online_map - has bit 'cpu' set iff cpu available to scheduler | 467 | * cpu_online_map - has bit 'cpu' set iff cpu available to scheduler |
468 | * cpu_active_map - has bit 'cpu' set iff cpu available to migration | ||
369 | * #else | 469 | * #else |
370 | * cpu_possible_map - has bit 'cpu' set iff cpu is populated | 470 | * cpu_possible_map - has bit 'cpu' set iff cpu is populated |
371 | * cpu_present_map - copy of cpu_possible_map | 471 | * cpu_present_map - copy of cpu_possible_map |
@@ -416,14 +516,16 @@ static inline void __cpus_fold(cpumask_t *dstp, const cpumask_t *origp, | |||
416 | extern cpumask_t cpu_possible_map; | 516 | extern cpumask_t cpu_possible_map; |
417 | extern cpumask_t cpu_online_map; | 517 | extern cpumask_t cpu_online_map; |
418 | extern cpumask_t cpu_present_map; | 518 | extern cpumask_t cpu_present_map; |
519 | extern cpumask_t cpu_active_map; | ||
419 | 520 | ||
420 | #if NR_CPUS > 1 | 521 | #if NR_CPUS > 1 |
421 | #define num_online_cpus() cpus_weight(cpu_online_map) | 522 | #define num_online_cpus() cpus_weight_nr(cpu_online_map) |
422 | #define num_possible_cpus() cpus_weight(cpu_possible_map) | 523 | #define num_possible_cpus() cpus_weight_nr(cpu_possible_map) |
423 | #define num_present_cpus() cpus_weight(cpu_present_map) | 524 | #define num_present_cpus() cpus_weight_nr(cpu_present_map) |
424 | #define cpu_online(cpu) cpu_isset((cpu), cpu_online_map) | 525 | #define cpu_online(cpu) cpu_isset((cpu), cpu_online_map) |
425 | #define cpu_possible(cpu) cpu_isset((cpu), cpu_possible_map) | 526 | #define cpu_possible(cpu) cpu_isset((cpu), cpu_possible_map) |
426 | #define cpu_present(cpu) cpu_isset((cpu), cpu_present_map) | 527 | #define cpu_present(cpu) cpu_isset((cpu), cpu_present_map) |
528 | #define cpu_active(cpu) cpu_isset((cpu), cpu_active_map) | ||
427 | #else | 529 | #else |
428 | #define num_online_cpus() 1 | 530 | #define num_online_cpus() 1 |
429 | #define num_possible_cpus() 1 | 531 | #define num_possible_cpus() 1 |
@@ -431,21 +533,13 @@ extern cpumask_t cpu_present_map; | |||
431 | #define cpu_online(cpu) ((cpu) == 0) | 533 | #define cpu_online(cpu) ((cpu) == 0) |
432 | #define cpu_possible(cpu) ((cpu) == 0) | 534 | #define cpu_possible(cpu) ((cpu) == 0) |
433 | #define cpu_present(cpu) ((cpu) == 0) | 535 | #define cpu_present(cpu) ((cpu) == 0) |
536 | #define cpu_active(cpu) ((cpu) == 0) | ||
434 | #endif | 537 | #endif |
435 | 538 | ||
436 | #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) | 539 | #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) |
437 | 540 | ||
438 | #ifdef CONFIG_SMP | 541 | #define for_each_possible_cpu(cpu) for_each_cpu_mask_nr((cpu), cpu_possible_map) |
439 | extern int nr_cpu_ids; | 542 | #define for_each_online_cpu(cpu) for_each_cpu_mask_nr((cpu), cpu_online_map) |
440 | #define any_online_cpu(mask) __any_online_cpu(&(mask)) | 543 | #define for_each_present_cpu(cpu) for_each_cpu_mask_nr((cpu), cpu_present_map) |
441 | int __any_online_cpu(const cpumask_t *mask); | ||
442 | #else | ||
443 | #define nr_cpu_ids 1 | ||
444 | #define any_online_cpu(mask) 0 | ||
445 | #endif | ||
446 | |||
447 | #define for_each_possible_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map) | ||
448 | #define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map) | ||
449 | #define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map) | ||
450 | 544 | ||
451 | #endif /* __LINUX_CPUMASK_H */ | 545 | #endif /* __LINUX_CPUMASK_H */ |