]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - mm/mempolicy.c
[SCTP]: Kill unused static inline sctp_sysctl_jiffies_ms
[linux-2.6-omap-h63xx.git] / mm / mempolicy.c
index 568152ae6cafe9c6f6052cf704c0e6dae0d198f7..6c7ba1a63d23b05931003d97b8932c39ca983060 100644 (file)
@@ -78,6 +78,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/module.h>
+#include <linux/nsproxy.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/compat.h>
@@ -115,22 +116,51 @@ static void mpol_rebind_policy(struct mempolicy *pol,
 /* Do sanity checking on a policy */
 static int mpol_check_policy(int mode, nodemask_t *nodes)
 {
-       int empty = nodes_empty(*nodes);
+       int was_empty, is_empty;
+
+       if (!nodes)
+               return 0;
+
+       /*
+        * "Contextualize" the in-coming nodemast for cpusets:
+        * Remember whether in-coming nodemask was empty,  If not,
+        * restrict the nodes to the allowed nodes in the cpuset.
+        * This is guaranteed to be a subset of nodes with memory.
+        */
+       cpuset_update_task_memory_state();
+       is_empty = was_empty = nodes_empty(*nodes);
+       if (!was_empty) {
+               nodes_and(*nodes, *nodes, cpuset_current_mems_allowed);
+               is_empty = nodes_empty(*nodes); /* after "contextualization" */
+       }
 
        switch (mode) {
        case MPOL_DEFAULT:
-               if (!empty)
+               /*
+                * require caller to specify an empty nodemask
+                * before "contextualization"
+                */
+               if (!was_empty)
                        return -EINVAL;
                break;
        case MPOL_BIND:
        case MPOL_INTERLEAVE:
-               /* Preferred will only use the first bit, but allow
-                  more for now. */
-               if (empty)
+               /*
+                * require at least 1 valid node after "contextualization"
+                */
+               if (is_empty)
+                       return -EINVAL;
+               break;
+       case MPOL_PREFERRED:
+               /*
+                * Did caller specify invalid nodes?
+                * Don't silently accept this as "local allocation".
+                */
+               if (!was_empty && is_empty)
                        return -EINVAL;
                break;
        }
-       return nodes_subset(*nodes, node_states[N_HIGH_MEMORY]) ? 0 : -EINVAL;
+       return 0;
 }
 
 /* Generate a custom zonelist for the BIND policy. */
@@ -187,8 +217,6 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
        switch (mode) {
        case MPOL_INTERLEAVE:
                policy->v.nodes = *nodes;
-               nodes_and(policy->v.nodes, policy->v.nodes,
-                                       node_states[N_HIGH_MEMORY]);
                if (nodes_weight(policy->v.nodes) == 0) {
                        kmem_cache_free(policy_cache, policy);
                        return ERR_PTR(-EINVAL);
@@ -420,18 +448,6 @@ static int mbind_range(struct vm_area_struct *vma, unsigned long start,
        return err;
 }
 
-static int contextualize_policy(int mode, nodemask_t *nodes)
-{
-       if (!nodes)
-               return 0;
-
-       cpuset_update_task_memory_state();
-       if (!cpuset_nodes_subset_current_mems_allowed(*nodes))
-               return -EINVAL;
-       return mpol_check_policy(mode, nodes);
-}
-
-
 /*
  * Update task->flags PF_MEMPOLICY bit: set iff non-default
  * mempolicy.  Allows more rapid checking of this (combined perhaps
@@ -467,7 +483,7 @@ static long do_set_mempolicy(int mode, nodemask_t *nodes)
 {
        struct mempolicy *new;
 
-       if (contextualize_policy(mode, nodes))
+       if (mpol_check_policy(mode, nodes))
                return -EINVAL;
        new = mpol_new(mode, nodes);
        if (IS_ERR(new))
@@ -721,12 +737,29 @@ out:
 
 }
 
+/*
+ * Allocate a new page for page migration based on vma policy.
+ * Start assuming that page is mapped by vma pointed to by @private.
+ * Search forward from there, if not.  N.B., this assumes that the
+ * list of pages handed to migrate_pages()--which is how we get here--
+ * is in virtual address order.
+ */
 static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
 {
        struct vm_area_struct *vma = (struct vm_area_struct *)private;
+       unsigned long uninitialized_var(address);
+
+       while (vma) {
+               address = page_address_in_vma(page, vma);
+               if (address != -EFAULT)
+                       break;
+               vma = vma->vm_next;
+       }
 
-       return alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma,
-                                       page_address_in_vma(page, vma));
+       /*
+        * if !vma, alloc_page_vma() will use task or system default policy
+        */
+       return alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
 }
 #else
 
@@ -897,10 +930,6 @@ asmlinkage long sys_mbind(unsigned long start, unsigned long len,
        err = get_nodes(&nodes, nmask, maxnode);
        if (err)
                return err;
-#ifdef CONFIG_CPUSETS
-       /* Restrict the nodes to the allowed nodes in the cpuset */
-       nodes_and(nodes, nodes, current->mems_allowed);
-#endif
        return do_mbind(start, len, mode, &nodes, flags);
 }
 
@@ -940,7 +969,7 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
 
        /* Find the mm_struct */
        read_lock(&tasklist_lock);
-       task = pid ? find_task_by_pid(pid) : current;
+       task = pid ? find_task_by_vpid(pid) : current;
        if (!task) {
                read_unlock(&tasklist_lock);
                return -ESRCH;
@@ -1388,7 +1417,6 @@ EXPORT_SYMBOL(alloc_pages_current);
  * keeps mempolicies cpuset relative after its cpuset moves.  See
  * further kernel/cpuset.c update_nodemask().
  */
-void *cpuset_being_rebound;
 
 /* Slow path of a mempolicy copy */
 struct mempolicy *__mpol_copy(struct mempolicy *old)
@@ -1968,7 +1996,7 @@ int show_numa_map(struct seq_file *m, void *v)
 
        if (file) {
                seq_printf(m, " file=");
-               seq_path(m, file->f_path.mnt, file->f_path.dentry, "\n\t= ");
+               seq_path(m, &file->f_path, "\n\t= ");
        } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
                seq_printf(m, " heap");
        } else if (vma->vm_start <= mm->start_stack &&
@@ -2019,4 +2047,3 @@ out:
                m->version = (vma != priv->tail_vma) ? vma->vm_start : 0;
        return 0;
 }
-