diff options
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r-- | mm/mempolicy.c | 112 |
1 files changed, 69 insertions, 43 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 3cec080faa23..643f66e10187 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -563,24 +563,50 @@ static int policy_vma(struct vm_area_struct *vma, struct mempolicy *new) | |||
563 | } | 563 | } |
564 | 564 | ||
565 | /* Step 2: apply policy to a range and do splits. */ | 565 | /* Step 2: apply policy to a range and do splits. */ |
566 | static int mbind_range(struct vm_area_struct *vma, unsigned long start, | 566 | static int mbind_range(struct mm_struct *mm, unsigned long start, |
567 | unsigned long end, struct mempolicy *new) | 567 | unsigned long end, struct mempolicy *new_pol) |
568 | { | 568 | { |
569 | struct vm_area_struct *next; | 569 | struct vm_area_struct *next; |
570 | int err; | 570 | struct vm_area_struct *prev; |
571 | struct vm_area_struct *vma; | ||
572 | int err = 0; | ||
573 | pgoff_t pgoff; | ||
574 | unsigned long vmstart; | ||
575 | unsigned long vmend; | ||
571 | 576 | ||
572 | err = 0; | 577 | vma = find_vma_prev(mm, start, &prev); |
573 | for (; vma && vma->vm_start < end; vma = next) { | 578 | if (!vma || vma->vm_start > start) |
579 | return -EFAULT; | ||
580 | |||
581 | for (; vma && vma->vm_start < end; prev = vma, vma = next) { | ||
574 | next = vma->vm_next; | 582 | next = vma->vm_next; |
575 | if (vma->vm_start < start) | 583 | vmstart = max(start, vma->vm_start); |
576 | err = split_vma(vma->vm_mm, vma, start, 1); | 584 | vmend = min(end, vma->vm_end); |
577 | if (!err && vma->vm_end > end) | 585 | |
578 | err = split_vma(vma->vm_mm, vma, end, 0); | 586 | pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); |
579 | if (!err) | 587 | prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags, |
580 | err = policy_vma(vma, new); | 588 | vma->anon_vma, vma->vm_file, pgoff, new_pol); |
589 | if (prev) { | ||
590 | vma = prev; | ||
591 | next = vma->vm_next; | ||
592 | continue; | ||
593 | } | ||
594 | if (vma->vm_start != vmstart) { | ||
595 | err = split_vma(vma->vm_mm, vma, vmstart, 1); | ||
596 | if (err) | ||
597 | goto out; | ||
598 | } | ||
599 | if (vma->vm_end != vmend) { | ||
600 | err = split_vma(vma->vm_mm, vma, vmend, 0); | ||
601 | if (err) | ||
602 | goto out; | ||
603 | } | ||
604 | err = policy_vma(vma, new_pol); | ||
581 | if (err) | 605 | if (err) |
582 | break; | 606 | goto out; |
583 | } | 607 | } |
608 | |||
609 | out: | ||
584 | return err; | 610 | return err; |
585 | } | 611 | } |
586 | 612 | ||
@@ -862,36 +888,36 @@ int do_migrate_pages(struct mm_struct *mm, | |||
862 | if (err) | 888 | if (err) |
863 | goto out; | 889 | goto out; |
864 | 890 | ||
865 | /* | 891 | /* |
866 | * Find a 'source' bit set in 'tmp' whose corresponding 'dest' | 892 | * Find a 'source' bit set in 'tmp' whose corresponding 'dest' |
867 | * bit in 'to' is not also set in 'tmp'. Clear the found 'source' | 893 | * bit in 'to' is not also set in 'tmp'. Clear the found 'source' |
868 | * bit in 'tmp', and return that <source, dest> pair for migration. | 894 | * bit in 'tmp', and return that <source, dest> pair for migration. |
869 | * The pair of nodemasks 'to' and 'from' define the map. | 895 | * The pair of nodemasks 'to' and 'from' define the map. |
870 | * | 896 | * |
871 | * If no pair of bits is found that way, fallback to picking some | 897 | * If no pair of bits is found that way, fallback to picking some |
872 | * pair of 'source' and 'dest' bits that are not the same. If the | 898 | * pair of 'source' and 'dest' bits that are not the same. If the |
873 | * 'source' and 'dest' bits are the same, this represents a node | 899 | * 'source' and 'dest' bits are the same, this represents a node |
874 | * that will be migrating to itself, so no pages need move. | 900 | * that will be migrating to itself, so no pages need move. |
875 | * | 901 | * |
876 | * If no bits are left in 'tmp', or if all remaining bits left | 902 | * If no bits are left in 'tmp', or if all remaining bits left |
877 | * in 'tmp' correspond to the same bit in 'to', return false | 903 | * in 'tmp' correspond to the same bit in 'to', return false |
878 | * (nothing left to migrate). | 904 | * (nothing left to migrate). |
879 | * | 905 | * |
880 | * This lets us pick a pair of nodes to migrate between, such that | 906 | * This lets us pick a pair of nodes to migrate between, such that |
881 | * if possible the dest node is not already occupied by some other | 907 | * if possible the dest node is not already occupied by some other |
882 | * source node, minimizing the risk of overloading the memory on a | 908 | * source node, minimizing the risk of overloading the memory on a |
883 | * node that would happen if we migrated incoming memory to a node | 909 | * node that would happen if we migrated incoming memory to a node |
884 | * before migrating outgoing memory source that same node. | 910 | * before migrating outgoing memory source that same node. |
885 | * | 911 | * |
886 | * A single scan of tmp is sufficient. As we go, we remember the | 912 | * A single scan of tmp is sufficient. As we go, we remember the |
887 | * most recent <s, d> pair that moved (s != d). If we find a pair | 913 | * most recent <s, d> pair that moved (s != d). If we find a pair |
888 | * that not only moved, but what's better, moved to an empty slot | 914 | * that not only moved, but what's better, moved to an empty slot |
889 | * (d is not set in tmp), then we break out then, with that pair. | 915 | * (d is not set in tmp), then we break out then, with that pair. |
890 | * Otherwise when we finish scannng from_tmp, we at least have the | 916 | * Otherwise when we finish scannng from_tmp, we at least have the |
891 | * most recent <s, d> pair that moved. If we get all the way through | 917 | * most recent <s, d> pair that moved. If we get all the way through |
892 | * the scan of tmp without finding any node that moved, much less | 918 | * the scan of tmp without finding any node that moved, much less |
893 | * moved to an empty node, then there is nothing left worth migrating. | 919 | * moved to an empty node, then there is nothing left worth migrating. |
894 | */ | 920 | */ |
895 | 921 | ||
896 | tmp = *from_nodes; | 922 | tmp = *from_nodes; |
897 | while (!nodes_empty(tmp)) { | 923 | while (!nodes_empty(tmp)) { |
@@ -1047,7 +1073,7 @@ static long do_mbind(unsigned long start, unsigned long len, | |||
1047 | if (!IS_ERR(vma)) { | 1073 | if (!IS_ERR(vma)) { |
1048 | int nr_failed = 0; | 1074 | int nr_failed = 0; |
1049 | 1075 | ||
1050 | err = mbind_range(vma, start, end, new); | 1076 | err = mbind_range(mm, start, end, new); |
1051 | 1077 | ||
1052 | if (!list_empty(&pagelist)) | 1078 | if (!list_empty(&pagelist)) |
1053 | nr_failed = migrate_pages(&pagelist, new_vma_page, | 1079 | nr_failed = migrate_pages(&pagelist, new_vma_page, |