+ filemap-drop-the-mmap_sem-for-all-blocking-operations-v6.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     Subject: filemap-drop-the-mmap_sem-for-all-blocking-operations-v6
has been added to the -mm tree.  Its filename is
     filemap-drop-the-mmap_sem-for-all-blocking-operations-v6.patch

This patch should soon appear at
    http://ozlabs.org/~akpm/mmots/broken-out/filemap-drop-the-mmap_sem-for-all-blocking-operations-v6.patch
and later at
    http://ozlabs.org/~akpm/mmotm/broken-out/filemap-drop-the-mmap_sem-for-all-blocking-operations-v6.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next and is updated
there every 3-4 working days

------------------------------------------------------
From: Josef Bacik <josef@xxxxxxxxxxxxxx>
Subject: filemap-drop-the-mmap_sem-for-all-blocking-operations-v6

- added more comments as per Andrew's suggestion.
- fixed the fpin leaks in the two error paths that were pointed out.

Link: http://lkml.kernel.org/r/20181212152757.10017-1-josef@xxxxxxxxxxxxxx
Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
Acked-by: Johannes Weiner <hannes@xxxxxxxxxxx>
Reviewed-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Dave Chinner <david@xxxxxxxxxxxxx>
Cc: Jan Kara <jack@xxxxxxx>
Cc: Rik van Riel <riel@xxxxxxxxxx>
Cc: Tejun Heo <tj@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---


--- a/mm/filemap.c~filemap-drop-the-mmap_sem-for-all-blocking-operations-v6
+++ a/mm/filemap.c
@@ -2371,6 +2371,12 @@ static struct file *maybe_unlock_mmap_fo
 	int flags = vmf->flags;
 	if (fpin)
 		return fpin;
+
+	/*
+	 * FAULT_FLAG_RETRY_NOWAIT means we don't want to wait on page locks or
+	 * anything, so we only pin the file and drop the mmap_sem if only
+	 * FAULT_FLAG_ALLOW_RETRY is set.
+	 */
 	if ((flags & (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_RETRY_NOWAIT)) ==
 	    FAULT_FLAG_ALLOW_RETRY) {
 		fpin = get_file(vmf->vma->vm_file);
@@ -2380,10 +2386,15 @@ static struct file *maybe_unlock_mmap_fo
 }
 
 /*
- * Works similar to lock_page_or_retry, except it will pin the file and drop the
- * mmap_sem if necessary and then lock the page, and return 1 in this case.
- * This means the caller needs to deal with the fpin appropriately.  0 return is
- * the same as in lock_page_or_retry.
+ * lock_page_maybe_drop_mmap - lock the page, possibly dropping the mmap_sem
+ * @vmf - the vm_fault for this fault.
+ * @page - the page to lock.
+ * @fpin - the pointer to the file we may pin (or is already pinned).
+ *
+ * This works similar to lock_page_or_retry in that it can drop the mmap_sem.
+ * It differs in that it actually returns the page locked if it returns 1 and 0
+ * if it couldn't lock the page.  If we did have to drop the mmap_sem then fpin
+ * will point to the pinned file and needs to be fput()'ed at a later point.
  */
 static int lock_page_maybe_drop_mmap(struct vm_fault *vmf, struct page *page,
 				     struct file **fpin)
@@ -2391,9 +2402,10 @@ static int lock_page_maybe_drop_mmap(str
 	if (trylock_page(page))
 		return 1;
 
-	*fpin = maybe_unlock_mmap_for_io(vmf, *fpin);
 	if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT)
 		return 0;
+
+	*fpin = maybe_unlock_mmap_for_io(vmf, *fpin);
 	if (vmf->flags & FAULT_FLAG_KILLABLE) {
 		if (__lock_page_killable(page)) {
 			/*
@@ -2413,8 +2425,11 @@ static int lock_page_maybe_drop_mmap(str
 
 
 /*
- * Synchronous readahead happens when we don't even find
- * a page in the page cache at all.
+ * Synchronous readahead happens when we don't even find a page in the page
+ * cache at all.  We don't want to perform IO under the mmap sem, so if we have
+ * to drop the mmap sem we return the file that was pinned in order for us to do
+ * that.  If we didn't pin a file then we return NULL.  The file that is
+ * returned needs to be fput()'ed when we're done with it.
  */
 static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 {
@@ -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;
 			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)) {
_

Patches currently in -mm which might be from josef@xxxxxxxxxxxxxx are

filemap-kill-page_cache_read-usage-in-filemap_fault.patch
filemap-pass-vm_fault-to-the-mmap-ra-helpers.patch
filemap-drop-the-mmap_sem-for-all-blocking-operations.patch
filemap-drop-the-mmap_sem-for-all-blocking-operations-v6.patch




[Index of Archives]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux