aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/rmap.h11
-rw-r--r--mm/rmap.c76
2 files changed, 37 insertions, 50 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
76void put_anon_vma(struct anon_vma *); 76void __put_anon_vma(struct anon_vma *anon_vma);
77
78static 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
78static inline struct anon_vma *page_anon_vma(struct page *page) 84static inline struct anon_vma *page_anon_vma(struct page *page)
79{ 85{
@@ -116,7 +122,6 @@ void unlink_anon_vmas(struct vm_area_struct *);
116int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *); 122int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *);
117int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *); 123int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *);
118void __anon_vma_link(struct vm_area_struct *); 124void __anon_vma_link(struct vm_area_struct *);
119void anon_vma_free(struct anon_vma *);
120 125
121static inline void anon_vma_merge(struct vm_area_struct *vma, 126static 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
133struct 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 */
diff --git a/mm/rmap.c b/mm/rmap.c
index 873cd9ef912c..4a8e99a0fb97 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -67,11 +67,24 @@ static struct kmem_cache *anon_vma_chain_cachep;
67 67
68static inline struct anon_vma *anon_vma_alloc(void) 68static inline struct anon_vma *anon_vma_alloc(void)
69{ 69{
70 return kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL); 70 struct anon_vma *anon_vma;
71
72 anon_vma = kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL);
73 if (anon_vma) {
74 atomic_set(&anon_vma->refcount, 1);
75 /*
76 * Initialise the anon_vma root to point to itself. If called
77 * from fork, the root will be reset to the parents anon_vma.
78 */
79 anon_vma->root = anon_vma;
80 }
81
82 return anon_vma;
71} 83}
72 84
73void anon_vma_free(struct anon_vma *anon_vma) 85static inline void anon_vma_free(struct anon_vma *anon_vma)
74{ 86{
87 VM_BUG_ON(atomic_read(&anon_vma->refcount));
75 kmem_cache_free(anon_vma_cachep, anon_vma); 88 kmem_cache_free(anon_vma_cachep, anon_vma);
76} 89}
77 90
@@ -133,11 +146,6 @@ int anon_vma_prepare(struct vm_area_struct *vma)
133 if (unlikely(!anon_vma)) 146 if (unlikely(!anon_vma))
134 goto out_enomem_free_avc; 147 goto out_enomem_free_avc;
135 allocated = anon_vma; 148 allocated = anon_vma;
136 /*
137 * This VMA had no anon_vma yet. This anon_vma is
138 * the root of any anon_vma tree that might form.
139 */
140 anon_vma->root = anon_vma;
141 } 149 }
142 150
143 anon_vma_lock(anon_vma); 151 anon_vma_lock(anon_vma);
@@ -156,7 +164,7 @@ int anon_vma_prepare(struct vm_area_struct *vma)
156 anon_vma_unlock(anon_vma); 164 anon_vma_unlock(anon_vma);
157 165
158 if (unlikely(allocated)) 166 if (unlikely(allocated))
159 anon_vma_free(allocated); 167 put_anon_vma(allocated);
160 if (unlikely(avc)) 168 if (unlikely(avc))
161 anon_vma_chain_free(avc); 169 anon_vma_chain_free(avc);
162 } 170 }
@@ -241,9 +249,9 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
241 */ 249 */
242 anon_vma->root = pvma->anon_vma->root; 250 anon_vma->root = pvma->anon_vma->root;
243 /* 251 /*
244 * With KSM refcounts, an anon_vma can stay around longer than the 252 * With refcounts, an anon_vma can stay around longer than the
245 * process it belongs to. The root anon_vma needs to be pinned 253 * process it belongs to. The root anon_vma needs to be pinned until
246 * until this anon_vma is freed, because the lock lives in the root. 254 * this anon_vma is freed, because the lock lives in the root.
247 */ 255 */
248 get_anon_vma(anon_vma->root); 256 get_anon_vma(anon_vma->root);
249 /* Mark this anon_vma as the one where our new (COWed) pages go. */ 257 /* Mark this anon_vma as the one where our new (COWed) pages go. */
@@ -253,7 +261,7 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
253 return 0; 261 return 0;
254 262
255 out_error_free_anon_vma: 263 out_error_free_anon_vma:
256 anon_vma_free(anon_vma); 264 put_anon_vma(anon_vma);
257 out_error: 265 out_error:
258 unlink_anon_vmas(vma); 266 unlink_anon_vmas(vma);
259 return -ENOMEM; 267 return -ENOMEM;
@@ -272,15 +280,11 @@ static void anon_vma_unlink(struct anon_vma_chain *anon_vma_chain)
272 list_del(&anon_vma_chain->same_anon_vma); 280 list_del(&anon_vma_chain->same_anon_vma);
273 281
274 /* We must garbage collect the anon_vma if it's empty */ 282 /* We must garbage collect the anon_vma if it's empty */
275 empty = list_empty(&anon_vma->head) && !atomic_read(&anon_vma->refcount); 283 empty = list_empty(&anon_vma->head);
276 anon_vma_unlock(anon_vma); 284 anon_vma_unlock(anon_vma);
277 285
278 if (empty) { 286 if (empty)
279 /* We no longer need the root anon_vma */ 287 put_anon_vma(anon_vma);
280 if (anon_vma->root != anon_vma)
281 put_anon_vma(anon_vma->root);
282 anon_vma_free(anon_vma);
283 }
284} 288}
285 289
286void unlink_anon_vmas(struct vm_area_struct *vma) 290void unlink_anon_vmas(struct vm_area_struct *vma)
@@ -1486,38 +1490,14 @@ int try_to_munlock(struct page *page)
1486 return try_to_unmap_file(page, TTU_MUNLOCK); 1490 return try_to_unmap_file(page, TTU_MUNLOCK);
1487} 1491}
1488 1492
1489/* 1493void __put_anon_vma(struct anon_vma *anon_vma)
1490 * Drop an anon_vma refcount, freeing the anon_vma and anon_vma->root
1491 * if necessary. Be careful to do all the tests under the lock. Once
1492 * we know we are the last user, nobody else can get a reference and we
1493 * can do the freeing without the lock.
1494 */
1495void put_anon_vma(struct anon_vma *anon_vma)
1496{ 1494{
1497 BUG_ON(atomic_read(&anon_vma->refcount) <= 0); 1495 struct anon_vma *root = anon_vma->root;
1498 if (atomic_dec_and_lock(&anon_vma->refcount, &anon_vma->root->lock)) {
1499 struct anon_vma *root = anon_vma->root;
1500 int empty = list_empty(&anon_vma->head);
1501 int last_root_user = 0;
1502 int root_empty = 0;
1503 1496
1504 /* 1497 if (root != anon_vma && atomic_dec_and_test(&root->refcount))
1505 * The refcount on a non-root anon_vma got dropped. Drop 1498 anon_vma_free(root);
1506 * the refcount on the root and check if we need to free it.
1507 */
1508 if (empty && anon_vma != root) {
1509 BUG_ON(atomic_read(&root->refcount) <= 0);
1510 last_root_user = atomic_dec_and_test(&root->refcount);
1511 root_empty = list_empty(&root->head);
1512 }
1513 anon_vma_unlock(anon_vma);
1514 1499
1515 if (empty) { 1500 anon_vma_free(anon_vma);
1516 anon_vma_free(anon_vma);
1517 if (root_empty && last_root_user)
1518 anon_vma_free(root);
1519 }
1520 }
1521} 1501}
1522 1502
1523#ifdef CONFIG_MIGRATION 1503#ifdef CONFIG_MIGRATION