mempolicy: rename policy_types and cleanup initialization
[safe/jmp/linux-2.6] / mm / mempolicy.c
index bda230e..ade5732 100644 (file)
@@ -73,7 +73,6 @@
 #include <linux/sched.h>
 #include <linux/nodemask.h>
 #include <linux/cpuset.h>
-#include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/module.h>
@@ -128,9 +127,6 @@ static int is_valid_nodemask(const nodemask_t *nodemask)
 {
        int nd, k;
 
-       /* Check that there is something useful in this mask */
-       k = policy_zone;
-
        for_each_node_mask(nd, *nodemask) {
                struct zone *z;
 
@@ -146,7 +142,7 @@ static int is_valid_nodemask(const nodemask_t *nodemask)
 
 static inline int mpol_store_user_nodemask(const struct mempolicy *pol)
 {
-       return pol->flags & (MPOL_F_STATIC_NODES | MPOL_F_RELATIVE_NODES);
+       return pol->flags & MPOL_MODE_FLAGS;
 }
 
 static void mpol_relative_nodemask(nodemask_t *ret, const nodemask_t *orig,
@@ -806,9 +802,13 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask,
 
        err = 0;
        if (nmask) {
-               task_lock(current);
-               get_policy_nodemask(pol, nmask);
-               task_unlock(current);
+               if (mpol_store_user_nodemask(pol)) {
+                       *nmask = pol->w.user_nodemask;
+               } else {
+                       task_lock(current);
+                       get_policy_nodemask(pol, nmask);
+                       task_unlock(current);
+               }
        }
 
  out:
@@ -1441,15 +1441,13 @@ static struct zonelist *policy_zonelist(gfp_t gfp, struct mempolicy *policy)
                /*
                 * Normally, MPOL_BIND allocations are node-local within the
                 * allowed nodemask.  However, if __GFP_THISNODE is set and the
-                * current node is part of the mask, we use the zonelist for
+                * current node isn't part of the mask, we use the zonelist for
                 * the first node in the mask instead.
                 */
                if (unlikely(gfp & __GFP_THISNODE) &&
                                unlikely(!node_isset(nd, policy->v.nodes)))
                        nd = first_node(policy->v.nodes);
                break;
-       case MPOL_INTERLEAVE: /* should not happen */
-               break;
        default:
                BUG();
        }
@@ -1756,10 +1754,12 @@ struct mempolicy *__mpol_dup(struct mempolicy *old)
 
        if (!new)
                return ERR_PTR(-ENOMEM);
+       rcu_read_lock();
        if (current_cpuset_is_being_rebound()) {
                nodemask_t mems = cpuset_mems_allowed(current);
                mpol_rebind_policy(old, &mems);
        }
+       rcu_read_unlock();
        *new = *old;
        atomic_set(&new->refcnt, 1);
        return new;
@@ -1787,16 +1787,6 @@ struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol,
        return tompol;
 }
 
-static int mpol_match_intent(const struct mempolicy *a,
-                            const struct mempolicy *b)
-{
-       if (a->flags != b->flags)
-               return 0;
-       if (!mpol_store_user_nodemask(a))
-               return 1;
-       return nodes_equal(a->w.user_nodemask, b->w.user_nodemask);
-}
-
 /* Slow path of a mempolicy comparison */
 int __mpol_equal(struct mempolicy *a, struct mempolicy *b)
 {
@@ -1804,8 +1794,12 @@ int __mpol_equal(struct mempolicy *a, struct mempolicy *b)
                return 0;
        if (a->mode != b->mode)
                return 0;
-       if (a->mode != MPOL_DEFAULT && !mpol_match_intent(a, b))
+       if (a->flags != b->flags)
                return 0;
+       if (mpol_store_user_nodemask(a))
+               if (!nodes_equal(a->w.user_nodemask, b->w.user_nodemask))
+                       return 0;
+
        switch (a->mode) {
        case MPOL_BIND:
                /* Fall through */
@@ -2127,9 +2121,15 @@ void numa_default_policy(void)
  * "local" is pseudo-policy:  MPOL_PREFERRED with MPOL_F_LOCAL flag
  * Used only for mpol_parse_str() and mpol_to_str()
  */
-#define MPOL_LOCAL (MPOL_INTERLEAVE + 1)
-static const char * const policy_types[] =
-       { "default", "prefer", "bind", "interleave", "local" };
+#define MPOL_LOCAL MPOL_MAX
+static const char * const policy_modes[] =
+{
+       [MPOL_DEFAULT]    = "default",
+       [MPOL_PREFERRED]  = "prefer",
+       [MPOL_BIND]       = "bind",
+       [MPOL_INTERLEAVE] = "interleave",
+       [MPOL_LOCAL]      = "local"
+};
 
 
 #ifdef CONFIG_TMPFS
@@ -2154,12 +2154,11 @@ static const char * const policy_types[] =
 int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
 {
        struct mempolicy *new = NULL;
-       unsigned short uninitialized_var(mode);
+       unsigned short mode;
        unsigned short uninitialized_var(mode_flags);
        nodemask_t nodes;
        char *nodelist = strchr(str, ':');
        char *flags = strchr(str, '=');
-       int i;
        int err = 1;
 
        if (nodelist) {
@@ -2175,13 +2174,12 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
        if (flags)
                *flags++ = '\0';        /* terminate mode string */
 
-       for (i = 0; i <= MPOL_LOCAL; i++) {
-               if (!strcmp(str, policy_types[i])) {
-                       mode = i;
+       for (mode = 0; mode <= MPOL_LOCAL; mode++) {
+               if (!strcmp(str, policy_modes[mode])) {
                        break;
                }
        }
-       if (i > MPOL_LOCAL)
+       if (mode > MPOL_LOCAL)
                goto out;
 
        switch (mode) {
@@ -2193,8 +2191,8 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
                        char *rest = nodelist;
                        while (isdigit(*rest))
                                rest++;
-                       if (!*rest)
-                               err = 0;
+                       if (*rest)
+                               goto out;
                }
                break;
        case MPOL_INTERLEAVE:
@@ -2203,7 +2201,6 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
                 */
                if (!nodelist)
                        nodes = node_states[N_HIGH_MEMORY];
-               err = 0;
                break;
        case MPOL_LOCAL:
                /*
@@ -2213,11 +2210,19 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
                        goto out;
                mode = MPOL_PREFERRED;
                break;
-
-       /*
-        * case MPOL_BIND:    mpol_new() enforces non-empty nodemask.
-        * case MPOL_DEFAULT: mpol_new() enforces empty nodemask, ignores flags.
-        */
+       case MPOL_DEFAULT:
+               /*
+                * Insist on a empty nodelist
+                */
+               if (!nodelist)
+                       err = 0;
+               goto out;
+       case MPOL_BIND:
+               /*
+                * Insist on a nodelist
+                */
+               if (!nodelist)
+                       goto out;
        }
 
        mode_flags = 0;
@@ -2231,13 +2236,17 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
                else if (!strcmp(flags, "relative"))
                        mode_flags |= MPOL_F_RELATIVE_NODES;
                else
-                       err = 1;
+                       goto out;
        }
 
        new = mpol_new(mode, mode_flags, &nodes);
        if (IS_ERR(new))
-               err = 1;
-       else {
+               goto out;
+
+       if (no_context) {
+               /* save for contextualization */
+               new->w.user_nodemask = nodes;
+       } else {
                int ret;
                NODEMASK_SCRATCH(scratch);
                if (scratch) {
@@ -2248,13 +2257,11 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
                        ret = -ENOMEM;
                NODEMASK_SCRATCH_FREE(scratch);
                if (ret) {
-                       err = 1;
                        mpol_put(new);
-               } else if (no_context) {
-                       /* save for contextualization */
-                       new->w.user_nodemask = nodes;
+                       goto out;
                }
        }
+       err = 0;
 
 out:
        /* Restore string for error message */
@@ -2323,11 +2330,11 @@ int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, int no_context)
                BUG();
        }
 
-       l = strlen(policy_types[mode]);
+       l = strlen(policy_modes[mode]);
        if (buffer + maxlen < p + l + 1)
                return -ENOSPC;
 
-       strcpy(p, policy_types[mode]);
+       strcpy(p, policy_modes[mode]);
        p += l;
 
        if (flags & MPOL_MODE_FLAGS) {