[PATCH 01/14] mm,migration: Take a reference to the anon_vma before migrating

Previous thread: regulator: regulator_get behaviour without CONFIG_REGULATOR set by Jerome Oufella on Friday, April 2, 2010 - 8:47 am. (15 messages)

Next thread: [PATCH 02/14] mm,migration: Do not try to migrate unmapped anonymous pages by Mel Gorman on Friday, April 2, 2010 - 9:02 am. (1 message)
From: Mel Gorman
Date: Friday, April 2, 2010 - 9:02 am

rmap_walk_anon() does not use page_lock_anon_vma() for looking up and
locking an anon_vma and it does not appear to have sufficient locking to
ensure the anon_vma does not disappear from under it.

This patch copies an approach used by KSM to take a reference on the
anon_vma while pages are being migrated. This should prevent rmap_walk()
running into nasty surprises later because anon_vma has been freed.

Signed-off-by: Mel Gorman <mel@csn.ul.ie>
Acked-by: Rik van Riel <riel@redhat.com>
---
 include/linux/rmap.h |   23 +++++++++++++++++++++++
 mm/migrate.c         |   12 ++++++++++++
 mm/rmap.c            |   10 +++++-----
 3 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index d25bd22..567d43f 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -29,6 +29,9 @@ struct anon_vma {
 #ifdef CONFIG_KSM
 	atomic_t ksm_refcount;
 #endif
+#ifdef CONFIG_MIGRATION
+	atomic_t migrate_refcount;
+#endif
 	/*
 	 * NOTE: the LSB of the head.next is set by
 	 * mm_take_all_locks() _after_ taking the above lock. So the
@@ -81,6 +84,26 @@ static inline int ksm_refcount(struct anon_vma *anon_vma)
 	return 0;
 }
 #endif /* CONFIG_KSM */
+#ifdef CONFIG_MIGRATION
+static inline void migrate_refcount_init(struct anon_vma *anon_vma)
+{
+	atomic_set(&anon_vma->migrate_refcount, 0);
+}
+
+static inline int migrate_refcount(struct anon_vma *anon_vma)
+{
+	return atomic_read(&anon_vma->migrate_refcount);
+}
+#else
+static inline void migrate_refcount_init(struct anon_vma *anon_vma)
+{
+}
+
+static inline int migrate_refcount(struct anon_vma *anon_vma)
+{
+	return 0;
+}
+#endif /* CONFIG_MIGRATE */
 
 static inline struct anon_vma *page_anon_vma(struct page *page)
 {
diff --git a/mm/migrate.c b/mm/migrate.c
index 6903abf..06e6316 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -542,6 +542,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
 	int rcu_locked = 0;
 	int charge = 0;
 ...
From: Andrew Morton
Date: Tuesday, April 6, 2010 - 5:05 pm

On Fri,  2 Apr 2010 17:02:35 +0100

The code didn't exactly bend over backwards making itself easy for

Some documentation here describing the need for this thing and its

So no helper function for this.  I guess a grep for `migrate_refcount'
will find it OK.


So...  Why shouldn't this be testing ksm_refcount() too?


--

From: Mel Gorman
Date: Wednesday, April 7, 2010 - 2:56 am

anon_vma in general is not perfectly straight-forward. I clarify the






-- 
Mel Gorman
Part-time Phd Student                          Linux Technology Center
University of Limerick                         IBM Dublin Software Lab
--

Previous thread: regulator: regulator_get behaviour without CONFIG_REGULATOR set by Jerome Oufella on Friday, April 2, 2010 - 8:47 am. (15 messages)

Next thread: [PATCH 02/14] mm,migration: Do not try to migrate unmapped anonymous pages by Mel Gorman on Friday, April 2, 2010 - 9:02 am. (1 message)