diff options
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r-- | mm/mempolicy.c | 36 |
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 | ||
592 | static 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 | ||
702 | static 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 | ||
699 | static void migrate_page_add(struct page *page, struct list_head *pagelist, | 710 | static 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 | |||
721 | static struct page *new_vma_page(struct page *page, unsigned long private) | ||
722 | { | ||
723 | return NULL; | ||
724 | } | ||
709 | #endif | 725 | #endif |
710 | 726 | ||
711 | long do_mbind(unsigned long start, unsigned long len, | 727 | long 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); |
934 | out: | 952 | out: |