summaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-05 06:30:28 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-05 06:30:28 +0200
commita1fde08c74e90accd62d4cfdbf580d2ede938fe7 (patch)
treebdf58078fd37484729e350acb066dc1b1fa890ee /mm/memory.c
parentMerge branch 'staging-linus' of git://git.kernel.org/pub/scm/linux/kernel/git... (diff)
downloadlinux-a1fde08c74e90accd62d4cfdbf580d2ede938fe7.tar.xz
linux-a1fde08c74e90accd62d4cfdbf580d2ede938fe7.zip
VM: skip the stack guard page lookup in get_user_pages only for mlock
The logic in __get_user_pages() used to skip the stack guard page lookup whenever the caller wasn't interested in seeing what the actual page was. But Michel Lespinasse points out that there are cases where we don't care about the physical page itself (so 'pages' may be NULL), but do want to make sure a page is mapped into the virtual address space. So using the existence of the "pages" array as an indication of whether to look up the guard page or not isn't actually so great, and we really should just use the FOLL_MLOCK bit. But because that bit was only set for the VM_LOCKED case (and not all vma's necessarily have it, even for mlock()), we couldn't do that originally. Fix that by moving the VM_LOCKED check deeper into the call-chain, which actually simplifies many things. Now mlock() gets simpler, and we can also check for FOLL_MLOCK in __get_user_pages() and the code ends up much more straightforward. Reported-and-reviewed-by: Michel Lespinasse <walken@google.com> Cc: stable@kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 607098d47e74..27f425378112 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1359,7 +1359,7 @@ split_fallthrough:
*/
mark_page_accessed(page);
}
- if (flags & FOLL_MLOCK) {
+ if ((flags & FOLL_MLOCK) && (vma->vm_flags & VM_LOCKED)) {
/*
* The preliminary mapping check is mainly to avoid the
* pointless overhead of lock_page on the ZERO_PAGE
@@ -1552,10 +1552,9 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
}
/*
- * If we don't actually want the page itself,
- * and it's the stack guard page, just skip it.
+ * For mlock, just skip the stack guard page.
*/
- if (!pages && stack_guard_page(vma, start))
+ if ((gup_flags & FOLL_MLOCK) && stack_guard_page(vma, start))
goto next_page;
do {