Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / include / lwk / cpumask.h
1 #ifndef _LWK_CPUMASK_H
2 #define _LWK_CPUMASK_H
3
4 /*
5  * Cpumasks provide a bitmap suitable for representing the
6  * set of CPU's in a system, one bit position per CPU number.
7  *
8  * See detailed comments in the file linux/bitmap.h describing the
9  * data type on which these cpumasks are based.
10  *
11  * For details of cpumask_scnprintf() and cpumask_parse(),
12  * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
13  * For details of cpulist_scnprintf() and cpulist_parse(), see
14  * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
15  * For details of cpu_remap(), see bitmap_bitremap in lib/bitmap.c
16  * For details of cpus_remap(), see bitmap_remap in lib/bitmap.c.
17  *
18  * The available cpumask operations are:
19  *
20  * void cpu_set(cpu, mask)              turn on bit 'cpu' in mask
21  * void cpu_clear(cpu, mask)            turn off bit 'cpu' in mask
22  * void cpus_setall(mask)               set all bits
23  * void cpus_clear(mask)                clear all bits
24  * int cpu_isset(cpu, mask)             true iff bit 'cpu' set in mask
25  * int cpu_test_and_set(cpu, mask)      test and set bit 'cpu' in mask
26  *
27  * void cpus_and(dst, src1, src2)       dst = src1 & src2  [intersection]
28  * void cpus_or(dst, src1, src2)        dst = src1 | src2  [union]
29  * void cpus_xor(dst, src1, src2)       dst = src1 ^ src2
30  * void cpus_andnot(dst, src1, src2)    dst = src1 & ~src2
31  * void cpus_complement(dst, src)       dst = ~src
32  *
33  * int cpus_equal(mask1, mask2)         Does mask1 == mask2?
34  * int cpus_intersects(mask1, mask2)    Do mask1 and mask2 intersect?
35  * int cpus_subset(mask1, mask2)        Is mask1 a subset of mask2?
36  * int cpus_empty(mask)                 Is mask empty (no bits sets)?
37  * int cpus_full(mask)                  Is mask full (all bits sets)?
38  * int cpus_weight(mask)                Hamming weigh - number of set bits
39  *
40  * void cpus_shift_right(dst, src, n)   Shift right
41  * void cpus_shift_left(dst, src, n)    Shift left
42  *
43  * int first_cpu(mask)                  Number lowest set bit, or NR_CPUS
44  * int next_cpu(cpu, mask)              Next cpu past 'cpu', or NR_CPUS
45  *
46  * cpumask_t cpumask_of_cpu(cpu)        Return cpumask with bit 'cpu' set
47  * CPU_MASK_ALL                         Initializer - all bits set
48  * CPU_MASK_NONE                        Initializer - no bits set
49  * unsigned long *cpus_addr(mask)       Array of unsigned long's in mask
50  *
51  * int cpumask_scnprintf(buf, len, mask) Format cpumask for printing
52  * int cpumask_parse(ubuf, ulen, mask)  Parse ascii string as cpumask
53  * int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing
54  * int cpulist_parse(buf, map)          Parse ascii string as cpulist
55  * int cpu_remap(oldbit, old, new)      newbit = map(old, new)(oldbit)
56  * int cpus_remap(dst, src, old, new)   *dst = map(old, new)(src)
57  *
58  * for_each_cpu_mask(cpu, mask)         for-loop cpu over mask
59  *
60  * int num_online_cpus()                Number of online CPUs
61  * int num_possible_cpus()              Number of all possible CPUs
62  * int num_present_cpus()               Number of present CPUs
63  *
64  * int cpu_online(cpu)                  Is some cpu online?
65  * int cpu_possible(cpu)                Is some cpu possible?
66  * int cpu_present(cpu)                 Is some cpu present (can schedule)?
67  *
68  * int any_online_cpu(mask)             First online cpu in mask
69  *
70  * for_each_possible_cpu(cpu)           for-loop cpu over cpu_possible_map
71  * for_each_online_cpu(cpu)             for-loop cpu over cpu_online_map
72  * for_each_present_cpu(cpu)            for-loop cpu over cpu_present_map
73  *
74  * Subtlety:
75  * 1) The 'type-checked' form of cpu_isset() causes gcc (3.3.2, anyway)
76  *    to generate slightly worse code.  Note for example the additional
77  *    40 lines of assembly code compiling the "for each possible cpu"
78  *    loops buried in the disk_stat_read() macros calls when compiling
79  *    drivers/block/genhd.c (arch i386, CONFIG_SMP=y).  So use a simple
80  *    one-line #define for cpu_isset(), instead of wrapping an inline
81  *    inside a macro, the way we do the other calls.
82  */
83
84 /**
85  * Fixed size cpumask structure for user-space.
86  * As long as CPU_MAX_ID >= NR_CPUS, we're good to go... 
87  * otherwise we need to bump up CPU_MAX_ID and therefore break
88  * user-level binary compatibility, causing a flag day.
89  */
90
91 #define CPU_MIN_ID 0
92 #define CPU_MAX_ID 2047
93 typedef struct {
94         unsigned long bits[(CPU_MAX_ID+1)/(sizeof(unsigned long) * 8)];
95 } user_cpumask_t;
96
97 #ifdef __KERNEL__
98
99 #include <lwk/kernel.h>
100 #include <lwk/bitmap.h>
101 #include <lwk/cpu.h>
102
103 #if (CPU_MAX_ID + 1 < NR_CPUS)
104 #error "NR_CPUS must be <= CPU_MAX_ID"
105 #endif
106
107 typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
108 extern cpumask_t _unused_cpumask_arg_;
109
110 static inline void
111 cpumask_kernel2user(const cpumask_t *kernel, user_cpumask_t *user)
112 {
113         memset(user, 0, sizeof(user_cpumask_t));
114         memcpy(user, kernel, sizeof(*kernel));
115 }
116
117 static inline void
118 cpumask_user2kernel(const user_cpumask_t *user, cpumask_t *kernel)
119 {
120         memcpy(kernel, user, sizeof(*kernel));
121 }
122
123 #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
124 static inline void __cpu_set(int cpu, volatile cpumask_t *dstp)
125 {
126         set_bit(cpu, dstp->bits);
127 }
128
129 #define cpu_clear(cpu, dst) __cpu_clear((cpu), &(dst))
130 static inline void __cpu_clear(int cpu, volatile cpumask_t *dstp)
131 {
132         clear_bit(cpu, dstp->bits);
133 }
134
135 #define cpus_setall(dst) __cpus_setall(&(dst), NR_CPUS)
136 static inline void __cpus_setall(cpumask_t *dstp, int nbits)
137 {
138         bitmap_fill(dstp->bits, nbits);
139 }
140
141 #define cpus_clear(dst) __cpus_clear(&(dst), NR_CPUS)
142 static inline void __cpus_clear(cpumask_t *dstp, int nbits)
143 {
144         bitmap_zero(dstp->bits, nbits);
145 }
146
147 /* No static inline type checking - see Subtlety (1) above. */
148 #define cpu_isset(cpu, cpumask) test_bit((cpu), (cpumask).bits)
149
150 #define cpu_test_and_set(cpu, cpumask) __cpu_test_and_set((cpu), &(cpumask))
151 static inline int __cpu_test_and_set(int cpu, cpumask_t *addr)
152 {
153         return test_and_set_bit(cpu, addr->bits);
154 }
155
156 #define cpus_and(dst, src1, src2) __cpus_and(&(dst), &(src1), &(src2), NR_CPUS)
157 static inline void __cpus_and(cpumask_t *dstp, const cpumask_t *src1p,
158                                         const cpumask_t *src2p, int nbits)
159 {
160         bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits);
161 }
162
163 #define cpus_or(dst, src1, src2) __cpus_or(&(dst), &(src1), &(src2), NR_CPUS)
164 static inline void __cpus_or(cpumask_t *dstp, const cpumask_t *src1p,
165                                         const cpumask_t *src2p, int nbits)
166 {
167         bitmap_or(dstp->bits, src1p->bits, src2p->bits, nbits);
168 }
169
170 #define cpus_xor(dst, src1, src2) __cpus_xor(&(dst), &(src1), &(src2), NR_CPUS)
171 static inline void __cpus_xor(cpumask_t *dstp, const cpumask_t *src1p,
172                                         const cpumask_t *src2p, int nbits)
173 {
174         bitmap_xor(dstp->bits, src1p->bits, src2p->bits, nbits);
175 }
176
177 #define cpus_andnot(dst, src1, src2) \
178                                 __cpus_andnot(&(dst), &(src1), &(src2), NR_CPUS)
179 static inline void __cpus_andnot(cpumask_t *dstp, const cpumask_t *src1p,
180                                         const cpumask_t *src2p, int nbits)
181 {
182         bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits);
183 }
184
185 #define cpus_complement(dst, src) __cpus_complement(&(dst), &(src), NR_CPUS)
186 static inline void __cpus_complement(cpumask_t *dstp,
187                                         const cpumask_t *srcp, int nbits)
188 {
189         bitmap_complement(dstp->bits, srcp->bits, nbits);
190 }
191
192 #define cpus_equal(src1, src2) __cpus_equal(&(src1), &(src2), NR_CPUS)
193 static inline int __cpus_equal(const cpumask_t *src1p,
194                                         const cpumask_t *src2p, int nbits)
195 {
196         return bitmap_equal(src1p->bits, src2p->bits, nbits);
197 }
198
199 #define cpus_intersects(src1, src2) __cpus_intersects(&(src1), &(src2), NR_CPUS)
200 static inline int __cpus_intersects(const cpumask_t *src1p,
201                                         const cpumask_t *src2p, int nbits)
202 {
203         return bitmap_intersects(src1p->bits, src2p->bits, nbits);
204 }
205
206 #define cpus_subset(src1, src2) __cpus_subset(&(src1), &(src2), NR_CPUS)
207 static inline int __cpus_subset(const cpumask_t *src1p,
208                                         const cpumask_t *src2p, int nbits)
209 {
210         return bitmap_subset(src1p->bits, src2p->bits, nbits);
211 }
212
213 #define cpus_empty(src) __cpus_empty(&(src), NR_CPUS)
214 static inline int __cpus_empty(const cpumask_t *srcp, int nbits)
215 {
216         return bitmap_empty(srcp->bits, nbits);
217 }
218
219 #define cpus_full(cpumask) __cpus_full(&(cpumask), NR_CPUS)
220 static inline int __cpus_full(const cpumask_t *srcp, int nbits)
221 {
222         return bitmap_full(srcp->bits, nbits);
223 }
224
225 #define cpus_weight(cpumask) __cpus_weight(&(cpumask), NR_CPUS)
226 static inline int __cpus_weight(const cpumask_t *srcp, int nbits)
227 {
228         return bitmap_weight(srcp->bits, nbits);
229 }
230
231 #define cpus_shift_right(dst, src, n) \
232                         __cpus_shift_right(&(dst), &(src), (n), NR_CPUS)
233 static inline void __cpus_shift_right(cpumask_t *dstp,
234                                         const cpumask_t *srcp, int n, int nbits)
235 {
236         bitmap_shift_right(dstp->bits, srcp->bits, n, nbits);
237 }
238
239 #define cpus_shift_left(dst, src, n) \
240                         __cpus_shift_left(&(dst), &(src), (n), NR_CPUS)
241 static inline void __cpus_shift_left(cpumask_t *dstp,
242                                         const cpumask_t *srcp, int n, int nbits)
243 {
244         bitmap_shift_left(dstp->bits, srcp->bits, n, nbits);
245 }
246
247 int __first_cpu(const cpumask_t *srcp);
248 #define first_cpu(src) __first_cpu(&(src))
249 int __next_cpu(int n, const cpumask_t *srcp);
250 #define next_cpu(n, src) __next_cpu((n), &(src))
251
252 #define cpumask_of_cpu(cpu)                                             \
253 ({                                                                      \
254         typeof(_unused_cpumask_arg_) m;                                 \
255         if (sizeof(m) == sizeof(unsigned long)) {                       \
256                 m.bits[0] = 1UL<<(cpu);                                 \
257         } else {                                                        \
258                 cpus_clear(m);                                          \
259                 cpu_set((cpu), m);                                      \
260         }                                                               \
261         m;                                                              \
262 })
263
264 #define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS)
265
266 #if NR_CPUS <= BITS_PER_LONG
267
268 #define CPU_MASK_ALL                                                    \
269 (cpumask_t) { {                                                         \
270         [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD                 \
271 } }
272
273 #else
274
275 #define CPU_MASK_ALL                                                    \
276 (cpumask_t) { {                                                         \
277         [0 ... BITS_TO_LONGS(NR_CPUS)-2] = ~0UL,                        \
278         [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD                 \
279 } }
280
281 #endif
282
283 #define CPU_MASK_NONE                                                   \
284 (cpumask_t) { {                                                         \
285         [0 ... BITS_TO_LONGS(NR_CPUS)-1] =  0UL                         \
286 } }
287
288 #define CPU_MASK_CPU0                                                   \
289 (cpumask_t) { {                                                         \
290         [0] =  1UL                                                      \
291 } }
292
293 #define cpus_addr(src) ((src).bits)
294
295 #define cpumask_scnprintf(buf, len, src) \
296                         __cpumask_scnprintf((buf), (len), &(src), NR_CPUS)
297 static inline int __cpumask_scnprintf(char *buf, int len,
298                                         const cpumask_t *srcp, int nbits)
299 {
300         return bitmap_scnprintf(buf, len, srcp->bits, nbits);
301 }
302
303 #define cpumask_parse(ubuf, ulen, dst) \
304                         __cpumask_parse((ubuf), (ulen), &(dst), NR_CPUS)
305 static inline int __cpumask_parse(const char __user *buf, int len,
306                                         cpumask_t *dstp, int nbits)
307 {
308         return bitmap_parse(buf, len, dstp->bits, nbits);
309 }
310
311 #define cpulist_scnprintf(buf, len, src) \
312                         __cpulist_scnprintf((buf), (len), &(src), NR_CPUS)
313 static inline int __cpulist_scnprintf(char *buf, int len,
314                                         const cpumask_t *srcp, int nbits)
315 {
316         return bitmap_scnlistprintf(buf, len, srcp->bits, nbits);
317 }
318
319 #define cpulist_parse(buf, dst) __cpulist_parse((buf), &(dst), NR_CPUS)
320 static inline int __cpulist_parse(const char *buf, cpumask_t *dstp, int nbits)
321 {
322         return bitmap_parselist(buf, dstp->bits, nbits);
323 }
324
325 #define cpu_remap(oldbit, old, new) \
326                 __cpu_remap((oldbit), &(old), &(new), NR_CPUS)
327 static inline int __cpu_remap(int oldbit,
328                 const cpumask_t *oldp, const cpumask_t *newp, int nbits)
329 {
330         return bitmap_bitremap(oldbit, oldp->bits, newp->bits, nbits);
331 }
332
333 #define cpus_remap(dst, src, old, new) \
334                 __cpus_remap(&(dst), &(src), &(old), &(new), NR_CPUS)
335 static inline void __cpus_remap(cpumask_t *dstp, const cpumask_t *srcp,
336                 const cpumask_t *oldp, const cpumask_t *newp, int nbits)
337 {
338         bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
339 }
340
341 #define for_each_cpu_mask(cpu, mask)            \
342         for ((cpu) = first_cpu(mask);           \
343                 (cpu) < NR_CPUS;                \
344                 (cpu) = next_cpu((cpu), (mask)))
345
346 /*
347  * The following particular system cpumasks and operations manage
348  * possible, present and online cpus.  Each of them is a fixed size
349  * bitmap of size NR_CPUS.
350  *
351  *  #ifdef CONFIG_HOTPLUG_CPU
352  *     cpu_possible_map - has bit 'cpu' set iff cpu is populatable
353  *     cpu_present_map  - has bit 'cpu' set iff cpu is populated
354  *     cpu_online_map   - has bit 'cpu' set iff cpu available to scheduler
355  *  #else
356  *     cpu_possible_map - has bit 'cpu' set iff cpu is populated
357  *     cpu_present_map  - copy of cpu_possible_map
358  *     cpu_online_map   - has bit 'cpu' set iff cpu available to scheduler
359  *  #endif
360  *
361  *  In either case, NR_CPUS is fixed at compile time, as the static
362  *  size of these bitmaps.  The cpu_possible_map is fixed at boot
363  *  time, as the set of CPU id's that it is possible might ever
364  *  be plugged in at anytime during the life of that system boot.
365  *  The cpu_present_map is dynamic(*), representing which CPUs
366  *  are currently plugged in.  And cpu_online_map is the dynamic
367  *  subset of cpu_present_map, indicating those CPUs available
368  *  for scheduling.
369  *
370  *  If HOTPLUG is enabled, then cpu_possible_map is forced to have
371  *  all NR_CPUS bits set, otherwise it is just the set of CPUs that
372  *  ACPI reports present at boot.
373  *
374  *  If HOTPLUG is enabled, then cpu_present_map varies dynamically,
375  *  depending on what ACPI reports as currently plugged in, otherwise
376  *  cpu_present_map is just a copy of cpu_possible_map.
377  *
378  *  (*) Well, cpu_present_map is dynamic in the hotplug case.  If not
379  *      hotplug, it's a copy of cpu_possible_map, hence fixed at boot.
380  *
381  * Subtleties:
382  * 1) UP arch's (NR_CPUS == 1, CONFIG_SMP not defined) hardcode
383  *    assumption that their single CPU is online.  The UP
384  *    cpu_{online,possible,present}_maps are placebos.  Changing them
385  *    will have no useful affect on the following num_*_cpus()
386  *    and cpu_*() macros in the UP case.  This ugliness is a UP
387  *    optimization - don't waste any instructions or memory references
388  *    asking if you're online or how many CPUs there are if there is
389  *    only one CPU.
390  * 2) Most SMP arch's #define some of these maps to be some
391  *    other map specific to that arch.  Therefore, the following
392  *    must be #define macros, not inlines.  To see why, examine
393  *    the assembly code produced by the following.  Note that
394  *    set1() writes phys_x_map, but set2() writes x_map:
395  *        int x_map, phys_x_map;
396  *        #define set1(a) x_map = a
397  *        inline void set2(int a) { x_map = a; }
398  *        #define x_map phys_x_map
399  *        main(){ set1(3); set2(5); }
400  */
401
402 extern cpumask_t cpu_possible_map;
403 extern cpumask_t cpu_online_map;
404 extern cpumask_t cpu_present_map;
405
406 #define num_online_cpus()       cpus_weight(cpu_online_map)
407 #define num_possible_cpus()     cpus_weight(cpu_possible_map)
408 #define num_present_cpus()      cpus_weight(cpu_present_map)
409 #define cpu_online(cpu)         cpu_isset((cpu), cpu_online_map)
410 #define cpu_possible(cpu)       cpu_isset((cpu), cpu_possible_map)
411 #define cpu_present(cpu)        cpu_isset((cpu), cpu_present_map)
412
413 int highest_possible_processor_id(void);
414 #define any_online_cpu(mask) __any_online_cpu(&(mask))
415 int __any_online_cpu(const cpumask_t *mask);
416
417 #define for_each_cpu(cpu)  for_each_cpu_mask((cpu), cpu_possible_map)
418 #define for_each_possible_cpu(cpu)  for_each_cpu_mask((cpu), cpu_possible_map)
419 #define for_each_online_cpu(cpu)  for_each_cpu_mask((cpu), cpu_online_map)
420 #define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map)
421
422 #endif
423 #endif /* _LWK_CPUMASK_H */