linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mm: fix hang on anon_vma->root->lock
@ 2010-08-26  6:12 Hugh Dickins
  2010-08-26  6:41 ` David Miller
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Hugh Dickins @ 2010-08-26  6:12 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Andrew Morton, Rik van Riel, Andrea Arcangeli, linux-kernel,
	linux-mm

After several hours, kbuild tests hang with anon_vma_prepare() spinning on
a newly allocated anon_vma's lock - on a box with CONFIG_TREE_PREEMPT_RCU=y
(which makes this very much more likely, but it could happen without).

The ever-subtle page_lock_anon_vma() now needs a further twist: since
anon_vma_prepare() and anon_vma_fork() are liable to change the ->root
of a reused anon_vma structure at any moment, page_lock_anon_vma()
needs to check page_mapped() again before succeeding, otherwise
page_unlock_anon_vma() might address a different root->lock.

Signed-off-by: Hugh Dickins <hughd@google.com>
---

 mm/rmap.c |   19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

--- 2.6.36-rc2/mm/rmap.c	2010-08-16 00:18:01.000000000 -0700
+++ linux/mm/rmap.c	2010-08-24 03:22:17.000000000 -0700
@@ -316,7 +316,7 @@ void __init anon_vma_init(void)
  */
 struct anon_vma *page_lock_anon_vma(struct page *page)
 {
-	struct anon_vma *anon_vma;
+	struct anon_vma *anon_vma, *root_anon_vma;
 	unsigned long anon_mapping;
 
 	rcu_read_lock();
@@ -327,8 +327,21 @@ struct anon_vma *page_lock_anon_vma(stru
 		goto out;
 
 	anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON);
-	anon_vma_lock(anon_vma);
-	return anon_vma;
+	root_anon_vma = ACCESS_ONCE(anon_vma->root);
+	spin_lock(&root_anon_vma->lock);
+
+	/*
+	 * If this page is still mapped, then its anon_vma cannot have been
+	 * freed.  But if it has been unmapped, we have no security against
+	 * the anon_vma structure being freed and reused (for another anon_vma:
+	 * SLAB_DESTROY_BY_RCU guarantees that - so the spin_lock above cannot
+	 * corrupt): with anon_vma_prepare() or anon_vma_fork() redirecting
+	 * anon_vma->root before page_unlock_anon_vma() is called to unlock.
+	 */
+	if (page_mapped(page))
+		return anon_vma;
+
+	spin_unlock(&root_anon_vma->lock);
 out:
 	rcu_read_unlock();
 	return NULL;

--
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>

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2010-08-28 15:54 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-26  6:12 [PATCH] mm: fix hang on anon_vma->root->lock Hugh Dickins
2010-08-26  6:41 ` David Miller
2010-08-26 10:54   ` Hugh Dickins
2010-08-26 19:00     ` David Miller
2010-08-27  0:19     ` Andrea Arcangeli
2010-08-26 13:32 ` Rik van Riel
2010-08-26 23:50 ` Andrea Arcangeli
2010-08-27  1:43   ` Hugh Dickins
2010-08-27  9:55     ` Andrea Arcangeli
2010-08-27 16:43       ` Hugh Dickins
2010-08-27 17:13         ` Christoph Lameter
2010-08-27 17:55           ` Hugh Dickins
2010-08-27 19:29             ` Christoph Lameter
2010-08-27 20:14               ` Hugh Dickins
2010-08-27 20:56                 ` Christoph Lameter
2010-08-27 21:28                   ` Hugh Dickins
2010-08-27 21:33                     ` Hugh Dickins
2010-08-27 23:06                       ` Christoph Lameter
2010-08-28  1:07                         ` Hugh Dickins
2010-08-28  2:47                           ` Christoph Lameter
2010-08-28 10:17                             ` Peter Zijlstra
2010-08-28 15:54                           ` Andrea Arcangeli

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).