diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2011-03-22 19:32:49 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-22 20:44:03 -0400 |
| commit | 01d8b20dec5f4019283e244aba50ba86fe6ead6e (patch) | |
| tree | 738a2e675547de61f74d6f4019dd5830c40446dd /include/linux | |
| parent | 83813267c699ab11cc65a6d9d0f42db42f0862b3 (diff) | |
mm: simplify anon_vma refcounts
This patch changes the anon_vma refcount to be 0 when the object is free.
It does this by adding 1 ref to being in use in the anon_vma structure
(iow. the anon_vma->head list is not empty).
This allows a simpler release scheme without having to check both the
refcount and the list as well as avoids taking a ref for each entry on the
list.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: Hugh Dickins <hughd@google.com>
Acked-by: Mel Gorman <mel@csn.ul.ie>
Acked-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/rmap.h | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/include/linux/rmap.h b/include/linux/rmap.h index fd56111a52c1..830e65dc01ee 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h | |||
| @@ -73,7 +73,13 @@ static inline void get_anon_vma(struct anon_vma *anon_vma) | |||
| 73 | atomic_inc(&anon_vma->refcount); | 73 | atomic_inc(&anon_vma->refcount); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | void put_anon_vma(struct anon_vma *); | 76 | void __put_anon_vma(struct anon_vma *anon_vma); |
| 77 | |||
| 78 | static inline void put_anon_vma(struct anon_vma *anon_vma) | ||
| 79 | { | ||
| 80 | if (atomic_dec_and_test(&anon_vma->refcount)) | ||
| 81 | __put_anon_vma(anon_vma); | ||
| 82 | } | ||
| 77 | 83 | ||
| 78 | static inline struct anon_vma *page_anon_vma(struct page *page) | 84 | static inline struct anon_vma *page_anon_vma(struct page *page) |
| 79 | { | 85 | { |
| @@ -116,7 +122,6 @@ void unlink_anon_vmas(struct vm_area_struct *); | |||
| 116 | int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *); | 122 | int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *); |
| 117 | int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *); | 123 | int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *); |
| 118 | void __anon_vma_link(struct vm_area_struct *); | 124 | void __anon_vma_link(struct vm_area_struct *); |
| 119 | void anon_vma_free(struct anon_vma *); | ||
| 120 | 125 | ||
| 121 | static inline void anon_vma_merge(struct vm_area_struct *vma, | 126 | static inline void anon_vma_merge(struct vm_area_struct *vma, |
| 122 | struct vm_area_struct *next) | 127 | struct vm_area_struct *next) |
| @@ -125,6 +130,8 @@ static inline void anon_vma_merge(struct vm_area_struct *vma, | |||
| 125 | unlink_anon_vmas(next); | 130 | unlink_anon_vmas(next); |
| 126 | } | 131 | } |
| 127 | 132 | ||
| 133 | struct anon_vma *page_get_anon_vma(struct page *page); | ||
| 134 | |||
| 128 | /* | 135 | /* |
| 129 | * rmap interfaces called when adding or removing pte of page | 136 | * rmap interfaces called when adding or removing pte of page |
| 130 | */ | 137 | */ |
