.. | .. |
---|
91 | 91 | anon_vma = kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL); |
---|
92 | 92 | if (anon_vma) { |
---|
93 | 93 | atomic_set(&anon_vma->refcount, 1); |
---|
94 | | - anon_vma->degree = 1; /* Reference for first vma */ |
---|
| 94 | + anon_vma->num_children = 0; |
---|
| 95 | + anon_vma->num_active_vmas = 0; |
---|
95 | 96 | anon_vma->parent = anon_vma; |
---|
96 | 97 | /* |
---|
97 | 98 | * Initialise the anon_vma root to point to itself. If called |
---|
.. | .. |
---|
199 | 200 | anon_vma = anon_vma_alloc(); |
---|
200 | 201 | if (unlikely(!anon_vma)) |
---|
201 | 202 | goto out_enomem_free_avc; |
---|
| 203 | + anon_vma->num_children++; /* self-parent link for new root */ |
---|
202 | 204 | allocated = anon_vma; |
---|
203 | 205 | } |
---|
204 | 206 | |
---|
.. | .. |
---|
208 | 210 | if (likely(!vma->anon_vma)) { |
---|
209 | 211 | vma->anon_vma = anon_vma; |
---|
210 | 212 | anon_vma_chain_link(vma, avc, anon_vma); |
---|
211 | | - /* vma reference or self-parent link for new root */ |
---|
212 | | - anon_vma->degree++; |
---|
| 213 | + anon_vma->num_active_vmas++; |
---|
213 | 214 | allocated = NULL; |
---|
214 | 215 | avc = NULL; |
---|
215 | 216 | } |
---|
.. | .. |
---|
294 | 295 | anon_vma_chain_link(dst, avc, anon_vma); |
---|
295 | 296 | |
---|
296 | 297 | /* |
---|
297 | | - * Reuse existing anon_vma if its degree lower than two, |
---|
298 | | - * that means it has no vma and only one anon_vma child. |
---|
| 298 | + * Reuse existing anon_vma if it has no vma and only one |
---|
| 299 | + * anon_vma child. |
---|
299 | 300 | * |
---|
300 | | - * Do not chose parent anon_vma, otherwise first child |
---|
301 | | - * will always reuse it. Root anon_vma is never reused: |
---|
| 301 | + * Root anon_vma is never reused: |
---|
302 | 302 | * it has self-parent reference and at least one child. |
---|
303 | 303 | */ |
---|
304 | 304 | if (!dst->anon_vma && src->anon_vma && |
---|
305 | | - anon_vma != src->anon_vma && anon_vma->degree < 2) |
---|
| 305 | + anon_vma->num_children < 2 && |
---|
| 306 | + anon_vma->num_active_vmas == 0) |
---|
306 | 307 | dst->anon_vma = anon_vma; |
---|
307 | 308 | } |
---|
308 | 309 | if (dst->anon_vma) |
---|
309 | | - dst->anon_vma->degree++; |
---|
| 310 | + dst->anon_vma->num_active_vmas++; |
---|
310 | 311 | unlock_anon_vma_root(root); |
---|
311 | 312 | return 0; |
---|
312 | 313 | |
---|
.. | .. |
---|
356 | 357 | anon_vma = anon_vma_alloc(); |
---|
357 | 358 | if (!anon_vma) |
---|
358 | 359 | goto out_error; |
---|
| 360 | + anon_vma->num_active_vmas++; |
---|
359 | 361 | avc = anon_vma_chain_alloc(GFP_KERNEL); |
---|
360 | 362 | if (!avc) |
---|
361 | 363 | goto out_error_free_anon_vma; |
---|
.. | .. |
---|
376 | 378 | vma->anon_vma = anon_vma; |
---|
377 | 379 | anon_vma_lock_write(anon_vma); |
---|
378 | 380 | anon_vma_chain_link(vma, avc, anon_vma); |
---|
379 | | - anon_vma->parent->degree++; |
---|
| 381 | + anon_vma->parent->num_children++; |
---|
380 | 382 | anon_vma_unlock_write(anon_vma); |
---|
381 | 383 | |
---|
382 | 384 | return 0; |
---|
.. | .. |
---|
408 | 410 | * to free them outside the lock. |
---|
409 | 411 | */ |
---|
410 | 412 | if (RB_EMPTY_ROOT(&anon_vma->rb_root.rb_root)) { |
---|
411 | | - anon_vma->parent->degree--; |
---|
| 413 | + anon_vma->parent->num_children--; |
---|
412 | 414 | continue; |
---|
413 | 415 | } |
---|
414 | 416 | |
---|
.. | .. |
---|
416 | 418 | anon_vma_chain_free(avc); |
---|
417 | 419 | } |
---|
418 | 420 | if (vma->anon_vma) |
---|
419 | | - vma->anon_vma->degree--; |
---|
| 421 | + vma->anon_vma->num_active_vmas--; |
---|
| 422 | + |
---|
420 | 423 | unlock_anon_vma_root(root); |
---|
421 | 424 | |
---|
422 | 425 | /* |
---|
.. | .. |
---|
427 | 430 | list_for_each_entry_safe(avc, next, &vma->anon_vma_chain, same_vma) { |
---|
428 | 431 | struct anon_vma *anon_vma = avc->anon_vma; |
---|
429 | 432 | |
---|
430 | | - VM_WARN_ON(anon_vma->degree); |
---|
| 433 | + VM_WARN_ON(anon_vma->num_children); |
---|
| 434 | + VM_WARN_ON(anon_vma->num_active_vmas); |
---|
431 | 435 | put_anon_vma(anon_vma); |
---|
432 | 436 | |
---|
433 | 437 | list_del(&avc->same_vma); |
---|
.. | .. |
---|
911 | 915 | |
---|
912 | 916 | return rwc.contended ? -1 : pra.referenced; |
---|
913 | 917 | } |
---|
| 918 | +EXPORT_SYMBOL_GPL(page_referenced); |
---|
914 | 919 | |
---|
915 | 920 | static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma, |
---|
916 | 921 | unsigned long address, void *arg) |
---|