[patch 29/36] page anon_vma

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Andrea Arcangeli <aarcange@xxxxxxxxxx>

Find the anon_vma to lock from the page rather than from the vma, after recent
anon_vma changes that allows a vma to belong to more than a single anon_vma.

Signed-off-by: Andrea Arcangeli <aarcange@xxxxxxxxxx>
---
 mm/huge_memory.c |   24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -761,13 +761,14 @@ static void __split_huge_page(struct pag
 			      struct anon_vma *anon_vma)
 {
 	int mapcount, mapcount2;
-	struct vm_area_struct *vma;
+	struct anon_vma_chain *avc;
 
 	BUG_ON(!PageHead(page));
 	BUG_ON(PageTail(page));
 
 	mapcount = 0;
-	list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
+	list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+		struct vm_area_struct *vma = avc->vma;
 		unsigned long addr = vma_address(page, vma);
 		if (addr == -EFAULT)
 			continue;
@@ -778,7 +779,8 @@ static void __split_huge_page(struct pag
 	__split_huge_page_refcount(page);
 
 	mapcount2 = 0;
-	list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
+	list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+		struct vm_area_struct *vma = avc->vma;
 		unsigned long addr = vma_address(page, vma);
 		if (addr == -EFAULT)
 			continue;
@@ -791,29 +793,29 @@ static void __split_huge_page(struct pag
 void __split_huge_page_vma(struct vm_area_struct *vma, pmd_t *pmd)
 {
 	struct page *page;
-	struct anon_vma *anon_vma;
 	struct mm_struct *mm;
 
 	BUG_ON(vma->vm_flags & VM_HUGETLB);
 
 	mm = vma->vm_mm;
 
-	anon_vma = vma->anon_vma;
-
-	spin_lock(&anon_vma->lock);
-	BUG_ON(pmd_trans_splitting(*pmd));
 	spin_lock(&mm->page_table_lock);
 	if (unlikely(!pmd_trans_huge(*pmd))) {
 		spin_unlock(&mm->page_table_lock);
-		spin_unlock(&anon_vma->lock);
 		return;
 	}
 	page = pmd_page(*pmd);
+	VM_BUG_ON(!page_count(page));
+	get_page(page);
 	spin_unlock(&mm->page_table_lock);
 
-	__split_huge_page(page, anon_vma);
+	/*
+	 * The vma->anon_vma->lock is the wrong lock if the page is shared,
+	 * the anon_vma->lock pointed by page->mapping is the right one.
+	 */
+	split_huge_page(page);
 
-	spin_unlock(&anon_vma->lock);
+	put_page(page);
 	BUG_ON(pmd_trans_huge(*pmd));
 }
 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxxx  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@xxxxxxxxx";> email@xxxxxxxxx </a>

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]