aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-11-04 21:39:10 -0500
committerIngo Molnar <mingo@elte.hu>2008-11-06 03:05:33 -0500
commit2d3854a37e8b767a51aba38ed6d22817b0631e33 (patch)
tree3b55cc93720b2e525460216b196ed20298ae985b /lib
parent75fa67706cce5272bcfc51ed646f2da21f3bdb6e (diff)
cpumask: introduce new API, without changing anything
Impact: introduce new APIs We want to deprecate cpumasks on the stack, as we are headed for gynormous numbers of CPUs. Eventually, we want to head towards an undefined 'struct cpumask' so they can never be declared on stack. 1) New cpumask functions which take pointers instead of copies. (cpus_* -> cpumask_*) 2) Several new helpers to reduce requirements for temporary cpumasks (cpumask_first_and, cpumask_next_and, cpumask_any_and) 3) Helpers for declaring cpumasks on or offstack for large NR_CPUS (cpumask_var_t, alloc_cpumask_var and free_cpumask_var) 4) 'struct cpumask' for explicitness and to mark new-style code. 5) Make iterator functions stop at nr_cpu_ids (a runtime constant), not NR_CPUS for time efficiency and for smaller dynamic allocations in future. 6) cpumask_copy() so we can allocate less than a full cpumask eventually (for alloc_cpumask_var), and so we can eliminate the 'struct cpumask' definition eventually. 7) work_on_cpu() helper for doing task on a CPU, rather than saving old cpumask for current thread and manipulating it. 8) smp_call_function_many() which is smp_call_function_mask() except taking a cpumask pointer. Note that this patch simply introduces the new functions and leaves the obsolescent ones in place. This is to simplify the transition patches. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'lib')
-rw-r--r--lib/cpumask.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 5f97dc25ef9..5ceb4211c83 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
6int __first_cpu(const cpumask_t *srcp) 7int __first_cpu(const cpumask_t *srcp)
7{ 8{
@@ -35,3 +36,75 @@ int __any_online_cpu(const cpumask_t *mask)
35 return cpu; 36 return cpu;
36} 37}
37EXPORT_SYMBOL(__any_online_cpu); 38EXPORT_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 */
48int 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}
56EXPORT_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 */
66int cpumask_any_but(const struct cpumask *mask, unsigned int cpu)
67{
68 unsigned int i;
69
70 for_each_cpu(i, mask)
71 if (i != cpu)
72 break;
73 return i;
74}
75
76/* These are not inline because of header tangles. */
77#ifdef CONFIG_CPUMASK_OFFSTACK
78bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags)
79{
80 if (likely(slab_is_available()))
81 *mask = kmalloc(cpumask_size(), flags);
82 else {
83#ifdef CONFIG_DEBUG_PER_CPU_MAPS
84 printk(KERN_ERR
85 "=> alloc_cpumask_var: kmalloc not available!\n");
86 dump_stack();
87#endif
88 *mask = NULL;
89 }
90#ifdef CONFIG_DEBUG_PER_CPU_MAPS
91 if (!*mask) {
92 printk(KERN_ERR "=> alloc_cpumask_var: failed!\n");
93 dump_stack();
94 }
95#endif
96 return *mask != NULL;
97}
98EXPORT_SYMBOL(alloc_cpumask_var);
99
100void __init alloc_bootmem_cpumask_var(cpumask_var_t *mask)
101{
102 *mask = alloc_bootmem(cpumask_size());
103}
104
105void free_cpumask_var(cpumask_var_t mask)
106{
107 kfree(mask);
108}
109EXPORT_SYMBOL(free_cpumask_var);
110#endif