From: Andrew Morton <akpm@linux-foundation.org>
To: Michel Lespinasse <walken@google.com>
Cc: Rik van Riel <riel@redhat.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
linux-mm@kvack.org, Ying Han <yinghan@google.com>,
linux-kernel@vger.kernel.org, Nick Piggin <npiggin@kernel.dk>,
Peter Zijlstra <peterz@infradead.org>
Subject: Re: [PATCH 2/3] Retry page fault when blocking on disk transfer.
Date: Mon, 11 Oct 2010 15:25:34 -0700 [thread overview]
Message-ID: <20101011152534.6cf01208.akpm@linux-foundation.org> (raw)
In-Reply-To: <20101009012204.GA17458@google.com>
On Fri, 8 Oct 2010 18:22:04 -0700
Michel Lespinasse <walken@google.com> wrote:
> Second try on adding the VM_FAULT_RETRY functionality to the swap in path.
>
> This proposal would replace [patch 2/3] of this series (the initial
> version of it, which was approved by linus / rik / hpa).
>
> Changes since the approved version:
>
> - split lock_page_or_retry() into an inline function in pagemap.h,
> handling the trylock_page() fast path, and __lock_page_or_retry() in
> filemap.c, handling the blocking path (with or without retry).
>
> - make do_swap_page() call lock_page_or_retry() in place of lock_page(),
> and handle the retry case.
Replacement patches are a bit cruel to people who've already reviewed
the previous version. I always turn them into deltas so I can see what
was changed. It is below.
How well was the new swapin path tested?
include/linux/pagemap.h | 13 +++++++++++++
mm/filemap.c | 35 ++++++++++++++---------------------
mm/memory.c | 7 ++++++-
3 files changed, 33 insertions(+), 22 deletions(-)
diff -puN include/linux/pagemap.h~mm-retry-page-fault-when-blocking-on-disk-transfer-update include/linux/pagemap.h
--- a/include/linux/pagemap.h~mm-retry-page-fault-when-blocking-on-disk-transfer-update
+++ a/include/linux/pagemap.h
@@ -299,6 +299,8 @@ static inline pgoff_t linear_page_index(
extern void __lock_page(struct page *page);
extern int __lock_page_killable(struct page *page);
extern void __lock_page_nosync(struct page *page);
+extern int __lock_page_or_retry(struct page *page, struct mm_struct *mm,
+ unsigned int flags);
extern void unlock_page(struct page *page);
static inline void __set_page_locked(struct page *page)
@@ -351,6 +353,17 @@ static inline void lock_page_nosync(stru
}
/*
+ * lock_page_or_retry - Lock the page, unless this would block and the
+ * caller indicated that it can handle a retry.
+ */
+static inline int lock_page_or_retry(struct page *page, struct mm_struct *mm,
+ unsigned int flags)
+{
+ might_sleep();
+ return trylock_page(page) || __lock_page_or_retry(page, mm, flags);
+}
+
+/*
* This is exported only for wait_on_page_locked/wait_on_page_writeback.
* Never use this directly!
*/
diff -puN mm/filemap.c~mm-retry-page-fault-when-blocking-on-disk-transfer-update mm/filemap.c
--- a/mm/filemap.c~mm-retry-page-fault-when-blocking-on-disk-transfer-update
+++ a/mm/filemap.c
@@ -623,6 +623,19 @@ void __lock_page_nosync(struct page *pag
TASK_UNINTERRUPTIBLE);
}
+int __lock_page_or_retry(struct page *page, struct mm_struct *mm,
+ unsigned int flags)
+{
+ if (!(flags & FAULT_FLAG_ALLOW_RETRY)) {
+ __lock_page(page);
+ return 1;
+ } else {
+ up_read(&mm->mmap_sem);
+ wait_on_page_locked(page);
+ return 0;
+ }
+}
+
/**
* find_get_page - find and get a page reference
* @mapping: the address_space to search
@@ -1512,26 +1525,6 @@ static void do_async_mmap_readahead(stru
page, offset, ra->ra_pages);
}
-/*
- * Lock the page, unless this would block and the caller indicated that it
- * can handle a retry.
- */
-static int lock_page_or_retry(struct page *page,
- struct vm_area_struct *vma, struct vm_fault *vmf)
-{
- if (trylock_page(page))
- return 1;
- if (!(vmf->flags & FAULT_FLAG_ALLOW_RETRY)) {
- __lock_page(page);
- return 1;
- }
-
- up_read(&vma->vm_mm->mmap_sem);
- wait_on_page_locked(page);
- page_cache_release(page);
- return 0;
-}
-
/**
* filemap_fault - read in file data for page fault handling
* @vma: vma in which the fault was taken
@@ -1581,7 +1574,7 @@ retry_find:
goto no_cached_page;
}
- if (!lock_page_or_retry(page, vma, vmf))
+ if (!lock_page_or_retry(page, &vma->vm_mm, vmf->flags))
return ret | VM_FAULT_RETRY;
/* Did it get truncated? */
diff -puN mm/memory.c~mm-retry-page-fault-when-blocking-on-disk-transfer-update mm/memory.c
--- a/mm/memory.c~mm-retry-page-fault-when-blocking-on-disk-transfer-update
+++ a/mm/memory.c
@@ -2627,6 +2627,7 @@ static int do_swap_page(struct mm_struct
struct page *page, *swapcache = NULL;
swp_entry_t entry;
pte_t pte;
+ int locked;
struct mem_cgroup *ptr = NULL;
int exclusive = 0;
int ret = 0;
@@ -2677,8 +2678,12 @@ static int do_swap_page(struct mm_struct
goto out_release;
}
- lock_page(page);
+ locked = lock_page_or_retry(page, mm, flags);
delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
+ if (!locked) {
+ ret |= VM_FAULT_RETRY;
+ goto out_release;
+ }
/*
* Make sure try_to_free_swap or reuse_swap_page or swapoff did not
_
WARNING: multiple messages have this Message-ID (diff)
From: Andrew Morton <akpm@linux-foundation.org>
To: Michel Lespinasse <walken@google.com>
Cc: Rik van Riel <riel@redhat.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
linux-mm@kvack.org, Ying Han <yinghan@google.com>,
linux-kernel@vger.kernel.org, Nick Piggin <npiggin@kernel.dk>,
Peter Zijlstra <peterz@infradead.org>
Subject: Re: [PATCH 2/3] Retry page fault when blocking on disk transfer.
Date: Mon, 11 Oct 2010 15:25:34 -0700 [thread overview]
Message-ID: <20101011152534.6cf01208.akpm@linux-foundation.org> (raw)
In-Reply-To: <20101009012204.GA17458@google.com>
On Fri, 8 Oct 2010 18:22:04 -0700
Michel Lespinasse <walken@google.com> wrote:
> Second try on adding the VM_FAULT_RETRY functionality to the swap in path.
>
> This proposal would replace [patch 2/3] of this series (the initial
> version of it, which was approved by linus / rik / hpa).
>
> Changes since the approved version:
>
> - split lock_page_or_retry() into an inline function in pagemap.h,
> handling the trylock_page() fast path, and __lock_page_or_retry() in
> filemap.c, handling the blocking path (with or without retry).
>
> - make do_swap_page() call lock_page_or_retry() in place of lock_page(),
> and handle the retry case.
Replacement patches are a bit cruel to people who've already reviewed
the previous version. I always turn them into deltas so I can see what
was changed. It is below.
How well was the new swapin path tested?
include/linux/pagemap.h | 13 +++++++++++++
mm/filemap.c | 35 ++++++++++++++---------------------
mm/memory.c | 7 ++++++-
3 files changed, 33 insertions(+), 22 deletions(-)
diff -puN include/linux/pagemap.h~mm-retry-page-fault-when-blocking-on-disk-transfer-update include/linux/pagemap.h
--- a/include/linux/pagemap.h~mm-retry-page-fault-when-blocking-on-disk-transfer-update
+++ a/include/linux/pagemap.h
@@ -299,6 +299,8 @@ static inline pgoff_t linear_page_index(
extern void __lock_page(struct page *page);
extern int __lock_page_killable(struct page *page);
extern void __lock_page_nosync(struct page *page);
+extern int __lock_page_or_retry(struct page *page, struct mm_struct *mm,
+ unsigned int flags);
extern void unlock_page(struct page *page);
static inline void __set_page_locked(struct page *page)
@@ -351,6 +353,17 @@ static inline void lock_page_nosync(stru
}
/*
+ * lock_page_or_retry - Lock the page, unless this would block and the
+ * caller indicated that it can handle a retry.
+ */
+static inline int lock_page_or_retry(struct page *page, struct mm_struct *mm,
+ unsigned int flags)
+{
+ might_sleep();
+ return trylock_page(page) || __lock_page_or_retry(page, mm, flags);
+}
+
+/*
* This is exported only for wait_on_page_locked/wait_on_page_writeback.
* Never use this directly!
*/
diff -puN mm/filemap.c~mm-retry-page-fault-when-blocking-on-disk-transfer-update mm/filemap.c
--- a/mm/filemap.c~mm-retry-page-fault-when-blocking-on-disk-transfer-update
+++ a/mm/filemap.c
@@ -623,6 +623,19 @@ void __lock_page_nosync(struct page *pag
TASK_UNINTERRUPTIBLE);
}
+int __lock_page_or_retry(struct page *page, struct mm_struct *mm,
+ unsigned int flags)
+{
+ if (!(flags & FAULT_FLAG_ALLOW_RETRY)) {
+ __lock_page(page);
+ return 1;
+ } else {
+ up_read(&mm->mmap_sem);
+ wait_on_page_locked(page);
+ return 0;
+ }
+}
+
/**
* find_get_page - find and get a page reference
* @mapping: the address_space to search
@@ -1512,26 +1525,6 @@ static void do_async_mmap_readahead(stru
page, offset, ra->ra_pages);
}
-/*
- * Lock the page, unless this would block and the caller indicated that it
- * can handle a retry.
- */
-static int lock_page_or_retry(struct page *page,
- struct vm_area_struct *vma, struct vm_fault *vmf)
-{
- if (trylock_page(page))
- return 1;
- if (!(vmf->flags & FAULT_FLAG_ALLOW_RETRY)) {
- __lock_page(page);
- return 1;
- }
-
- up_read(&vma->vm_mm->mmap_sem);
- wait_on_page_locked(page);
- page_cache_release(page);
- return 0;
-}
-
/**
* filemap_fault - read in file data for page fault handling
* @vma: vma in which the fault was taken
@@ -1581,7 +1574,7 @@ retry_find:
goto no_cached_page;
}
- if (!lock_page_or_retry(page, vma, vmf))
+ if (!lock_page_or_retry(page, &vma->vm_mm, vmf->flags))
return ret | VM_FAULT_RETRY;
/* Did it get truncated? */
diff -puN mm/memory.c~mm-retry-page-fault-when-blocking-on-disk-transfer-update mm/memory.c
--- a/mm/memory.c~mm-retry-page-fault-when-blocking-on-disk-transfer-update
+++ a/mm/memory.c
@@ -2627,6 +2627,7 @@ static int do_swap_page(struct mm_struct
struct page *page, *swapcache = NULL;
swp_entry_t entry;
pte_t pte;
+ int locked;
struct mem_cgroup *ptr = NULL;
int exclusive = 0;
int ret = 0;
@@ -2677,8 +2678,12 @@ static int do_swap_page(struct mm_struct
goto out_release;
}
- lock_page(page);
+ locked = lock_page_or_retry(page, mm, flags);
delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
+ if (!locked) {
+ ret |= VM_FAULT_RETRY;
+ goto out_release;
+ }
/*
* Make sure try_to_free_swap or reuse_swap_page or swapoff did not
_
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2010-10-11 22:25 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-05 7:53 [PATCH 0/3] V2: Reduce mmap_sem hold times during file backed page faults Michel Lespinasse
2010-10-05 7:53 ` Michel Lespinasse
2010-10-05 7:53 ` [PATCH 1/3] filemap_fault: unique path for locking page Michel Lespinasse
2010-10-05 7:53 ` Michel Lespinasse
2010-10-05 17:07 ` Rik van Riel
2010-10-05 17:07 ` Rik van Riel
2010-10-05 7:53 ` [PATCH 2/3] Retry page fault when blocking on disk transfer Michel Lespinasse
2010-10-05 7:53 ` Michel Lespinasse
2010-10-05 17:33 ` Linus Torvalds
2010-10-05 17:33 ` Linus Torvalds
2010-10-05 17:38 ` Rik van Riel
2010-10-05 17:38 ` Rik van Riel
2010-10-05 22:44 ` Michel Lespinasse
2010-10-05 22:44 ` Michel Lespinasse
2010-10-08 4:39 ` Michel Lespinasse
2010-10-08 4:39 ` Michel Lespinasse
2010-10-08 13:24 ` Rik van Riel
2010-10-08 13:24 ` Rik van Riel
2010-10-08 20:06 ` Michel Lespinasse
2010-10-08 20:06 ` Michel Lespinasse
2010-10-09 1:22 ` Michel Lespinasse
2010-10-09 1:22 ` Michel Lespinasse
2010-10-11 22:25 ` Andrew Morton [this message]
2010-10-11 22:25 ` Andrew Morton
2010-10-11 22:43 ` Michel Lespinasse
2010-10-11 22:43 ` Michel Lespinasse
2010-10-13 23:17 ` Andrew Morton
2010-10-13 23:17 ` Andrew Morton
2010-11-02 20:05 ` Michel Lespinasse
2010-11-02 20:11 ` Rik van Riel
2010-10-06 4:02 ` H. Peter Anvin
2010-10-06 4:02 ` H. Peter Anvin
2010-10-05 7:53 ` [PATCH 3/3] access_error API cleanup Michel Lespinasse
2010-10-05 7:53 ` Michel Lespinasse
2010-10-05 19:44 ` Rik van Riel
2010-10-05 19:44 ` Rik van Riel
2010-10-06 4:02 ` H. Peter Anvin
2010-10-06 4:02 ` H. Peter Anvin
2010-10-06 4:14 ` Michel Lespinasse
2010-10-06 4:14 ` Michel Lespinasse
2010-10-06 4:18 ` Andrew Morton
2010-10-06 4:18 ` Andrew Morton
2010-10-06 4:20 ` H. Peter Anvin
2010-10-06 4:20 ` H. Peter Anvin
2010-10-05 14:55 ` [PATCH 0/3] V2: Reduce mmap_sem hold times during file backed page faults Rik van Riel
2010-10-05 14:55 ` Rik van Riel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101011152534.6cf01208.akpm@linux-foundation.org \
--to=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=npiggin@kernel.dk \
--cc=peterz@infradead.org \
--cc=riel@redhat.com \
--cc=torvalds@linux-foundation.org \
--cc=walken@google.com \
--cc=yinghan@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.