aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mempolicy.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r--mm/mempolicy.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 8778f58880c4..ec4a1a950df9 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -87,6 +87,8 @@
87#include <linux/seq_file.h> 87#include <linux/seq_file.h>
88#include <linux/proc_fs.h> 88#include <linux/proc_fs.h>
89#include <linux/migrate.h> 89#include <linux/migrate.h>
90#include <linux/rmap.h>
91#include <linux/security.h>
90 92
91#include <asm/tlbflush.h> 93#include <asm/tlbflush.h>
92#include <asm/uaccess.h> 94#include <asm/uaccess.h>
@@ -587,6 +589,11 @@ static void migrate_page_add(struct page *page, struct list_head *pagelist,
587 isolate_lru_page(page, pagelist); 589 isolate_lru_page(page, pagelist);
588} 590}
589 591
592static struct page *new_node_page(struct page *page, unsigned long node, int **x)
593{
594 return alloc_pages_node(node, GFP_HIGHUSER, 0);
595}
596
590/* 597/*
591 * Migrate pages from one node to a target node. 598 * Migrate pages from one node to a target node.
592 * Returns error or the number of pages not migrated. 599 * Returns error or the number of pages not migrated.
@@ -603,11 +610,9 @@ int migrate_to_node(struct mm_struct *mm, int source, int dest, int flags)
603 check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nmask, 610 check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nmask,
604 flags | MPOL_MF_DISCONTIG_OK, &pagelist); 611 flags | MPOL_MF_DISCONTIG_OK, &pagelist);
605 612
606 if (!list_empty(&pagelist)) { 613 if (!list_empty(&pagelist))
607 err = migrate_pages_to(&pagelist, NULL, dest); 614 err = migrate_pages(&pagelist, new_node_page, dest);
608 if (!list_empty(&pagelist)) 615
609 putback_lru_pages(&pagelist);
610 }
611 return err; 616 return err;
612} 617}
613 618
@@ -694,6 +699,12 @@ int do_migrate_pages(struct mm_struct *mm,
694 699
695} 700}
696 701
702static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
703{
704 struct vm_area_struct *vma = (struct vm_area_struct *)private;
705
706 return alloc_page_vma(GFP_HIGHUSER, vma, page_address_in_vma(page, vma));
707}
697#else 708#else
698 709
699static void migrate_page_add(struct page *page, struct list_head *pagelist, 710static void migrate_page_add(struct page *page, struct list_head *pagelist,
@@ -706,6 +717,11 @@ int do_migrate_pages(struct mm_struct *mm,
706{ 717{
707 return -ENOSYS; 718 return -ENOSYS;
708} 719}
720
721static struct page *new_vma_page(struct page *page, unsigned long private)
722{
723 return NULL;
724}
709#endif 725#endif
710 726
711long do_mbind(unsigned long start, unsigned long len, 727long do_mbind(unsigned long start, unsigned long len,
@@ -767,15 +783,13 @@ long do_mbind(unsigned long start, unsigned long len,
767 err = mbind_range(vma, start, end, new); 783 err = mbind_range(vma, start, end, new);
768 784
769 if (!list_empty(&pagelist)) 785 if (!list_empty(&pagelist))
770 nr_failed = migrate_pages_to(&pagelist, vma, -1); 786 nr_failed = migrate_pages(&pagelist, new_vma_page,
787 (unsigned long)vma);
771 788
772 if (!err && nr_failed && (flags & MPOL_MF_STRICT)) 789 if (!err && nr_failed && (flags & MPOL_MF_STRICT))
773 err = -EIO; 790 err = -EIO;
774 } 791 }
775 792
776 if (!list_empty(&pagelist))
777 putback_lru_pages(&pagelist);
778
779 up_write(&mm->mmap_sem); 793 up_write(&mm->mmap_sem);
780 mpol_free(new); 794 mpol_free(new);
781 return err; 795 return err;
@@ -929,6 +943,10 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
929 goto out; 943 goto out;
930 } 944 }
931 945
946 err = security_task_movememory(task);
947 if (err)
948 goto out;
949
932 err = do_migrate_pages(mm, &old, &new, 950 err = do_migrate_pages(mm, &old, &new,
933 capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); 951 capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE);
934out: 952out: