aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLee Schermerhorn <Lee.Schermerhorn@hp.com>2007-10-16 04:24:51 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:42:54 -0400
commit754af6f5a85fcd1ecb456851d20c65e4c6ce10ab (patch)
tree8c985bfd704a8c993d6ca992725969c6fc5c9e5a
parent32a4330d4156e55a4888a201f484dbafed9504ed (diff)
Mem Policy: add MPOL_F_MEMS_ALLOWED get_mempolicy() flag
Allow an application to query the memories allowed by its context. Updated numa_memory_policy.txt to mention that applications can use this to obtain allowed memories for constructing valid policies. TODO: update out-of-tree libnuma wrapper[s], or maybe add a new wrapper--e.g., numa_get_mems_allowed() ? Also, update numa syscall man pages. Tested with memtoy V>=0.13. Signed-off-by: Lee Schermerhorn <lee.schermerhorn@hp.com> Acked-by: Christoph Lameter <clameter@sgi.com> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/vm/numa_memory_policy.txt33
-rw-r--r--include/linux/mempolicy.h1
-rw-r--r--mm/mempolicy.c12
3 files changed, 28 insertions, 18 deletions
diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt
index 8242f52d0f22..dd4986497996 100644
--- a/Documentation/vm/numa_memory_policy.txt
+++ b/Documentation/vm/numa_memory_policy.txt
@@ -302,31 +302,30 @@ MEMORY POLICIES AND CPUSETS
302 302
303Memory policies work within cpusets as described above. For memory policies 303Memory policies work within cpusets as described above. For memory policies
304that require a node or set of nodes, the nodes are restricted to the set of 304that require a node or set of nodes, the nodes are restricted to the set of
305nodes whose memories are allowed by the cpuset constraints. If the 305nodes whose memories are allowed by the cpuset constraints. If the nodemask
306intersection of the set of nodes specified for the policy and the set of nodes 306specified for the policy contains nodes that are not allowed by the cpuset, or
307allowed by the cpuset is the empty set, the policy is considered invalid and 307the intersection of the set of nodes specified for the policy and the set of
308cannot be installed. 308nodes with memory is the empty set, the policy is considered invalid
309and cannot be installed.
309 310
310The interaction of memory policies and cpusets can be problematic for a 311The interaction of memory policies and cpusets can be problematic for a
311couple of reasons: 312couple of reasons:
312 313
3131) the memory policy APIs take physical node id's as arguments. However, the 3141) the memory policy APIs take physical node id's as arguments. As mentioned
314 memory policy APIs do not provide a way to determine what nodes are valid 315 above, it is illegal to specify nodes that are not allowed in the cpuset.
315 in the context where the application is running. An application MAY consult 316 The application must query the allowed nodes using the get_mempolicy()
316 the cpuset file system [directly or via an out of tree, and not generally 317 API with the MPOL_F_MEMS_ALLOWED flag to determine the allowed nodes and
317 available, libcpuset API] to obtain this information, but then the 318 restrict itself to those nodes. However, the resources available to a
318 application must be aware that it is running in a cpuset and use what are 319 cpuset can be changed by the system administrator, or a workload manager
319 intended primarily as administrative APIs. 320 application, at any time. So, a task may still get errors attempting to
320 321 specify policy nodes, and must query the allowed memories again.
321 However, as long as the policy specifies at least one node that is valid
322 in the controlling cpuset, the policy can be used.
323 322
3242) when tasks in two cpusets share access to a memory region, such as shared 3232) when tasks in two cpusets share access to a memory region, such as shared
325 memory segments created by shmget() of mmap() with the MAP_ANONYMOUS and 324 memory segments created by shmget() of mmap() with the MAP_ANONYMOUS and
326 MAP_SHARED flags, and any of the tasks install shared policy on the region, 325 MAP_SHARED flags, and any of the tasks install shared policy on the region,
327 only nodes whose memories are allowed in both cpusets may be used in the 326 only nodes whose memories are allowed in both cpusets may be used in the
328 policies. Again, obtaining this information requires "stepping outside" 327 policies. Obtaining this information requires "stepping outside" the
329 the memory policy APIs, as well as knowing in what cpusets other task might 328 memory policy APIs to use the cpuset information and requires that one
330 be attaching to the shared region, to use the cpuset information. 329 know in what cpusets other task might be attaching to the shared region.
331 Furthermore, if the cpusets' allowed memory sets are disjoint, "local" 330 Furthermore, if the cpusets' allowed memory sets are disjoint, "local"
332 allocation is the only valid policy. 331 allocation is the only valid policy.
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index a020eb2d4e2a..7e9698ec839b 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -19,6 +19,7 @@
19/* Flags for get_mem_policy */ 19/* Flags for get_mem_policy */
20#define MPOL_F_NODE (1<<0) /* return next IL mode instead of node mask */ 20#define MPOL_F_NODE (1<<0) /* return next IL mode instead of node mask */
21#define MPOL_F_ADDR (1<<1) /* look up vma using address */ 21#define MPOL_F_ADDR (1<<1) /* look up vma using address */
22#define MPOL_F_MEMS_ALLOWED (1<<2) /* return allowed memories */
22 23
23/* Flags for mbind */ 24/* Flags for mbind */
24#define MPOL_MF_STRICT (1<<0) /* Verify existing pages in the mapping */ 25#define MPOL_MF_STRICT (1<<0) /* Verify existing pages in the mapping */
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 3a45b7dd0a09..ccbdb22147bb 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -526,8 +526,18 @@ long do_get_mempolicy(int *policy, nodemask_t *nmask,
526 struct mempolicy *pol = current->mempolicy; 526 struct mempolicy *pol = current->mempolicy;
527 527
528 cpuset_update_task_memory_state(); 528 cpuset_update_task_memory_state();
529 if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR)) 529 if (flags &
530 ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR|MPOL_F_MEMS_ALLOWED))
530 return -EINVAL; 531 return -EINVAL;
532
533 if (flags & MPOL_F_MEMS_ALLOWED) {
534 if (flags & (MPOL_F_NODE|MPOL_F_ADDR))
535 return -EINVAL;
536 *policy = 0; /* just so it's initialized */
537 *nmask = cpuset_current_mems_allowed;
538 return 0;
539 }
540
531 if (flags & MPOL_F_ADDR) { 541 if (flags & MPOL_F_ADDR) {
532 down_read(&mm->mmap_sem); 542 down_read(&mm->mmap_sem);
533 vma = find_vma_intersection(mm, addr, addr+1); 543 vma = find_vma_intersection(mm, addr, addr+1);