Skip to content

Commit

Permalink
[PATCH] mm: fix madvise vma merging
Browse files Browse the repository at this point in the history
Better late than never, I've at last reviewed the madvise vma merging
going into 2.6.13.  Remove a pointless check and fix two little bugs -
a simple test (with /proc/<pid>/maps hacked to show ReadHints) showed
both mismerges in practice: though being madvise, neither was disastrous.

1. Correct placement of the success label in madvise_behavior: as in
   mprotect_fixup and mlock_fixup, it is necessary to update vm_flags
   when vma_merge succeeds (to handle the exceptional Case 8 noted in
   the comments above vma_merge itself).

2. Correct initial value of prev when starting part way into a vma: as
   in sys_mprotect and do_mlock, it needs to be set to vma in this case
   (vma_merge handles only that minimum of cases shown in its comments).

3. If find_vma_prev sets prev, then the vma it returns is prev->vm_next,
   so it's pointless to make that same assignment again in sys_madvise.

Signed-off-by: Hugh Dickins <hugh@veritas.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Hugh Dickins authored and Linus Torvalds committed Sep 5, 2005
1 parent 53e9a61 commit 836d5ff
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions mm/madvise.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static long madvise_behavior(struct vm_area_struct * vma,

if (new_flags == vma->vm_flags) {
*prev = vma;
goto success;
goto out;
}

pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
Expand All @@ -62,6 +62,7 @@ static long madvise_behavior(struct vm_area_struct * vma,
goto out;
}

success:
/*
* vm_flags is protected by the mmap_sem held in write mode.
*/
Expand All @@ -70,7 +71,6 @@ static long madvise_behavior(struct vm_area_struct * vma,
out:
if (error == -ENOMEM)
error = -EAGAIN;
success:
return error;
}

Expand Down Expand Up @@ -237,8 +237,9 @@ asmlinkage long sys_madvise(unsigned long start, size_t len_in, int behavior)
* - different from the way of handling in mlock etc.
*/
vma = find_vma_prev(current->mm, start, &prev);
if (!vma && prev)
vma = prev->vm_next;
if (vma && start > vma->vm_start)
prev = vma;

for (;;) {
/* Still start < end. */
error = -ENOMEM;
Expand Down

0 comments on commit 836d5ff

Please sign in to comment.