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 | 10 ++++++++++ 1 files changed, 10 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-04 00:22:56.000000000 -0700 +++ 25-akpm/mm/usercopy.c 2003-08-04 05:07:01.000000000 -0700 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,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); _