We're not allowed to do down_read() on the filemap_copy_from_user() path: the caller has an atomic kmap. Just fail the copy and let the filemap_copy_from_user() slow path recover. mm/usercopy.c | 9 +++++++++ 1 files changed, 9 insertions(+) diff -puN mm/usercopy.c~4g4g-pin_page-atomicity-fix mm/usercopy.c --- 25/mm/usercopy.c~4g4g-pin_page-atomicity-fix 2003-08-03 21:06:24.000000000 -0700 +++ 25-akpm/mm/usercopy.c 2003-08-03 21:08:20.000000000 -0700 @@ -46,6 +46,15 @@ static inline struct page *pin_page(unsi */ spin_unlock(&mm->page_table_lock); + /* + * In the context of filemap_copy_from_user(), we are not allowed + * to sleep. We must fail this usercopy attempt and allow + * filemap_copy_from_user() to recover: drop its atomic kmap and use + * a sleeping kmap instead. + */ + if (in_atomic()) + return NULL; + down_read(&mm->mmap_sem); ret = get_user_pages(current, mm, addr, 1, write, 0, &page, NULL); up_read(&mm->mmap_sem); _