From: Mel Gorman <mel@csn.ul.ie>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Linux-MM <linux-mm@kvack.org>,
LKML <linux-kernel@vger.kernel.org>,
Minchan Kim <minchan.kim@gmail.com>,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
Christoph Lameter <cl@linux.com>,
Andrea Arcangeli <aarcange@redhat.com>,
Rik van Riel <riel@redhat.com>
Subject: Re: [PATCH 1/2] mm,migration: Prevent rmap_walk_[anon|ksm] seeing the wrong VMA information
Date: Wed, 5 May 2010 18:53:11 +0100 [thread overview]
Message-ID: <20100505175311.GU20979@csn.ul.ie> (raw)
In-Reply-To: <alpine.LFD.2.00.1005050815060.5478@i5.linux-foundation.org>
On Wed, May 05, 2010 at 08:31:42AM -0700, Linus Torvalds wrote:
> That said, I do wonder if we could _make_ the ordering reliable. I did
> that for the 'same_vma' one, because I wanted to be able to verify that
> chains were consistent (and we also needed to be able to find the "oldest
> anon_vma" for the case of re-instantiating pages that migth exist in
> multiple different anon_vma's).
>
> Any ideas?
>
If the same_vma list is properly ordered then maybe something like the
following is allowed?
(This patch is on top of mm,migration: Prevent rmap_walk_[anon|ksm]
seeing the wrong VMA information)
At least it booted and did not immediately kill itself during migration.
It's less clear what to do for KSM but I'm ignoring it for the moment.
==== CUT HERE ====
mm,migration: In rmap_walk, always take the locks in the same order
---
include/linux/rmap.h | 32 ++++++++++++++++++++++++++++++++
mm/ksm.c | 5 +----
mm/rmap.c | 13 ++-----------
3 files changed, 35 insertions(+), 15 deletions(-)
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 7721674..749aaca 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -99,6 +99,38 @@ static inline struct anon_vma *page_anon_vma(struct page *page)
return page_rmapping(page);
}
+static inline struct anon_vma *page_anon_vma_lock_oldest(struct page *page)
+{
+ struct anon_vma *anon_vma, *oldest_anon_vma;
+ struct anon_vma_chain *avc, *oldest_avc;
+
+ /* Get the pages anon_vma */
+ if (((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) !=
+ PAGE_MAPPING_ANON)
+ return NULL;
+ anon_vma = page_rmapping(page);
+ if (!anon_vma)
+ return NULL;
+
+ spin_lock(&anon_vma->lock);
+
+ /*
+ * Get the oldest anon_vma on the list by depending on the ordering
+ * of the same_vma list setup by __page_set_anon_rmap
+ */
+ avc = list_entry(&anon_vma->head, struct anon_vma_chain, same_anon_vma);
+ oldest_avc = list_entry(avc->vma->anon_vma_chain.prev,
+ struct anon_vma_chain, same_vma);
+ oldest_anon_vma = oldest_avc->anon_vma;
+
+ if (anon_vma != oldest_anon_vma) {
+ spin_lock(&oldest_anon_vma->lock);
+ spin_unlock(&anon_vma->lock);
+ }
+
+ return oldest_anon_vma;
+}
+
static inline void anon_vma_lock(struct vm_area_struct *vma)
{
struct anon_vma *anon_vma = vma->anon_vma;
diff --git a/mm/ksm.c b/mm/ksm.c
index 0c09927..113f972 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1680,10 +1680,7 @@ again:
locked_vma = NULL;
if (anon_vma != vma->anon_vma) {
locked_vma = vma->anon_vma;
- if (!spin_trylock(&locked_vma->lock)) {
- spin_unlock(&anon_vma->lock);
- goto again;
- }
+ spin_lock(&locked_vma->lock);
}
if (rmap_item->address < vma->vm_start ||
diff --git a/mm/rmap.c b/mm/rmap.c
index f7ed89f..ae37a63 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1368,26 +1368,17 @@ static int rmap_walk_anon(struct page *page, int (*rmap_one)(struct page *,
* are holding mmap_sem. Users without mmap_sem are required to
* take a reference count to prevent the anon_vma disappearing
*/
-retry:
- anon_vma = page_anon_vma(page);
+ anon_vma = page_anon_vma_lock_oldest(page);
if (!anon_vma)
return ret;
- spin_lock(&anon_vma->lock);
list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
struct vm_area_struct *vma = avc->vma;
unsigned long address;
- /*
- * Guard against deadlocks by not spinning against
- * vma->anon_vma->lock. On contention release and retry
- */
locked_vma = NULL;
if (anon_vma != vma->anon_vma) {
locked_vma = vma->anon_vma;
- if (!spin_trylock(&locked_vma->lock)) {
- spin_unlock(&anon_vma->lock);
- goto retry;
- }
+ spin_lock(&locked_vma->lock);
}
address = vma_address(page, vma);
if (address != -EFAULT)
--
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-05-05 17:53 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-05 13:14 [PATCH 0/2] Fix migration races in rmap_walk() V5 Mel Gorman
2010-05-05 13:14 ` [PATCH 1/2] mm,migration: Prevent rmap_walk_[anon|ksm] seeing the wrong VMA information Mel Gorman
2010-05-05 14:34 ` Linus Torvalds
2010-05-05 14:56 ` Mel Gorman
2010-05-05 15:31 ` Linus Torvalds
2010-05-05 15:54 ` Mel Gorman
2010-05-05 16:13 ` Andrea Arcangeli
2010-05-05 19:11 ` Peter Zijlstra
2010-05-05 19:57 ` Andrea Arcangeli
2010-05-21 0:27 ` Andrea Arcangeli
2010-05-06 10:37 ` Mel Gorman
2010-05-05 17:34 ` Linus Torvalds
2010-05-05 17:57 ` Linus Torvalds
2010-05-05 18:14 ` Mel Gorman
2010-05-05 18:34 ` Linus Torvalds
2010-05-06 11:03 ` Mel Gorman
2010-05-06 13:40 ` Rik van Riel
2010-05-06 13:45 ` Mel Gorman
2010-05-05 17:53 ` Mel Gorman [this message]
2010-05-05 18:02 ` Linus Torvalds
2010-05-05 18:17 ` Mel Gorman
2010-05-06 0:22 ` Mel Gorman
2010-05-06 0:42 ` Linus Torvalds
2010-05-06 10:02 ` Mel Gorman
2010-05-06 14:15 ` Linus Torvalds
2010-05-06 14:25 ` Mel Gorman
2010-05-06 9:47 ` Minchan Kim
2010-05-06 9:54 ` Mel Gorman
2010-05-06 10:01 ` Minchan Kim
2010-05-06 10:10 ` Mel Gorman
2010-05-06 14:06 ` Linus Torvalds
2010-05-06 15:59 ` Minchan Kim
2010-05-06 7:38 ` KAMEZAWA Hiroyuki
2010-05-06 9:46 ` Mel Gorman
2010-05-06 23:52 ` KAMEZAWA Hiroyuki
2010-05-07 5:49 ` KAMEZAWA Hiroyuki
2010-05-05 13:14 ` [PATCH 2/2] mm,migration: Fix race between shift_arg_pages and rmap_walk by guaranteeing rmap_walk finds PTEs created within the temporary stack Mel Gorman
-- strict thread matches above, loose matches on Subject: below --
2010-05-06 15:33 [PATCH 0/2] Fix migration races in rmap_walk() V6 Mel Gorman
2010-05-06 15:33 ` [PATCH 1/2] mm,migration: Prevent rmap_walk_[anon|ksm] seeing the wrong VMA information Mel Gorman
2010-05-06 15:44 ` Rik van Riel
2010-05-06 15:51 ` Mel Gorman
2010-05-06 15:59 ` Linus Torvalds
2010-05-06 17:07 ` Mel Gorman
2010-05-06 23:20 [PATCH 0/2] Fix migration races in rmap_walk() V7 Mel Gorman
2010-05-06 23:20 ` [PATCH 1/2] mm,migration: Prevent rmap_walk_[anon|ksm] seeing the wrong VMA information Mel Gorman
2010-05-07 0:56 ` KAMEZAWA Hiroyuki
2010-05-07 16:26 ` Mel Gorman
2010-05-08 15:39 ` Andrea Arcangeli
2010-05-08 17:02 ` Linus Torvalds
2010-05-08 18:04 ` Andrea Arcangeli
2010-05-08 19:51 ` Linus Torvalds
2010-05-09 19:23 ` Mel Gorman
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=20100505175311.GU20979@csn.ul.ie \
--to=mel@csn.ul.ie \
--cc=aarcange@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=cl@linux.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=minchan.kim@gmail.com \
--cc=riel@redhat.com \
--cc=torvalds@linux-foundation.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).