Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 115829
b: refs/heads/master
c: d9d332e
h: refs/heads/master
i:
  115827: bd2ae35
v: v3
  • Loading branch information
Linus Torvalds committed Oct 19, 2008
1 parent b5fe68f commit 6749aa2
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0cfd81031a26717fe14380d18275f8e217571615
refs/heads/master: d9d332e0874f46b91d8ac4604b68ee42b8a7a2c6
42 changes: 32 additions & 10 deletions trunk/mm/rmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,28 +55,51 @@

struct kmem_cache *anon_vma_cachep;

/* This must be called under the mmap_sem. */
/**
* anon_vma_prepare - attach an anon_vma to a memory region
* @vma: the memory region in question
*
* This makes sure the memory mapping described by 'vma' has
* an 'anon_vma' attached to it, so that we can associate the
* anonymous pages mapped into it with that anon_vma.
*
* The common case will be that we already have one, but if
* if not we either need to find an adjacent mapping that we
* can re-use the anon_vma from (very common when the only
* reason for splitting a vma has been mprotect()), or we
* allocate a new one.
*
* Anon-vma allocations are very subtle, because we may have
* optimistically looked up an anon_vma in page_lock_anon_vma()
* and that may actually touch the spinlock even in the newly
* allocated vma (it depends on RCU to make sure that the
* anon_vma isn't actually destroyed).
*
* As a result, we need to do proper anon_vma locking even
* for the new allocation. At the same time, we do not want
* to do any locking for the common case of already having
* an anon_vma.
*
* This must be called with the mmap_sem held for reading.
*/
int anon_vma_prepare(struct vm_area_struct *vma)
{
struct anon_vma *anon_vma = vma->anon_vma;

might_sleep();
if (unlikely(!anon_vma)) {
struct mm_struct *mm = vma->vm_mm;
struct anon_vma *allocated, *locked;
struct anon_vma *allocated;

anon_vma = find_mergeable_anon_vma(vma);
if (anon_vma) {
allocated = NULL;
locked = anon_vma;
spin_lock(&locked->lock);
} else {
allocated = NULL;
if (!anon_vma) {
anon_vma = anon_vma_alloc();
if (unlikely(!anon_vma))
return -ENOMEM;
allocated = anon_vma;
locked = NULL;
}
spin_lock(&anon_vma->lock);

/* page_table_lock to protect against threads */
spin_lock(&mm->page_table_lock);
Expand All @@ -87,8 +110,7 @@ int anon_vma_prepare(struct vm_area_struct *vma)
}
spin_unlock(&mm->page_table_lock);

if (locked)
spin_unlock(&locked->lock);
spin_unlock(&anon_vma->lock);
if (unlikely(allocated))
anon_vma_free(allocated);
}
Expand Down

0 comments on commit 6749aa2

Please sign in to comment.