aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorPaul Jackson <pj@sgi.com>2008-04-28 05:12:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-28 11:58:19 -0400
commit7ea931c9fc80c4d0a4306c30ec92eb0f1d922a0b (patch)
tree4f2c85d658c75e8679e01943e3e95866b3729b54 /include/linux
parentf5b087b52f1710eb0bf15a2d2b030c51a6a1ca9e (diff)
mempolicy: add bitmap_onto() and bitmap_fold() operations
The following adds two more bitmap operators, bitmap_onto() and bitmap_fold(), with the usual cpumask and nodemask wrappers. The bitmap_onto() operator computes one bitmap relative to another. If the n-th bit in the origin mask is set, then the m-th bit of the destination mask will be set, where m is the position of the n-th set bit in the relative mask. The bitmap_fold() operator folds a bitmap into a second that has bit m set iff the input bitmap has some bit n set, where m == n mod sz, for the specified sz value. There are two substantive changes between this patch and its predecessor bitmap_relative: 1) Renamed bitmap_relative() to be bitmap_onto(). 2) Added bitmap_fold(). The essential motivation for bitmap_onto() is to provide a mechanism for converting a cpuset-relative CPU or Node mask to an absolute mask. Cpuset relative masks are written as if the current task were in a cpuset whose CPUs or Nodes were just the consecutive ones numbered 0..N-1, for some N. The bitmap_onto() operator is provided in anticipation of adding support for the first such cpuset relative mask, by the mbind() and set_mempolicy() system calls, using a planned flag of MPOL_F_RELATIVE_NODES. These bitmap operators (and their nodemask wrappers, in particular) will be used in code that converts the user specified cpuset relative memory policy to a specific system node numbered policy, given the current mems_allowed of the tasks cpuset. Such cpuset relative mempolicies will address two deficiencies of the existing interface between cpusets and mempolicies: 1) A task cannot at present reliably establish a cpuset relative mempolicy because there is an essential race condition, in that the tasks cpuset may be changed in between the time the task can query its cpuset placement, and the time the task can issue the applicable mbind or set_memplicy system call. 2) A task cannot at present establish what cpuset relative mempolicy it would like to have, if it is in a smaller cpuset than it might have mempolicy preferences for, because the existing interface only allows specifying mempolicies for nodes currently allowed by the cpuset. Cpuset relative mempolicies are useful for tasks that don't distinguish particularly between one CPU or Node and another, but only between how many of each are allowed, and the proper placement of threads and memory pages on the various CPUs and Nodes available. The motivation for the added bitmap_fold() can be seen in the following example. Let's say an application has specified some mempolicies that presume 16 memory nodes, including say a mempolicy that specified MPOL_F_RELATIVE_NODES (cpuset relative) nodes 12-15. Then lets say that application is crammed into a cpuset that only has 8 memory nodes, 0-7. If one just uses bitmap_onto(), this mempolicy, mapped to that cpuset, would ignore the requested relative nodes above 7, leaving it empty of nodes. That's not good; better to fold the higher nodes down, so that some nodes are included in the resulting mapped mempolicy. In this case, the mempolicy nodes 12-15 are taken modulo 8 (the weight of the mems_allowed of the confining cpuset), resulting in a mempolicy specifying nodes 4-7. Signed-off-by: Paul Jackson <pj@sgi.com> Signed-off-by: David Rientjes <rientjes@google.com> Cc: Christoph Lameter <clameter@sgi.com> Cc: Andi Kleen <ak@suse.de> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Lee Schermerhorn <lee.schermerhorn@hp.com> Cc: <kosaki.motohiro@jp.fujitsu.com> Cc: <ray-lk@madrabbit.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/bitmap.h6
-rw-r--r--include/linux/cpumask.h22
-rw-r--r--include/linux/nodemask.h22
3 files changed, 48 insertions, 2 deletions
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 1dbe074f1c64..43b406def35f 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -46,6 +46,8 @@
46 * bitmap_shift_left(dst, src, n, nbits) *dst = *src << n 46 * bitmap_shift_left(dst, src, n, nbits) *dst = *src << n
47 * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src) 47 * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src)
48 * bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit) 48 * bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit)
49 * bitmap_onto(dst, orig, relmap, nbits) *dst = orig relative to relmap
50 * bitmap_fold(dst, orig, sz, nbits) dst bits = orig bits mod sz
49 * bitmap_scnprintf(buf, len, src, nbits) Print bitmap src to buf 51 * bitmap_scnprintf(buf, len, src, nbits) Print bitmap src to buf
50 * bitmap_parse(buf, buflen, dst, nbits) Parse bitmap dst from kernel buf 52 * bitmap_parse(buf, buflen, dst, nbits) Parse bitmap dst from kernel buf
51 * bitmap_parse_user(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf 53 * bitmap_parse_user(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf
@@ -121,6 +123,10 @@ extern void bitmap_remap(unsigned long *dst, const unsigned long *src,
121 const unsigned long *old, const unsigned long *new, int bits); 123 const unsigned long *old, const unsigned long *new, int bits);
122extern int bitmap_bitremap(int oldbit, 124extern int bitmap_bitremap(int oldbit,
123 const unsigned long *old, const unsigned long *new, int bits); 125 const unsigned long *old, const unsigned long *new, int bits);
126extern void bitmap_onto(unsigned long *dst, const unsigned long *orig,
127 const unsigned long *relmap, int bits);
128extern void bitmap_fold(unsigned long *dst, const unsigned long *orig,
129 int sz, int bits);
124extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order); 130extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order);
125extern void bitmap_release_region(unsigned long *bitmap, int pos, int order); 131extern void bitmap_release_region(unsigned long *bitmap, int pos, int order);
126extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order); 132extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order);
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 259c8051155d..9650806fe2ea 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -14,6 +14,8 @@
14 * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c. 14 * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
15 * For details of cpu_remap(), see bitmap_bitremap in lib/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. 16 * For details of cpus_remap(), see bitmap_remap 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.
17 * 19 *
18 * The available cpumask operations are: 20 * The available cpumask operations are:
19 * 21 *
@@ -53,7 +55,9 @@
53 * int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing 55 * int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing
54 * int cpulist_parse(buf, map) Parse ascii string as cpulist 56 * int cpulist_parse(buf, map) Parse ascii string as cpulist
55 * int cpu_remap(oldbit, old, new) newbit = map(old, new)(oldbit) 57 * int cpu_remap(oldbit, old, new) newbit = map(old, new)(oldbit)
56 * int cpus_remap(dst, src, old, new) *dst = map(old, new)(src) 58 * void cpus_remap(dst, src, old, new) *dst = map(old, new)(src)
59 * void cpus_onto(dst, orig, relmap) *dst = orig relative to relmap
60 * void cpus_fold(dst, orig, sz) dst bits = orig bits mod sz
57 * 61 *
58 * for_each_cpu_mask(cpu, mask) for-loop cpu over mask 62 * for_each_cpu_mask(cpu, mask) for-loop cpu over mask
59 * 63 *
@@ -330,6 +334,22 @@ static inline void __cpus_remap(cpumask_t *dstp, const cpumask_t *srcp,
330 bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits); 334 bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
331} 335}
332 336
337#define cpus_onto(dst, orig, relmap) \
338 __cpus_onto(&(dst), &(orig), &(relmap), NR_CPUS)
339static inline void __cpus_onto(cpumask_t *dstp, const cpumask_t *origp,
340 const cpumask_t *relmapp, int nbits)
341{
342 bitmap_onto(dstp->bits, origp->bits, relmapp->bits, nbits);
343}
344
345#define cpus_fold(dst, orig, sz) \
346 __cpus_fold(&(dst), &(orig), sz, NR_CPUS)
347static inline void __cpus_fold(cpumask_t *dstp, const cpumask_t *origp,
348 int sz, int nbits)
349{
350 bitmap_fold(dstp->bits, origp->bits, sz, nbits);
351}
352
333#if NR_CPUS > 1 353#if NR_CPUS > 1
334#define for_each_cpu_mask(cpu, mask) \ 354#define for_each_cpu_mask(cpu, mask) \
335 for ((cpu) = first_cpu(mask); \ 355 for ((cpu) = first_cpu(mask); \
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 905e18f4b412..848025cd7087 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -14,6 +14,8 @@
14 * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c. 14 * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
15 * For details of node_remap(), see bitmap_bitremap in lib/bitmap.c. 15 * For details of node_remap(), see bitmap_bitremap in lib/bitmap.c.
16 * For details of nodes_remap(), see bitmap_remap in lib/bitmap.c. 16 * For details of nodes_remap(), see bitmap_remap in lib/bitmap.c.
17 * For details of nodes_onto(), see bitmap_onto in lib/bitmap.c.
18 * For details of nodes_fold(), see bitmap_fold in lib/bitmap.c.
17 * 19 *
18 * The available nodemask operations are: 20 * The available nodemask operations are:
19 * 21 *
@@ -55,7 +57,9 @@
55 * int nodelist_scnprintf(buf, len, mask) Format nodemask as list for printing 57 * int nodelist_scnprintf(buf, len, mask) Format nodemask as list for printing
56 * int nodelist_parse(buf, map) Parse ascii string as nodelist 58 * int nodelist_parse(buf, map) Parse ascii string as nodelist
57 * int node_remap(oldbit, old, new) newbit = map(old, new)(oldbit) 59 * int node_remap(oldbit, old, new) newbit = map(old, new)(oldbit)
58 * int nodes_remap(dst, src, old, new) *dst = map(old, new)(dst) 60 * void nodes_remap(dst, src, old, new) *dst = map(old, new)(src)
61 * void nodes_onto(dst, orig, relmap) *dst = orig relative to relmap
62 * void nodes_fold(dst, orig, sz) dst bits = orig bits mod sz
59 * 63 *
60 * for_each_node_mask(node, mask) for-loop node over mask 64 * for_each_node_mask(node, mask) for-loop node over mask
61 * 65 *
@@ -326,6 +330,22 @@ static inline void __nodes_remap(nodemask_t *dstp, const nodemask_t *srcp,
326 bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits); 330 bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
327} 331}
328 332
333#define nodes_onto(dst, orig, relmap) \
334 __nodes_onto(&(dst), &(orig), &(relmap), MAX_NUMNODES)
335static inline void __nodes_onto(nodemask_t *dstp, const nodemask_t *origp,
336 const nodemask_t *relmapp, int nbits)
337{
338 bitmap_onto(dstp->bits, origp->bits, relmapp->bits, nbits);
339}
340
341#define nodes_fold(dst, orig, sz) \
342 __nodes_fold(&(dst), &(orig), sz, MAX_NUMNODES)
343static inline void __nodes_fold(nodemask_t *dstp, const nodemask_t *origp,
344 int sz, int nbits)
345{
346 bitmap_fold(dstp->bits, origp->bits, sz, nbits);
347}
348
329#if MAX_NUMNODES > 1 349#if MAX_NUMNODES > 1
330#define for_each_node_mask(node, mask) \ 350#define for_each_node_mask(node, mask) \
331 for ((node) = first_node(mask); \ 351 for ((node) = first_node(mask); \