On Wed, Feb 13, 2019 at 11:34:44AM +0800, Peter Xu wrote: > On Tue, Feb 12, 2019 at 10:56:10AM +0800, Peter Xu wrote: > > [...] > > > @@ -1351,7 +1351,7 @@ EXPORT_SYMBOL_GPL(__lock_page_killable); > > int __lock_page_or_retry(struct page *page, struct mm_struct *mm, > > unsigned int flags) > > { > > - if (flags & FAULT_FLAG_ALLOW_RETRY) { > > + if (!flags & FAULT_FLAG_TRIED) { > > Sorry, this should be: > > if (!(flags & FAULT_FLAG_TRIED)) Ok this is problematic too... Because we for sure allow the page fault flags to be both !ALLOW_RETRY and !TRIED (e.g., when doing GUP and when __get_user_pages() is with locked==NULL and !FOLL_NOWAIT). So current code will fall through the if condition and call up_read(mmap_sem) even if above condition happened (while we shouldn't because the GUP caller would assume the mmap_sem should be still held). So the correct check should be: if ((flags & FAULT_FLAG_ALLOW_RETRY) && !(flags & FAULT_FLAG_TRIED)) To make things easier, I'll just repost this single patch later. Sorry for the noise. Regards, -- Peter Xu