mm/vmalloc.c: eliminate extra loop in pcpu_get_vm_areas error path
[linux-2.6-block.git] / mm / mempolicy.c
index adc395481813532efe82dced222e79115b075b0e..06b145fb64ab59a399344bc73ca277be0e39ed7b 100644 (file)
@@ -636,6 +636,7 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
        struct vm_area_struct *prev;
        struct vm_area_struct *vma;
        int err = 0;
+       pgoff_t pgoff;
        unsigned long vmstart;
        unsigned long vmend;
 
@@ -643,13 +644,21 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
        if (!vma || vma->vm_start > start)
                return -EFAULT;
 
+       if (start > vma->vm_start)
+               prev = vma;
+
        for (; vma && vma->vm_start < end; prev = vma, vma = next) {
                next = vma->vm_next;
                vmstart = max(start, vma->vm_start);
                vmend   = min(end, vma->vm_end);
 
+               if (mpol_equal(vma_policy(vma), new_pol))
+                       continue;
+
+               pgoff = vma->vm_pgoff +
+                       ((vmstart - vma->vm_start) >> PAGE_SHIFT);
                prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags,
-                                 vma->anon_vma, vma->vm_file, vma->vm_pgoff,
+                                 vma->anon_vma, vma->vm_file, pgoff,
                                  new_pol);
                if (prev) {
                        vma = prev;
@@ -933,7 +942,7 @@ static int migrate_to_node(struct mm_struct *mm, int source, int dest,
 
        if (!list_empty(&pagelist)) {
                err = migrate_pages(&pagelist, new_node_page, dest,
-                                                               false, true);
+                                                       false, MIGRATE_SYNC);
                if (err)
                        putback_lru_pages(&pagelist);
        }
@@ -1974,28 +1983,28 @@ struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol,
 }
 
 /* Slow path of a mempolicy comparison */
-int __mpol_equal(struct mempolicy *a, struct mempolicy *b)
+bool __mpol_equal(struct mempolicy *a, struct mempolicy *b)
 {
        if (!a || !b)
-               return 0;
+               return false;
        if (a->mode != b->mode)
-               return 0;
+               return false;
        if (a->flags != b->flags)
-               return 0;
+               return false;
        if (mpol_store_user_nodemask(a))
                if (!nodes_equal(a->w.user_nodemask, b->w.user_nodemask))
-                       return 0;
+                       return false;
 
        switch (a->mode) {
        case MPOL_BIND:
                /* Fall through */
        case MPOL_INTERLEAVE:
-               return nodes_equal(a->v.nodes, b->v.nodes);
+               return !!nodes_equal(a->v.nodes, b->v.nodes);
        case MPOL_PREFERRED:
                return a->v.preferred_node == b->v.preferred_node;
        default:
                BUG();
-               return 0;
+               return false;
        }
 }