diff options
Diffstat (limited to 'mm/rmap.c')
-rw-r--r-- | mm/rmap.c | 85 |
1 files changed, 32 insertions, 53 deletions
@@ -31,11 +31,12 @@ | |||
31 | * swap_lock (in swap_duplicate, swap_info_get) | 31 | * swap_lock (in swap_duplicate, swap_info_get) |
32 | * mmlist_lock (in mmput, drain_mmlist and others) | 32 | * mmlist_lock (in mmput, drain_mmlist and others) |
33 | * mapping->private_lock (in __set_page_dirty_buffers) | 33 | * mapping->private_lock (in __set_page_dirty_buffers) |
34 | * inode_lock (in set_page_dirty's __mark_inode_dirty) | 34 | * inode->i_lock (in set_page_dirty's __mark_inode_dirty) |
35 | * inode_wb_list_lock (in set_page_dirty's __mark_inode_dirty) | ||
35 | * sb_lock (within inode_lock in fs/fs-writeback.c) | 36 | * sb_lock (within inode_lock in fs/fs-writeback.c) |
36 | * mapping->tree_lock (widely used, in set_page_dirty, | 37 | * mapping->tree_lock (widely used, in set_page_dirty, |
37 | * in arch-dependent flush_dcache_mmap_lock, | 38 | * in arch-dependent flush_dcache_mmap_lock, |
38 | * within inode_lock in __sync_single_inode) | 39 | * within inode_wb_list_lock in __sync_single_inode) |
39 | * | 40 | * |
40 | * (code doesn't rely on that order so it could be switched around) | 41 | * (code doesn't rely on that order so it could be switched around) |
41 | * ->tasklist_lock | 42 | * ->tasklist_lock |
@@ -67,11 +68,24 @@ static struct kmem_cache *anon_vma_chain_cachep; | |||
67 | 68 | ||
68 | static inline struct anon_vma *anon_vma_alloc(void) | 69 | static inline struct anon_vma *anon_vma_alloc(void) |
69 | { | 70 | { |
70 | return kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL); | 71 | struct anon_vma *anon_vma; |
72 | |||
73 | anon_vma = kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL); | ||
74 | if (anon_vma) { | ||
75 | atomic_set(&anon_vma->refcount, 1); | ||
76 | /* | ||
77 | * Initialise the anon_vma root to point to itself. If called | ||
78 | * from fork, the root will be reset to the parents anon_vma. | ||
79 | */ | ||
80 | anon_vma->root = anon_vma; | ||
81 | } | ||
82 | |||
83 | return anon_vma; | ||
71 | } | 84 | } |
72 | 85 | ||
73 | void anon_vma_free(struct anon_vma *anon_vma) | 86 | static inline void anon_vma_free(struct anon_vma *anon_vma) |
74 | { | 87 | { |
88 | VM_BUG_ON(atomic_read(&anon_vma->refcount)); | ||
75 | kmem_cache_free(anon_vma_cachep, anon_vma); | 89 | kmem_cache_free(anon_vma_cachep, anon_vma); |
76 | } | 90 | } |
77 | 91 | ||
@@ -133,11 +147,6 @@ int anon_vma_prepare(struct vm_area_struct *vma) | |||
133 | if (unlikely(!anon_vma)) | 147 | if (unlikely(!anon_vma)) |
134 | goto out_enomem_free_avc; | 148 | goto out_enomem_free_avc; |
135 | allocated = anon_vma; | 149 | 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 | } | 150 | } |
142 | 151 | ||
143 | anon_vma_lock(anon_vma); | 152 | anon_vma_lock(anon_vma); |
@@ -156,7 +165,7 @@ int anon_vma_prepare(struct vm_area_struct *vma) | |||
156 | anon_vma_unlock(anon_vma); | 165 | anon_vma_unlock(anon_vma); |
157 | 166 | ||
158 | if (unlikely(allocated)) | 167 | if (unlikely(allocated)) |
159 | anon_vma_free(allocated); | 168 | put_anon_vma(allocated); |
160 | if (unlikely(avc)) | 169 | if (unlikely(avc)) |
161 | anon_vma_chain_free(avc); | 170 | anon_vma_chain_free(avc); |
162 | } | 171 | } |
@@ -241,9 +250,9 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma) | |||
241 | */ | 250 | */ |
242 | anon_vma->root = pvma->anon_vma->root; | 251 | anon_vma->root = pvma->anon_vma->root; |
243 | /* | 252 | /* |
244 | * With KSM refcounts, an anon_vma can stay around longer than the | 253 | * With refcounts, an anon_vma can stay around longer than the |
245 | * process it belongs to. The root anon_vma needs to be pinned | 254 | * 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. | 255 | * this anon_vma is freed, because the lock lives in the root. |
247 | */ | 256 | */ |
248 | get_anon_vma(anon_vma->root); | 257 | get_anon_vma(anon_vma->root); |
249 | /* Mark this anon_vma as the one where our new (COWed) pages go. */ | 258 | /* Mark this anon_vma as the one where our new (COWed) pages go. */ |
@@ -253,7 +262,7 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma) | |||
253 | return 0; | 262 | return 0; |
254 | 263 | ||
255 | out_error_free_anon_vma: | 264 | out_error_free_anon_vma: |
256 | anon_vma_free(anon_vma); | 265 | put_anon_vma(anon_vma); |
257 | out_error: | 266 | out_error: |
258 | unlink_anon_vmas(vma); | 267 | unlink_anon_vmas(vma); |
259 | return -ENOMEM; | 268 | return -ENOMEM; |
@@ -272,15 +281,11 @@ static void anon_vma_unlink(struct anon_vma_chain *anon_vma_chain) | |||
272 | list_del(&anon_vma_chain->same_anon_vma); | 281 | list_del(&anon_vma_chain->same_anon_vma); |
273 | 282 | ||
274 | /* We must garbage collect the anon_vma if it's empty */ | 283 | /* We must garbage collect the anon_vma if it's empty */ |
275 | empty = list_empty(&anon_vma->head) && !anonvma_external_refcount(anon_vma); | 284 | empty = list_empty(&anon_vma->head); |
276 | anon_vma_unlock(anon_vma); | 285 | anon_vma_unlock(anon_vma); |
277 | 286 | ||
278 | if (empty) { | 287 | if (empty) |
279 | /* We no longer need the root anon_vma */ | 288 | put_anon_vma(anon_vma); |
280 | if (anon_vma->root != anon_vma) | ||
281 | drop_anon_vma(anon_vma->root); | ||
282 | anon_vma_free(anon_vma); | ||
283 | } | ||
284 | } | 289 | } |
285 | 290 | ||
286 | void unlink_anon_vmas(struct vm_area_struct *vma) | 291 | void unlink_anon_vmas(struct vm_area_struct *vma) |
@@ -303,7 +308,7 @@ static void anon_vma_ctor(void *data) | |||
303 | struct anon_vma *anon_vma = data; | 308 | struct anon_vma *anon_vma = data; |
304 | 309 | ||
305 | spin_lock_init(&anon_vma->lock); | 310 | spin_lock_init(&anon_vma->lock); |
306 | anonvma_external_refcount_init(anon_vma); | 311 | atomic_set(&anon_vma->refcount, 0); |
307 | INIT_LIST_HEAD(&anon_vma->head); | 312 | INIT_LIST_HEAD(&anon_vma->head); |
308 | } | 313 | } |
309 | 314 | ||
@@ -1486,41 +1491,15 @@ int try_to_munlock(struct page *page) | |||
1486 | return try_to_unmap_file(page, TTU_MUNLOCK); | 1491 | return try_to_unmap_file(page, TTU_MUNLOCK); |
1487 | } | 1492 | } |
1488 | 1493 | ||
1489 | #if defined(CONFIG_KSM) || defined(CONFIG_MIGRATION) | 1494 | void __put_anon_vma(struct anon_vma *anon_vma) |
1490 | /* | ||
1491 | * Drop an anon_vma refcount, freeing the anon_vma and anon_vma->root | ||
1492 | * if necessary. Be careful to do all the tests under the lock. Once | ||
1493 | * we know we are the last user, nobody else can get a reference and we | ||
1494 | * can do the freeing without the lock. | ||
1495 | */ | ||
1496 | void drop_anon_vma(struct anon_vma *anon_vma) | ||
1497 | { | 1495 | { |
1498 | BUG_ON(atomic_read(&anon_vma->external_refcount) <= 0); | 1496 | struct anon_vma *root = anon_vma->root; |
1499 | if (atomic_dec_and_lock(&anon_vma->external_refcount, &anon_vma->root->lock)) { | ||
1500 | struct anon_vma *root = anon_vma->root; | ||
1501 | int empty = list_empty(&anon_vma->head); | ||
1502 | int last_root_user = 0; | ||
1503 | int root_empty = 0; | ||
1504 | 1497 | ||
1505 | /* | 1498 | if (root != anon_vma && atomic_dec_and_test(&root->refcount)) |
1506 | * The refcount on a non-root anon_vma got dropped. Drop | 1499 | anon_vma_free(root); |
1507 | * the refcount on the root and check if we need to free it. | ||
1508 | */ | ||
1509 | if (empty && anon_vma != root) { | ||
1510 | BUG_ON(atomic_read(&root->external_refcount) <= 0); | ||
1511 | last_root_user = atomic_dec_and_test(&root->external_refcount); | ||
1512 | root_empty = list_empty(&root->head); | ||
1513 | } | ||
1514 | anon_vma_unlock(anon_vma); | ||
1515 | 1500 | ||
1516 | if (empty) { | 1501 | anon_vma_free(anon_vma); |
1517 | anon_vma_free(anon_vma); | ||
1518 | if (root_empty && last_root_user) | ||
1519 | anon_vma_free(root); | ||
1520 | } | ||
1521 | } | ||
1522 | } | 1502 | } |
1523 | #endif | ||
1524 | 1503 | ||
1525 | #ifdef CONFIG_MIGRATION | 1504 | #ifdef CONFIG_MIGRATION |
1526 | /* | 1505 | /* |