aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mempolicy.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r--mm/mempolicy.c54
1 files changed, 37 insertions, 17 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 8778f58880c4..e07e27e846a2 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
@@ -627,6 +632,10 @@ int do_migrate_pages(struct mm_struct *mm,
627 632
628 down_read(&mm->mmap_sem); 633 down_read(&mm->mmap_sem);
629 634
635 err = migrate_vmas(mm, from_nodes, to_nodes, flags);
636 if (err)
637 goto out;
638
630/* 639/*
631 * Find a 'source' bit set in 'tmp' whose corresponding 'dest' 640 * Find a 'source' bit set in 'tmp' whose corresponding 'dest'
632 * bit in 'to' is not also set in 'tmp'. Clear the found 'source' 641 * bit in 'to' is not also set in 'tmp'. Clear the found 'source'
@@ -686,7 +695,7 @@ int do_migrate_pages(struct mm_struct *mm,
686 if (err < 0) 695 if (err < 0)
687 break; 696 break;
688 } 697 }
689 698out:
690 up_read(&mm->mmap_sem); 699 up_read(&mm->mmap_sem);
691 if (err < 0) 700 if (err < 0)
692 return err; 701 return err;
@@ -694,6 +703,12 @@ int do_migrate_pages(struct mm_struct *mm,
694 703
695} 704}
696 705
706static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
707{
708 struct vm_area_struct *vma = (struct vm_area_struct *)private;
709
710 return alloc_page_vma(GFP_HIGHUSER, vma, page_address_in_vma(page, vma));
711}
697#else 712#else
698 713
699static void migrate_page_add(struct page *page, struct list_head *pagelist, 714static void migrate_page_add(struct page *page, struct list_head *pagelist,
@@ -706,6 +721,11 @@ int do_migrate_pages(struct mm_struct *mm,
706{ 721{
707 return -ENOSYS; 722 return -ENOSYS;
708} 723}
724
725static struct page *new_vma_page(struct page *page, unsigned long private)
726{
727 return NULL;
728}
709#endif 729#endif
710 730
711long do_mbind(unsigned long start, unsigned long len, 731long do_mbind(unsigned long start, unsigned long len,
@@ -767,15 +787,13 @@ long do_mbind(unsigned long start, unsigned long len,
767 err = mbind_range(vma, start, end, new); 787 err = mbind_range(vma, start, end, new);
768 788
769 if (!list_empty(&pagelist)) 789 if (!list_empty(&pagelist))
770 nr_failed = migrate_pages_to(&pagelist, vma, -1); 790 nr_failed = migrate_pages(&pagelist, new_vma_page,
791 (unsigned long)vma);
771 792
772 if (!err && nr_failed && (flags & MPOL_MF_STRICT)) 793 if (!err && nr_failed && (flags & MPOL_MF_STRICT))
773 err = -EIO; 794 err = -EIO;
774 } 795 }
775 796
776 if (!list_empty(&pagelist))
777 putback_lru_pages(&pagelist);
778
779 up_write(&mm->mmap_sem); 797 up_write(&mm->mmap_sem);
780 mpol_free(new); 798 mpol_free(new);
781 return err; 799 return err;
@@ -929,6 +947,10 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
929 goto out; 947 goto out;
930 } 948 }
931 949
950 err = security_task_movememory(task);
951 if (err)
952 goto out;
953
932 err = do_migrate_pages(mm, &old, &new, 954 err = do_migrate_pages(mm, &old, &new,
933 capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); 955 capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE);
934out: 956out:
@@ -1187,10 +1209,8 @@ static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
1187 1209
1188 zl = NODE_DATA(nid)->node_zonelists + gfp_zone(gfp); 1210 zl = NODE_DATA(nid)->node_zonelists + gfp_zone(gfp);
1189 page = __alloc_pages(gfp, order, zl); 1211 page = __alloc_pages(gfp, order, zl);
1190 if (page && page_zone(page) == zl->zones[0]) { 1212 if (page && page_zone(page) == zl->zones[0])
1191 zone_pcp(zl->zones[0],get_cpu())->interleave_hit++; 1213 inc_zone_page_state(page, NUMA_INTERLEAVE_HIT);
1192 put_cpu();
1193 }
1194 return page; 1214 return page;
1195} 1215}
1196 1216
@@ -1799,7 +1819,7 @@ static inline void check_huge_range(struct vm_area_struct *vma,
1799 1819
1800int show_numa_map(struct seq_file *m, void *v) 1820int show_numa_map(struct seq_file *m, void *v)
1801{ 1821{
1802 struct task_struct *task = m->private; 1822 struct proc_maps_private *priv = m->private;
1803 struct vm_area_struct *vma = v; 1823 struct vm_area_struct *vma = v;
1804 struct numa_maps *md; 1824 struct numa_maps *md;
1805 struct file *file = vma->vm_file; 1825 struct file *file = vma->vm_file;
@@ -1815,7 +1835,7 @@ int show_numa_map(struct seq_file *m, void *v)
1815 return 0; 1835 return 0;
1816 1836
1817 mpol_to_str(buffer, sizeof(buffer), 1837 mpol_to_str(buffer, sizeof(buffer),
1818 get_vma_policy(task, vma, vma->vm_start)); 1838 get_vma_policy(priv->task, vma, vma->vm_start));
1819 1839
1820 seq_printf(m, "%08lx %s", vma->vm_start, buffer); 1840 seq_printf(m, "%08lx %s", vma->vm_start, buffer);
1821 1841
@@ -1869,7 +1889,7 @@ out:
1869 kfree(md); 1889 kfree(md);
1870 1890
1871 if (m->count < m->size) 1891 if (m->count < m->size)
1872 m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0; 1892 m->version = (vma != priv->tail_vma) ? vma->vm_start : 0;
1873 return 0; 1893 return 0;
1874} 1894}
1875 1895