linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Magnus Damm <magnus@valinux.co.jp>
To: linux-mm@kvack.org, linux-kernel@vger.kernel.org
Cc: Magnus Damm <magnus@valinux.co.jp>, andrea@suse.de
Subject: [PATCH 03/07] Add anon_vma use count
Date: Thu,  8 Dec 2005 20:27:10 +0900 (JST)	[thread overview]
Message-ID: <20051208112955.6309.47344.sendpatchset@cherry.local> (raw)
In-Reply-To: <20051208112940.6309.39428.sendpatchset@cherry.local>

Add anon_vma use count.

This patch adds an atomic use counter to struct anon_vma. We do this because
we need to be able to follow page->mapping to determine the map count when
page->_mapcount is missing. Without this patch page->mapping might point
to an already freed struct anon_vma.

Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
---

 include/linux/rmap.h |    4 +++-
 mm/page_alloc.c      |    6 +++++-
 mm/rmap.c            |   18 ++++++++++--------
 3 files changed, 18 insertions(+), 10 deletions(-)

--- from-0002/include/linux/rmap.h
+++ to-work/include/linux/rmap.h	2005-12-08 12:17:33.000000000 +0900
@@ -27,6 +27,7 @@
 struct anon_vma {
 	spinlock_t lock;	/* Serialize access to vma list */
 	struct list_head head;	/* List of private "related" vmas */
+	atomic_t use_count;
 };
 
 #ifdef CONFIG_MMU
@@ -40,7 +41,8 @@ static inline struct anon_vma *anon_vma_
 
 static inline void anon_vma_free(struct anon_vma *anon_vma)
 {
-	kmem_cache_free(anon_vma_cachep, anon_vma);
+	if (atomic_add_negative(-1, &anon_vma->use_count))
+		kmem_cache_free(anon_vma_cachep, anon_vma);
 }
 
 static inline void anon_vma_lock(struct vm_area_struct *vma)
--- from-0003/mm/page_alloc.c
+++ to-work/mm/page_alloc.c	2005-12-08 12:17:33.000000000 +0900
@@ -36,6 +36,7 @@
 #include <linux/memory_hotplug.h>
 #include <linux/nodemask.h>
 #include <linux/vmalloc.h>
+#include <linux/rmap.h>
 
 #include <asm/tlbflush.h>
 #include "internal.h"
@@ -683,8 +684,11 @@ static void fastcall free_hot_cold_page(
 
 	arch_free_page(page, 0);
 
-	if (PageAnon(page))
+	if (PageAnon(page)) {
+		anon_vma_free((void *)((unsigned long)
+				       (page->mapping) - PAGE_MAPPING_ANON));
 		page->mapping = NULL;
+	}
 	if (free_pages_check(__FUNCTION__, page))
 		return;
 
--- from-0003/mm/rmap.c
+++ to-work/mm/rmap.c	2005-12-08 12:17:33.000000000 +0900
@@ -100,6 +100,8 @@ int anon_vma_prepare(struct vm_area_stru
 			locked = NULL;
 		}
 
+		atomic_inc(&anon_vma->use_count);
+
 		/* page_table_lock to protect against threads */
 		spin_lock(&mm->page_table_lock);
 		if (likely(!vma->anon_vma)) {
@@ -121,6 +123,7 @@ void __anon_vma_merge(struct vm_area_str
 {
 	BUG_ON(vma->anon_vma != next->anon_vma);
 	list_del(&next->anon_vma_node);
+	anon_vma_free(vma->anon_vma);
 }
 
 void __anon_vma_link(struct vm_area_struct *vma)
@@ -128,6 +131,7 @@ void __anon_vma_link(struct vm_area_stru
 	struct anon_vma *anon_vma = vma->anon_vma;
 
 	if (anon_vma) {
+		atomic_inc(&anon_vma->use_count);
 		list_add(&vma->anon_vma_node, &anon_vma->head);
 		validate_anon_vma(vma);
 	}
@@ -138,6 +142,7 @@ void anon_vma_link(struct vm_area_struct
 	struct anon_vma *anon_vma = vma->anon_vma;
 
 	if (anon_vma) {
+		atomic_inc(&anon_vma->use_count);
 		spin_lock(&anon_vma->lock);
 		list_add(&vma->anon_vma_node, &anon_vma->head);
 		validate_anon_vma(vma);
@@ -148,7 +153,6 @@ void anon_vma_link(struct vm_area_struct
 void anon_vma_unlink(struct vm_area_struct *vma)
 {
 	struct anon_vma *anon_vma = vma->anon_vma;
-	int empty;
 
 	if (!anon_vma)
 		return;
@@ -156,13 +160,8 @@ void anon_vma_unlink(struct vm_area_stru
 	spin_lock(&anon_vma->lock);
 	validate_anon_vma(vma);
 	list_del(&vma->anon_vma_node);
-
-	/* We must garbage collect the anon_vma if it's empty */
-	empty = list_empty(&anon_vma->head);
 	spin_unlock(&anon_vma->lock);
-
-	if (empty)
-		anon_vma_free(anon_vma);
+	anon_vma_free(anon_vma);
 }
 
 static void anon_vma_ctor(void *data, kmem_cache_t *cachep, unsigned long flags)
@@ -173,6 +172,7 @@ static void anon_vma_ctor(void *data, km
 
 		spin_lock_init(&anon_vma->lock);
 		INIT_LIST_HEAD(&anon_vma->head);
+		atomic_set(&anon_vma->use_count, -1);
 	}
 }
 
@@ -434,7 +434,9 @@ void page_add_anon_rmap(struct page *pag
 		struct anon_vma *anon_vma = vma->anon_vma;
 
 		BUG_ON(!anon_vma);
-		anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
+		atomic_inc(&anon_vma->use_count);
+		anon_vma = (void *) ((unsigned long)anon_vma 
+				     + PAGE_MAPPING_ANON);
 		page->mapping = (struct address_space *) anon_vma;
 
 		page->index = linear_page_index(vma, address);

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

  parent reply	other threads:[~2005-12-08 11:27 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-12-08 11:26 [PATCH 00/07][RFC] Remove mapcount from struct page Magnus Damm
2005-12-08 11:27 ` [PATCH 01/07] Remove page_mapcount Magnus Damm
2005-12-08 11:27 ` [PATCH 02/07] Add PG_mapped Magnus Damm
2005-12-08 11:27 ` Magnus Damm [this message]
2005-12-08 11:27 ` [PATCH 04/07] Replace mapcount with PG_mapped Magnus Damm
2005-12-08 11:27 ` [PATCH 05/07] Remove reset_page_mapcount Magnus Damm
2005-12-08 11:27 ` [PATCH 06/07] Remove page_remove_rmap Magnus Damm
2005-12-08 11:27 ` [PATCH 07/07] Remove page_dup_rmap Magnus Damm
2005-12-08 14:16 ` [PATCH 00/07][RFC] Remove mapcount from struct page Hugh Dickins
2005-12-09  2:48   ` Magnus Damm

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=20051208112955.6309.47344.sendpatchset@cherry.local \
    --to=magnus@valinux.co.jp \
    --cc=andrea@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.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