Instead of all of these games with dropping and reacquiring mmap_sem and adding other locks, or deferring the work, why don't we just do a get_user_pages()? Something along the lines of: while (1) { ret = cmpxchg(addr) if (!ret) break; if (ret == -EFAULT) get_user_pages(addr); } Does anybody see a problem with that?