diff options
Diffstat (limited to 'lib/cpumask.c')
| -rw-r--r-- | lib/cpumask.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/lib/cpumask.c b/lib/cpumask.c index 5f97dc25ef9c..8d03f22c6ced 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #include <linux/bitops.h> | 2 | #include <linux/bitops.h> |
| 3 | #include <linux/cpumask.h> | 3 | #include <linux/cpumask.h> |
| 4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
| 5 | #include <linux/bootmem.h> | ||
| 5 | 6 | ||
| 6 | int __first_cpu(const cpumask_t *srcp) | 7 | int __first_cpu(const cpumask_t *srcp) |
| 7 | { | 8 | { |
| @@ -35,3 +36,81 @@ int __any_online_cpu(const cpumask_t *mask) | |||
| 35 | return cpu; | 36 | return cpu; |
| 36 | } | 37 | } |
| 37 | EXPORT_SYMBOL(__any_online_cpu); | 38 | EXPORT_SYMBOL(__any_online_cpu); |
| 39 | |||
| 40 | /** | ||
| 41 | * cpumask_next_and - get the next cpu in *src1p & *src2p | ||
| 42 | * @n: the cpu prior to the place to search (ie. return will be > @n) | ||
| 43 | * @src1p: the first cpumask pointer | ||
| 44 | * @src2p: the second cpumask pointer | ||
| 45 | * | ||
| 46 | * Returns >= nr_cpu_ids if no further cpus set in both. | ||
| 47 | */ | ||
| 48 | int cpumask_next_and(int n, const struct cpumask *src1p, | ||
| 49 | const struct cpumask *src2p) | ||
| 50 | { | ||
| 51 | while ((n = cpumask_next(n, src1p)) < nr_cpu_ids) | ||
| 52 | if (cpumask_test_cpu(n, src2p)) | ||
| 53 | break; | ||
| 54 | return n; | ||
| 55 | } | ||
| 56 | EXPORT_SYMBOL(cpumask_next_and); | ||
| 57 | |||
| 58 | /** | ||
| 59 | * cpumask_any_but - return a "random" in a cpumask, but not this one. | ||
| 60 | * @mask: the cpumask to search | ||
| 61 | * @cpu: the cpu to ignore. | ||
| 62 | * | ||
| 63 | * Often used to find any cpu but smp_processor_id() in a mask. | ||
| 64 | * Returns >= nr_cpu_ids if no cpus set. | ||
| 65 | */ | ||
| 66 | int cpumask_any_but(const struct cpumask *mask, unsigned int cpu) | ||
| 67 | { | ||
| 68 | unsigned int i; | ||
| 69 | |||
| 70 | cpumask_check(cpu); | ||
| 71 | for_each_cpu(i, mask) | ||
| 72 | if (i != cpu) | ||
| 73 | break; | ||
| 74 | return i; | ||
| 75 | } | ||
| 76 | |||
| 77 | /* These are not inline because of header tangles. */ | ||
| 78 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
| 79 | bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) | ||
| 80 | { | ||
| 81 | if (likely(slab_is_available())) | ||
| 82 | *mask = kmalloc(cpumask_size(), flags); | ||
| 83 | else { | ||
| 84 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | ||
| 85 | printk(KERN_ERR | ||
| 86 | "=> alloc_cpumask_var: kmalloc not available!\n"); | ||
| 87 | dump_stack(); | ||
| 88 | #endif | ||
| 89 | *mask = NULL; | ||
| 90 | } | ||
| 91 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | ||
| 92 | if (!*mask) { | ||
| 93 | printk(KERN_ERR "=> alloc_cpumask_var: failed!\n"); | ||
| 94 | dump_stack(); | ||
| 95 | } | ||
| 96 | #endif | ||
| 97 | return *mask != NULL; | ||
| 98 | } | ||
| 99 | EXPORT_SYMBOL(alloc_cpumask_var); | ||
| 100 | |||
| 101 | void __init alloc_bootmem_cpumask_var(cpumask_var_t *mask) | ||
| 102 | { | ||
| 103 | *mask = alloc_bootmem(cpumask_size()); | ||
| 104 | } | ||
| 105 | |||
| 106 | void free_cpumask_var(cpumask_var_t mask) | ||
| 107 | { | ||
| 108 | kfree(mask); | ||
| 109 | } | ||
| 110 | EXPORT_SYMBOL(free_cpumask_var); | ||
| 111 | |||
| 112 | void __init free_bootmem_cpumask_var(cpumask_var_t mask) | ||
| 113 | { | ||
| 114 | free_bootmem((unsigned long)mask, cpumask_size()); | ||
| 115 | } | ||
| 116 | #endif | ||
