[PATCH] page migration: handle freeing of pages in migrate_pages()
[pandora-kernel.git] / mm / mempolicy.c
index e93cc74..244f3f1 100644 (file)
@@ -422,6 +422,37 @@ static int contextualize_policy(int mode, nodemask_t *nodes)
        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
+ * with other PF_* flag bits) on memory allocation hot code paths.
+ *
+ * If called from outside this file, the task 'p' should -only- be
+ * a newly forked child not yet visible on the task list, because
+ * manipulating the task flags of a visible task is not safe.
+ *
+ * The above limitation is why this routine has the funny name
+ * mpol_fix_fork_child_flag().
+ *
+ * It is also safe to call this with a task pointer of current,
+ * which the static wrapper mpol_set_task_struct_flag() does,
+ * for use within this file.
+ */
+
+void mpol_fix_fork_child_flag(struct task_struct *p)
+{
+       if (p->mempolicy)
+               p->flags |= PF_MEMPOLICY;
+       else
+               p->flags &= ~PF_MEMPOLICY;
+}
+
+static void mpol_set_task_struct_flag(void)
+{
+       mpol_fix_fork_child_flag(current);
+}
+
 /* Set the process memory policy */
 long do_set_mempolicy(int mode, nodemask_t *nodes)
 {
@@ -434,6 +465,7 @@ long do_set_mempolicy(int mode, nodemask_t *nodes)
                return PTR_ERR(new);
        mpol_free(current->mempolicy);
        current->mempolicy = new;
+       mpol_set_task_struct_flag();
        if (new && new->policy == MPOL_INTERLEAVE)
                current->il_next = first_node(new->v.nodes);
        return 0;
@@ -571,11 +603,8 @@ int migrate_to_node(struct mm_struct *mm, int source, int dest, int flags)
        check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nmask,
                        flags | MPOL_MF_DISCONTIG_OK, &pagelist);
 
-       if (!list_empty(&pagelist)) {
+       if (!list_empty(&pagelist))
                err = migrate_pages_to(&pagelist, NULL, dest);
-               if (!list_empty(&pagelist))
-                       putback_lru_pages(&pagelist);
-       }
        return err;
 }
 
@@ -741,9 +770,6 @@ long do_mbind(unsigned long start, unsigned long len,
                        err = -EIO;
        }
 
-       if (!list_empty(&pagelist))
-               putback_lru_pages(&pagelist);
-
        up_write(&mm->mmap_sem);
        mpol_free(new);
        return err;
@@ -880,7 +906,7 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
        /*
         * Check if this process has the right to modify the specified
         * process. The right exists if the process has administrative
-        * capabilities, superuser priviledges or the same
+        * capabilities, superuser privileges or the same
         * userid as the target process.
         */
        if ((current->euid != task->suid) && (current->euid != task->uid) &&
@@ -1729,7 +1755,6 @@ static void gather_stats(struct page *page, void *private, int pte_dirty)
                md->mapcount_max = count;
 
        md->node[page_to_nid(page)]++;
-       cond_resched();
 }
 
 #ifdef CONFIG_HUGETLB_PAGE