]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - mm/mempolicy.c
mempolicy: support optional mode flags
[linux-2.6-omap-h63xx.git] / mm / mempolicy.c
index 83c69f8a64c29dd0878050b3912e5f0c2b1af3ac..1f6ff9c1bbc3ec99d5ad6b8db04859eb234ee96d 100644 (file)
@@ -114,70 +114,86 @@ static void mpol_rebind_policy(struct mempolicy *pol,
                                const nodemask_t *newmask);
 
 /* Do sanity checking on a policy */
-static int mpol_check_policy(int mode, nodemask_t *nodes)
+static int mpol_check_policy(unsigned short 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;
+       default:
+               BUG();
        }
-       return nodes_subset(*nodes, node_states[N_HIGH_MEMORY]) ? 0 : -EINVAL;
+       return 0;
 }
 
-/* Generate a custom zonelist for the BIND policy. */
-static struct zonelist *bind_zonelist(nodemask_t *nodes)
+/* Check that the nodemask contains at least one populated zone */
+static int is_valid_nodemask(nodemask_t *nodemask)
 {
-       struct zonelist *zl;
-       int num, max, nd;
-       enum zone_type k;
+       int nd, k;
 
-       max = 1 + MAX_NR_ZONES * nodes_weight(*nodes);
-       max++;                  /* space for zlcache_ptr (see mmzone.h) */
-       zl = kmalloc(sizeof(struct zone *) * max, GFP_KERNEL);
-       if (!zl)
-               return ERR_PTR(-ENOMEM);
-       zl->zlcache_ptr = NULL;
-       num = 0;
-       /* First put in the highest zones from all nodes, then all the next 
-          lower zones etc. Avoid empty zones because the memory allocator
-          doesn't like them. If you implement node hot removal you
-          have to fix that. */
-       k = MAX_NR_ZONES - 1;
-       while (1) {
-               for_each_node_mask(nd, *nodes) { 
-                       struct zone *z = &NODE_DATA(nd)->node_zones[k];
-                       if (z->present_pages > 0) 
-                               zl->zones[num++] = z;
+       /* Check that there is something useful in this mask */
+       k = policy_zone;
+
+       for_each_node_mask(nd, *nodemask) {
+               struct zone *z;
+
+               for (k = 0; k <= policy_zone; k++) {
+                       z = &NODE_DATA(nd)->node_zones[k];
+                       if (z->present_pages > 0)
+                               return 1;
                }
-               if (k == 0)
-                       break;
-               k--;
        }
-       if (num == 0) {
-               kfree(zl);
-               return ERR_PTR(-EINVAL);
-       }
-       zl->zones[num] = NULL;
-       return zl;
+
+       return 0;
 }
 
 /* Create a new policy */
-static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
+static struct mempolicy *mpol_new(unsigned short mode, unsigned short flags,
+                                 nodemask_t *nodes)
 {
        struct mempolicy *policy;
 
-       pr_debug("setting mode %d nodes[0] %lx\n",
-                mode, nodes ? nodes_addr(*nodes)[0] : -1);
+       pr_debug("setting mode %d flags %d nodes[0] %lx\n",
+                mode, flags, nodes ? nodes_addr(*nodes)[0] : -1);
 
        if (mode == MPOL_DEFAULT)
                return NULL;
@@ -188,8 +204,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);
@@ -201,15 +215,17 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
                        policy->v.preferred_node = -1;
                break;
        case MPOL_BIND:
-               policy->v.zonelist = bind_zonelist(nodes);
-               if (IS_ERR(policy->v.zonelist)) {
-                       void *error_code = policy->v.zonelist;
+               if (!is_valid_nodemask(nodes)) {
                        kmem_cache_free(policy_cache, policy);
-                       return error_code;
+                       return ERR_PTR(-EINVAL);
                }
+               policy->v.nodes = *nodes;
                break;
+       default:
+               BUG();
        }
        policy->policy = mode;
+       policy->flags = flags;
        policy->cpuset_mems_allowed = cpuset_mems_allowed(current);
        return policy;
 }
@@ -421,18 +437,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
@@ -464,13 +468,14 @@ static void mpol_set_task_struct_flag(void)
 }
 
 /* Set the process memory policy */
