[PATCH] Make try_to_unmap() return SWAP_MLOCK for mlocked pages Modify try_to_unmap() so that we can distinguish failing to unmap due to a mlocked page from other causes. Signed-off-by: Christoph Lameter Index: linux-2.6.20/include/linux/rmap.h =================================================================== --- linux-2.6.20.orig/include/linux/rmap.h 2007-02-14 15:47:13.000000000 -0800 +++ linux-2.6.20/include/linux/rmap.h 2007-02-14 16:00:35.000000000 -0800 @@ -134,5 +134,6 @@ #define SWAP_SUCCESS 0 #define SWAP_AGAIN 1 #define SWAP_FAIL 2 +#define SWAP_MLOCK 3 #endif /* _LINUX_RMAP_H */ Index: linux-2.6.20/mm/rmap.c =================================================================== --- linux-2.6.20.orig/mm/rmap.c 2007-02-14 15:47:13.000000000 -0800 +++ linux-2.6.20/mm/rmap.c 2007-02-14 16:00:36.000000000 -0800 @@ -631,10 +631,16 @@ * If it's recently referenced (perhaps page_referenced * skipped over this mm) then we should reactivate it. */ - if (!migration && ((vma->vm_flags & VM_LOCKED) || - (ptep_clear_flush_young(vma, address, pte)))) { - ret = SWAP_FAIL; - goto out_unmap; + if (!migration) { + if (vma->vm_flags & VM_LOCKED) { + ret = SWAP_MLOCK; + goto out_unmap; + } + + if (ptep_clear_flush_young(vma, address, pte)) { + ret = SWAP_FAIL; + goto out_unmap; + } } /* Nuke the page table entry. */ @@ -799,7 +805,8 @@ list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { ret = try_to_unmap_one(page, vma, migration); - if (ret == SWAP_FAIL || !page_mapped(page)) + if (ret == SWAP_FAIL || ret == SWAP_MLOCK || + !page_mapped(page)) break; } spin_unlock(&anon_vma->lock); @@ -830,7 +837,8 @@ spin_lock(&mapping->i_mmap_lock); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { ret = try_to_unmap_one(page, vma, migration); - if (ret == SWAP_FAIL || !page_mapped(page)) + if (ret == SWAP_FAIL || ret == SWAP_MLOCK || + !page_mapped(page)) goto out; } @@ -913,6 +921,7 @@ * SWAP_SUCCESS - we succeeded in removing all mappings * SWAP_AGAIN - we missed a mapping, try again later * SWAP_FAIL - the page is unswappable + * SWAP_MLOCK - the page is under mlock() */ int try_to_unmap(struct page *page, int migration) { Index: linux-2.6.20/mm/vmscan.c =================================================================== --- linux-2.6.20.orig/mm/vmscan.c 2007-02-14 15:47:13.000000000 -0800 +++ linux-2.6.20/mm/vmscan.c 2007-02-14 16:00:36.000000000 -0800 @@ -509,6 +509,7 @@ if (page_mapped(page) && mapping) { switch (try_to_unmap(page, 0)) { case SWAP_FAIL: + case SWAP_MLOCK: goto activate_locked; case SWAP_AGAIN: goto keep_locked;