summaryrefslogtreecommitdiffstats
path: root/mm/huge_memory.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-01-27 10:20:22 +0100
committerTakashi Iwai <tiwai@suse.de>2013-01-27 10:20:22 +0100
commit257c2a02a8f668ea195bcb56eebbddc1af718e5e (patch)
tree27ccff43bc36d119dc3afeaf610638a56f4bf3ea /mm/huge_memory.c
parent0712eea349d8e2b6d0e44b94a752d999319027fb (diff)
parenta8c136d2eba7b0b0c872e59eb404b1fe36504112 (diff)
Merge tag 'asoc-3.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v3.8-rc4 The usual set of driver updates, nothing too thrilling in here - one core change for the regulator bypass mode which was just not doing the right thing at all and a bunch of driver specifics.
Diffstat (limited to 'mm/huge_memory.c')
-rw-r--r--mm/huge_memory.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 9e894edc781..6001ee6347a 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1819,9 +1819,19 @@ int split_huge_page(struct page *page)
BUG_ON(is_huge_zero_pfn(page_to_pfn(page)));
BUG_ON(!PageAnon(page));
- anon_vma = page_lock_anon_vma_read(page);
+
+ /*
+ * The caller does not necessarily hold an mmap_sem that would prevent
+ * the anon_vma disappearing so we first we take a reference to it
+ * and then lock the anon_vma for write. This is similar to
+ * page_lock_anon_vma_read except the write lock is taken to serialise
+ * against parallel split or collapse operations.
+ */
+ anon_vma = page_get_anon_vma(page);
if (!anon_vma)
goto out;
+ anon_vma_lock_write(anon_vma);
+
ret = 0;
if (!PageCompound(page))
goto out_unlock;
@@ -1832,7 +1842,8 @@ int split_huge_page(struct page *page)
BUG_ON(PageCompound(page));
out_unlock:
- page_unlock_anon_vma_read(anon_vma);
+ anon_vma_unlock(anon_vma);
+ put_anon_vma(anon_vma);
out:
return ret;
}