Merge branch 'master' of git://1984.lsi.us.es/nf
[deliverable/linux.git] / mm / mempolicy.c
index 1763418f1adad41450f6d766efd8173d08312b0b..d04a8a54c294f852f55e624e3c41d1b03b7a56e9 100644 (file)
@@ -946,15 +946,18 @@ static int migrate_to_node(struct mm_struct *mm, int source, int dest,
        nodemask_t nmask;
        LIST_HEAD(pagelist);
        int err = 0;
-       struct vm_area_struct *vma;
 
        nodes_clear(nmask);
        node_set(source, nmask);
 
-       vma = check_range(mm, mm->mmap->vm_start, mm->task_size, &nmask,
+       /*
+        * This does not "check" the range but isolates all pages that
+        * need migration.  Between passing in the full user address
+        * space range and MPOL_MF_DISCONTIG_OK, this call can not fail.
+        */
+       VM_BUG_ON(!(flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)));
+       check_range(mm, mm->mmap->vm_start, mm->task_size, &nmask,
                        flags | MPOL_MF_DISCONTIG_OK, &pagelist);
-       if (IS_ERR(vma))
-               return PTR_ERR(vma);
 
        if (!list_empty(&pagelist)) {
                err = migrate_pages(&pagelist, new_node_page, dest,
@@ -1533,9 +1536,8 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
  *
  * Returns effective policy for a VMA at specified address.
  * Falls back to @task or system default policy, as necessary.
- * Current or other task's task mempolicy and non-shared vma policies
- * are protected by the task's mmap_sem, which must be held for read by
- * the caller.
+ * Current or other task's task mempolicy and non-shared vma policies must be
+ * protected by task_lock(task) by the caller.
  * Shared policies [those marked as MPOL_F_SHARED] require an extra reference
  * count--added by the get_policy() vm_op, as appropriate--to protect against
  * freeing by another task.  It is the caller's responsibility to free the
@@ -1552,8 +1554,18 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
                                                                        addr);
                        if (vpol)
                                pol = vpol;
-               } else if (vma->vm_policy)
+               } else if (vma->vm_policy) {
                        pol = vma->vm_policy;
+
+                       /*
+                        * shmem_alloc_page() passes MPOL_F_SHARED policy with
+                        * a pseudo vma whose vma->vm_ops=NULL. Take a reference
+                        * count on these policies which will be dropped by
+                        * mpol_cond_put() later
+                        */
+                       if (mpol_needs_cond_ref(pol))
+                               mpol_get(pol);
+               }
        }
        if (!pol)
                pol = &default_policy;
This page took 0.0281 seconds and 5 git commands to generate.