-static long do_set_mempolicy(int mode, nodemask_t *nodes)
+static long do_set_mempolicy(unsigned short mode, unsigned short flags,
+                            nodemask_t *nodes)
 {
        struct mempolicy *new;
 
-       if (contextualize_policy(mode, nodes))
+       if (mpol_check_policy(mode, nodes))
                return -EINVAL;
-       new = mpol_new(mode, nodes);
+       new = mpol_new(mode, flags, nodes);
        if (IS_ERR(new))
                return PTR_ERR(new);
        mpol_free(current->mempolicy);
@@ -484,17 +489,12 @@ static long do_set_mempolicy(int mode, nodemask_t *nodes)
 /* Fill a zone bitmap for a policy */
 static void get_zonemask(struct mempolicy *p, nodemask_t *nodes)
 {
-       int i;
-
        nodes_clear(*nodes);
        switch (p->policy) {
-       case MPOL_BIND:
-               for (i = 0; p->v.zonelist->zones[i]; i++)
-                       node_set(zone_to_nid(p->v.zonelist->zones[i]),
-                               *nodes);
-               break;
        case MPOL_DEFAULT:
                break;
+       case MPOL_BIND:
+               /* Fall through */
        case MPOL_INTERLEAVE:
                *nodes = p->v.nodes;
                break;
@@ -576,7 +576,7 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask,
                        goto out;
                }
        } else
-               *policy = pol->policy;
+               *policy = pol->policy | pol->flags;
 
        if (vma) {
                up_read(&current->mm->mmap_sem);
@@ -766,8 +766,8 @@ static struct page *new_vma_page(struct page *page, unsigned long private, int *
 #endif
 
 static long do_mbind(unsigned long start, unsigned long len,
-                    unsigned long mode, nodemask_t *nmask,
-                    unsigned long flags)
+                    unsigned short mode, unsigned short mode_flags,
+                    nodemask_t *nmask, unsigned long flags)
 {
        struct vm_area_struct *vma;
        struct mm_struct *mm = current->mm;
@@ -776,9 +776,8 @@ static long do_mbind(unsigned long start, unsigned long len,
        int err;
        LIST_HEAD(pagelist);
 
-       if ((flags & ~(unsigned long)(MPOL_MF_STRICT |
-                                     MPOL_MF_MOVE | MPOL_MF_MOVE_ALL))
-           || mode > MPOL_MAX)
+       if (flags & ~(unsigned long)(MPOL_MF_STRICT |
+                                    MPOL_MF_MOVE | MPOL_MF_MOVE_ALL))
                return -EINVAL;
        if ((flags & MPOL_MF_MOVE_ALL) && !capable(CAP_SYS_NICE))
                return -EPERM;
@@ -800,7 +799,7 @@ static long do_mbind(unsigned long start, unsigned long len,
        if (mpol_check_policy(mode, nmask))
                return -EINVAL;
 
-       new = mpol_new(mode, nmask);
+       new = mpol_new(mode, mode_flags, nmask);
        if (IS_ERR(new))
                return PTR_ERR(new);
 
@@ -811,8 +810,9 @@ static long do_mbind(unsigned long start, unsigned long len,
        if (!new)
                flags |= MPOL_MF_DISCONTIG_OK;
 
-       pr_debug("mbind %lx-%lx mode:%ld nodes:%lx\n",start,start+len,
-                mode, nmask ? nodes_addr(*nmask)[0] : -1);
+       pr_debug("mbind %lx-%lx mode:%d flags:%d nodes:%lx\n",
+                start, start + len, mode, mode_flags,
+                nmask ? nodes_addr(*nmask)[0] : -1);
 
        down_write(&mm->mmap_sem);
        vma = check_range(mm, start, end, nmask,
@@ -911,15 +911,16 @@ asmlinkage long sys_mbind(unsigned long start, unsigned long len,
 {
        nodemask_t nodes;
        int err;
+       unsigned short mode_flags;
 
+       mode_flags = mode & MPOL_MODE_FLAGS;
+       mode &= ~MPOL_MODE_FLAGS;
+       if (mode >= MPOL_MAX)
+               return -EINVAL;
        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);
+       return do_mbind(start, len, mode, mode_flags, &nodes, flags);
 }
 
 /* Set the process memory policy */
@@ -928,13 +929,16 @@ asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
 {
        int err;
        nodemask_t nodes;
+       unsigned short flags;
 
-       if (mode < 0 || mode > MPOL_MAX)
+       flags = mode & MPOL_MODE_FLAGS;
+       mode &= ~MPOL_MODE_FLAGS;
+       if ((unsigned int)mode >= MPOL_MAX)
                return -EINVAL;
        err = get_nodes(&nodes, nmask, maxnode);
        if (err)
                return err;
-       return do_set_mempolicy(mode, &nodes);
+       return do_set_mempolicy(mode, flags, &nodes);
 }
 
 asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
@@ -1146,6 +1150,18 @@ static struct mempolicy * get_vma_policy(struct task_struct *task,
        return pol;
 }
 
+/* Return a nodemask representing a mempolicy */
+static nodemask_t *nodemask_policy(gfp_t gfp, struct mempolicy *policy)
+{
+       /* Lower zones don't get a nodemask applied for MPOL_BIND */
+       if (unlikely(policy->policy == MPOL_BIND) &&
+                       gfp_zone(gfp) >= policy_zone &&
+                       cpuset_nodemask_valid_mems_allowed(&policy->v.nodes))
+               return &policy->v.nodes;
+
+       return NULL;
+}
+
 /* Return a zonelist representing a mempolicy */
 static struct zonelist *zonelist_policy(gfp_t gfp, struct mempolicy *policy)
 {
@@ -1158,12 +1174,17 @@ static struct zonelist *zonelist_policy(gfp_t gfp, struct mempolicy *policy)
                        nd = numa_node_id();
                break;
        case MPOL_BIND:
-               /* Lower zones don't get a policy applied */
-               /* Careful: current->mems_allowed might have moved */
-               if (gfp_zone(gfp) >= policy_zone)
-                       if (cpuset_zonelist_valid_mems_allowed(policy->v.zonelist))
-                               return policy->v.zonelist;
-               /*FALL THROUGH*/
+               /*
+                * Normally, MPOL_BIND allocations node-local 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
+                * the zonelist for the first node in the mask instead.
+                */
+               nd = numa_node_id();
+               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 */
        case MPOL_DEFAULT:
                nd = numa_node_id();
@@ -1172,7 +1193,7 @@ static struct zonelist *zonelist_policy(gfp_t gfp, struct mempolicy *policy)
                nd = 0;
                BUG();
        }
-       return NODE_DATA(nd)->node_zonelists + gfp_zone(gfp);
+       return node_zonelist(nd, gfp);
 }
 
 /* Do dynamic interleaving for a process */
@@ -1195,18 +1216,26 @@ static unsigned interleave_nodes(struct mempolicy *policy)
  */
 unsigned slab_node(struct mempolicy *policy)
 {
-       int pol = policy ? policy->policy : MPOL_DEFAULT;
+       unsigned short pol = policy ? policy->policy : MPOL_DEFAULT;
 
        switch (pol) {
        case MPOL_INTERLEAVE:
                return interleave_nodes(policy);
 
-       case MPOL_BIND:
+       case MPOL_BIND: {
                /*
                 * Follow bind policy behavior and start allocation at the
                 * first node.
                 */
-               return zone_to_nid(policy->v.zonelist->zones[0]);
+               struct zonelist *zonelist;
+               struct zone *zone;
+               enum zone_type highest_zoneidx = gfp_zone(GFP_KERNEL);
+               zonelist = &NODE_DATA(numa_node_id())->node_zonelists[0];
+               (void)first_zones_zonelist(zonelist, highest_zoneidx,
+                                                       &policy->v.nodes,
+                                                       &zone);
+               return zone->node;
+       }
 
        case MPOL_PREFERRED:
                if (policy->v.preferred_node >= 0)
@@ -1263,30 +1292,38 @@ static inline unsigned interleave_nid(struct mempolicy *pol,
  * @vma = virtual memory area whose policy is sought
  * @addr = address in @vma for shared policy lookup and interleave policy
  * @gfp_flags = for requested zone
- * @mpol = pointer to mempolicy pointer for reference counted 'BIND policy
+ * @mpol = pointer to mempolicy pointer for reference counted mempolicy
+ * @nodemask = pointer to nodemask pointer for MPOL_BIND nodemask
  *
  * Returns a zonelist suitable for a huge page allocation.
- * If the effective policy is 'BIND, returns pointer to policy's zonelist.
+ * If the effective policy is 'BIND, returns pointer to local node's zonelist,
+ * and a pointer to the mempolicy's @nodemask for filtering the zonelist.
  * If it is also a policy for which get_vma_policy() returns an extra
- * reference, we must hold that reference until after allocation.
+ * reference, we must hold that reference until after the allocation.
  * In that case, return policy via @mpol so hugetlb allocation can drop
- * the reference.  For non-'BIND referenced policies, we can/do drop the
+ * the reference. For non-'BIND referenced policies, we can/do drop the
  * reference here, so the caller doesn't need to know about the special case
  * for default and current task policy.
  */
 struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr,
-                               gfp_t gfp_flags, struct mempolicy **mpol)
+                               gfp_t gfp_flags, struct mempolicy **mpol,
+                               nodemask_t **nodemask)
 {
        struct mempolicy *pol = get_vma_policy(current, vma, addr);
        struct zonelist *zl;
 
        *mpol = NULL;           /* probably no unref needed */
-       if (pol->policy == MPOL_INTERLEAVE) {
+       *nodemask = NULL;       /* assume !MPOL_BIND */
+       if (pol->policy == MPOL_BIND) {
+                       *nodemask = &pol->v.nodes;
+       } else if (pol->policy == MPOL_INTERLEAVE) {
                unsigned nid;
 
                nid = interleave_nid(pol, vma, addr, HPAGE_SHIFT);
-               __mpol_free(pol);               /* finished with pol */
-               return NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_flags);
+               if (unlikely(pol != &default_policy &&
+                               pol != current->mempolicy))
+                       __mpol_free(pol);       /* finished with pol */
+               return node_zonelist(nid, gfp_flags);
        }
 
        zl = zonelist_policy(GFP_HIGHUSER, pol);
@@ -1308,9 +1345,9 @@ static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
        struct zonelist *zl;
        struct page *page;
 
-       zl = NODE_DATA(nid)->node_zonelists + gfp_zone(gfp);
+       zl = node_zonelist(nid, gfp);
        page = __alloc_pages(gfp, order, zl);
-       if (page && page_zone(page) == zl->zones[0])
+       if (page && page_zone(page) == zonelist_zone(&zl->_zonerefs[0]))
                inc_zone_page_state(page, NUMA_INTERLEAVE_HIT);
        return page;
 }
@@ -1349,6 +1386,9 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr)
                unsigned nid;
 
                nid = interleave_nid(pol, vma, addr, PAGE_SHIFT);
+               if (unlikely(pol != &default_policy &&
+                               pol != current->mempolicy))
+                       __mpol_free(pol);       /* finished with pol */
                return alloc_page_interleave(gfp, 0, nid);
        }
        zl = zonelist_policy(gfp, pol);
@@ -1356,14 +1396,15 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr)
                /*
                 * slow path: ref counted policy -- shared or vma
                 */
-               struct page *page =  __alloc_pages(gfp, 0, zl);
+               struct page *page =  __alloc_pages_nodemask(gfp, 0,
+                                               zl, nodemask_policy(gfp, pol));
                __mpol_free(pol);
                return page;
        }
        /*
         * fast path:  default or task policy
         */
-       return __alloc_pages(gfp, 0, zl);
+       return __alloc_pages_nodemask(gfp, 0, zl, nodemask_policy(gfp, pol));
 }
 
 /**
@@ -1395,7 +1436,8 @@ struct page *alloc_pages_current(gfp_t gfp, unsigned order)
                pol = &default_policy;
        if (pol->policy == MPOL_INTERLEAVE)
                return alloc_page_interleave(gfp, order, interleave_nodes(pol));
-       return __alloc_pages(gfp, order, zonelist_policy(gfp, pol));
+       return __alloc_pages_nodemask(gfp, order,
+                       zonelist_policy(gfp, pol), nodemask_policy(gfp, pol));
 }
 EXPORT_SYMBOL(alloc_pages_current);
 
@@ -1420,14 +1462,6 @@ struct mempolicy *__mpol_copy(struct mempolicy *old)
        }
        *new = *old;
        atomic_set(&new->refcnt, 1);
-       if (new->policy == MPOL_BIND) {
-               int sz = ksize(old->v.zonelist);
-               new->v.zonelist = kmemdup(old->v.zonelist, sz, GFP_KERNEL);
-               if (!new->v.zonelist) {
-                       kmem_cache_free(policy_cache, new);
-                       return ERR_PTR(-ENOMEM);
-               }
-       }
        return new;
 }
 
@@ -1441,17 +1475,12 @@ int __mpol_equal(struct mempolicy *a, struct mempolicy *b)
        switch (a->policy) {
        case MPOL_DEFAULT:
                return 1;
+       case MPOL_BIND:
+               /* Fall through */
        case MPOL_INTERLEAVE:
                return nodes_equal(a->v.nodes, b->v.nodes);
        case MPOL_PREFERRED:
                return a->v.preferred_node == b->v.preferred_node;
-       case MPOL_BIND: {
-               int i;
-               for (i = 0; a->v.zonelist->zones[i]; i++)
-                       if (a->v.zonelist->zones[i] != b->v.zonelist->zones[i])
-                               return 0;
-               return b->v.zonelist->zones[i] == NULL;
-       }
        default:
                BUG();
                return 0;
@@ -1463,8 +1492,6 @@ void __mpol_free(struct mempolicy *p)
 {
        if (!atomic_dec_and_test(&p->refcnt))
                return;
-       if (p->policy == MPOL_BIND)
-               kfree(p->v.zonelist);
        p->policy = MPOL_DEFAULT;
        kmem_cache_free(policy_cache, p);
 }
@@ -1623,8 +1650,8 @@ restart:
        return 0;
 }
 
-void mpol_shared_policy_init(struct shared_policy *info, int policy,
-                               nodemask_t *policy_nodes)
+void mpol_shared_policy_init(struct shared_policy *info, unsigned short policy,
+                       unsigned short flags, nodemask_t *policy_nodes)
 {
        info->root = RB_ROOT;
        spin_lock_init(&info->lock);
@@ -1633,7 +1660,7 @@ void mpol_shared_policy_init(struct shared_policy *info, int policy,
                struct mempolicy *newpol;
 
                /* Falls back to MPOL_DEFAULT on any error */
-               newpol = mpol_new(policy, policy_nodes);
+               newpol = mpol_new(policy, flags, policy_nodes);
                if (!IS_ERR(newpol)) {
                        /* Create pseudo-vma that contains just the policy */
                        struct vm_area_struct pvma;
@@ -1654,9 +1681,10 @@ int mpol_set_shared_policy(struct shared_policy *info,
        struct sp_node *new = NULL;
        unsigned long sz = vma_pages(vma);
 
-       pr_debug("set_shared_policy %lx sz %lu %d %lx\n",
+       pr_debug("set_shared_policy %lx sz %lu %d %d %lx\n",
                 vma->vm_pgoff,
-                sz, npol? npol->policy : -1,
+                sz, npol ? npol->policy : -1,
+                npol ? npol->flags : -1,
                 npol ? nodes_addr(npol->v.nodes)[0] : -1);
 
        if (npol) {
@@ -1729,14 +1757,14 @@ void __init numa_policy_init(void)
        if (unlikely(nodes_empty(interleave_nodes)))
                node_set(prefer, interleave_nodes);
 
-       if (do_set_mempolicy(MPOL_INTERLEAVE, &interleave_nodes))
+       if (do_set_mempolicy(MPOL_INTERLEAVE, 0, &interleave_nodes))
                printk("numa_policy_init: interleaving failed\n");
 }
 
 /* Reset policy of current process to default */
 void numa_default_policy(void)
 {
-       do_set_mempolicy(MPOL_DEFAULT, NULL);
+       do_set_mempolicy(MPOL_DEFAULT, 0, NULL);
 }
 
 /* Migrate a policy to a different set of nodes */
@@ -1755,6 +1783,8 @@ static void mpol_rebind_policy(struct mempolicy *pol,
        switch (pol->policy) {
        case MPOL_DEFAULT:
                break;
+       case MPOL_BIND:
+               /* Fall through */
        case MPOL_INTERLEAVE:
                nodes_remap(tmp, pol->v.nodes, *mpolmask, *newmask);
                pol->v.nodes = tmp;
@@ -1767,32 +1797,6 @@ static void mpol_rebind_policy(struct mempolicy *pol,
                                                *mpolmask, *newmask);
                *mpolmask = *newmask;
                break;
-       case MPOL_BIND: {
-               nodemask_t nodes;
-               struct zone **z;
-               struct zonelist *zonelist;
-
-               nodes_clear(nodes);
-               for (z = pol->v.zonelist->zones; *z; z++)
-                       node_set(zone_to_nid(*z), nodes);
-               nodes_remap(tmp, nodes, *mpolmask, *newmask);
-               nodes = tmp;
-
-               zonelist = bind_zonelist(&nodes);
-
-               /* If no mem, then zonelist is NULL and we keep old zonelist.
-                * If that old zonelist has no remaining mems_allowed nodes,
-                * then zonelist_policy() will "FALL THROUGH" to MPOL_DEFAULT.
-                */
-
-               if (!IS_ERR(zonelist)) {
-                       /* Good - got mem - substitute new zonelist */
-                       kfree(pol->v.zonelist);
-                       pol->v.zonelist = zonelist;
-               }
-               *mpolmask = *newmask;
-               break;
-       }
        default:
                BUG();
                break;
@@ -1842,7 +1846,7 @@ static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol)
        char *p = buffer;
        int l;
        nodemask_t nodes;
-       int mode = pol ? pol->policy : MPOL_DEFAULT;
+       unsigned short mode = pol ? pol->policy : MPOL_DEFAULT;
 
        switch (mode) {
        case MPOL_DEFAULT:
@@ -1855,9 +1859,7 @@ static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol)
                break;
 
        case MPOL_BIND:
-               get_zonemask(pol, &nodes);
-               break;
-
+               /* Fall through */
        case MPOL_INTERLEAVE:
                nodes = pol->v.nodes;
                break;
@@ -1985,7 +1987,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 &&