Like do_wp_page(), __replace_page() should do munlock_vma_page()
for the case when the old page still has other !VM_LOCKED mappings.
Unfortunately this needs mm/internal.h.

Also, move put_page() outside of ptl lock. This doesn't really
matter but looks a bit better.

Signed-off-by: Oleg Nesterov <o...@redhat.com>
Acked-by: Srikar Dronamraju <srikar.vnet.ibm.com>
---
 kernel/events/uprobes.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 5c8ceaf..940005d 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -32,6 +32,7 @@
 #include <linux/swap.h>                /* try_to_free_swap */
 #include <linux/ptrace.h>      /* user_enable_single_step */
 #include <linux/kdebug.h>      /* notifier mechanism */
+#include "../../mm/internal.h" /* munlock_vma_page */
 
 #include <linux/uprobes.h>
 
@@ -141,7 +142,7 @@ static int __replace_page(struct vm_area_struct *vma, 
unsigned long addr,
        pte_t *ptep;
        int err;
 
-       /* freeze PageSwapCache() for try_to_free_swap() below */
+       /* For try_to_free_swap() and munlock_vma_page() below */
        lock_page(page);
 
        err = -EAGAIN;
@@ -164,9 +165,12 @@ static int __replace_page(struct vm_area_struct *vma, 
unsigned long addr,
        page_remove_rmap(page);
        if (!page_mapped(page))
                try_to_free_swap(page);
-       put_page(page);
        pte_unmap_unlock(ptep, ptl);
 
+       if (vma->vm_flags & VM_LOCKED)
+               munlock_vma_page(page);
+       put_page(page);
+
        err = 0;
  unlock:
        unlock_page(page);
-- 
1.5.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to