aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mempolicy.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r--mm/mempolicy.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index adc395481813..c3fdbcb17658 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -636,6 +636,7 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
636 struct vm_area_struct *prev; 636 struct vm_area_struct *prev;
637 struct vm_area_struct *vma; 637 struct vm_area_struct *vma;
638 int err = 0; 638 int err = 0;
639 pgoff_t pgoff;
639 unsigned long vmstart; 640 unsigned long vmstart;
640 unsigned long vmend; 641 unsigned long vmend;
641 642
@@ -643,13 +644,21 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
643 if (!vma || vma->vm_start > start) 644 if (!vma || vma->vm_start > start)
644 return -EFAULT; 645 return -EFAULT;
645 646
647 if (start > vma->vm_start)
648 prev = vma;
649
646 for (; vma && vma->vm_start < end; prev = vma, vma = next) { 650 for (; vma && vma->vm_start < end; prev = vma, vma = next) {
647 next = vma->vm_next; 651 next = vma->vm_next;
648 vmstart = max(start, vma->vm_start); 652 vmstart = max(start, vma->vm_start);
649 vmend = min(end, vma->vm_end); 653 vmend = min(end, vma->vm_end);
650 654
655 if (mpol_equal(vma_policy(vma), new_pol))
656 continue;
657
658 pgoff = vma->vm_pgoff +
659 ((vmstart - vma->vm_start) >> PAGE_SHIFT);
651 prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags, 660 prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags,
652 vma->anon_vma, vma->vm_file, vma->vm_pgoff, 661 vma->anon_vma, vma->vm_file, pgoff,
653 new_pol); 662 new_pol);
654 if (prev) { 663 if (prev) {
655 vma = prev; 664 vma = prev;