--- include/linux/mm.h | 1 + mm/memory.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) Index: linux-2.6/include/linux/mm.h =================================================================== --- linux-2.6.orig/include/linux/mm.h 2008-02-14 18:59:12.000000000 -0800 +++ linux-2.6/include/linux/mm.h 2008-02-14 18:59:31.000000000 -0800 @@ -1147,6 +1147,7 @@ struct page *follow_page(struct vm_area_ #define FOLL_TOUCH 0x02 /* mark page accessed */ #define FOLL_GET 0x04 /* do get_page on page */ #define FOLL_ANON 0x08 /* give ZERO_PAGE if no pgtable */ +#define FOLL_LOCK 0x08 /* attempt to lock the page */ typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, void *data); Index: linux-2.6/mm/memory.c =================================================================== --- linux-2.6.orig/mm/memory.c 2008-02-14 18:59:12.000000000 -0800 +++ linux-2.6/mm/memory.c 2008-02-14 19:10:00.000000000 -0800 @@ -975,6 +975,15 @@ struct page *follow_page(struct vm_area_ set_page_dirty(page); mark_page_accessed(page); } + + if (flags & FOLL_LOCK) { + if (TestSetPageLocked(page)) { + if (flags & FOLL_GET) + put_page(page); + page = NULL; + } + } + unlock: pte_unmap_unlock(ptep, ptl); out: @@ -1068,6 +1077,10 @@ int get_user_pages(struct task_struct *t foll_flags = FOLL_TOUCH; if (pages) foll_flags |= FOLL_GET; + + if (lock) + foll_flags |= FOLL_LOCK; + if (!write && !(vma->vm_flags & VM_LOCKED) && (!vma->vm_ops || (!vma->vm_ops->nopage && !vma->vm_ops->fault)))