On Wed, 12 Dec 2018 10:27:57 -0500 Josef Bacik <josef@xxxxxxxxxxxxxx> wrote: > v5->v6: > - added more comments as per Andrew's suggestion. > - fixed the fpin leaks in the two error paths that were pointed out. > hm, > --- a/mm/filemap.c~filemap-drop-the-mmap_sem-for-all-blocking-operations-v6 > +++ a/mm/filemap.c > @@ -2461,7 +2476,8 @@ static struct file *do_sync_mmap_readahe > > /* > * Asynchronous readahead happens when we find the page and PG_readahead, > - * so we want to possibly extend the readahead further.. > + * so we want to possibly extend the readahead further. We return the file that > + * was pinned if we have to drop the mmap_sem in order to do IO. > */ > static struct file *do_async_mmap_readahead(struct vm_fault *vmf, > struct page *page) > @@ -2545,14 +2561,15 @@ retry_find: > page = pagecache_get_page(mapping, offset, > FGP_CREAT|FGP_FOR_MMAP, > vmf->gfp_mask); > - if (!page) > + if (!page) { > + if (fpin) > + goto out_retry; Is this right? If pagecache_get_page() returns NULL we can now return VM_FAULT_MAJOR|VM_FAULT_RETRY whereas we used to return ENOMEM. > return vmf_error(-ENOMEM); > + } > } > > - if (!lock_page_maybe_drop_mmap(vmf, page, &fpin)) { > - put_page(page); > - return ret | VM_FAULT_RETRY; > - } > + if (!lock_page_maybe_drop_mmap(vmf, page, &fpin)) > + goto out_retry; > > /* Did it get truncated? */ > if (unlikely(page->mapping != mapping)) {