[3.8.y.z extended stable] Patch "mm: fix BUG in __split_huge_page_pmd" has been added to staging queue

Kamal Mostafa kamal at canonical.com
Tue Oct 29 17:54:50 UTC 2013


This is a note to let you know that I have just added a patch titled

    mm: fix BUG in __split_huge_page_pmd

to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue

This patch is scheduled to be released in version 3.8.13.12.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.8.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Kamal

------

>From 46a033fddf51104cfacfb9d3ce540118233f97a7 Mon Sep 17 00:00:00 2001
From: Hugh Dickins <hughd at google.com>
Date: Wed, 16 Oct 2013 13:47:08 -0700
Subject: mm: fix BUG in __split_huge_page_pmd

commit 750e8165f5e87b6a142be953640eabb13a9d350a upstream.

Occasionally we hit the BUG_ON(pmd_trans_huge(*pmd)) at the end of
__split_huge_page_pmd(): seen when doing madvise(,,MADV_DONTNEED).

It's invalid: we don't always have down_write of mmap_sem there: a racing
do_huge_pmd_wp_page() might have copied-on-write to another huge page
before our split_huge_page() got the anon_vma lock.

Forget the BUG_ON, just go back and try again if this happens.

Signed-off-by: Hugh Dickins <hughd at google.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov at linux.intel.com>
Cc: Andrea Arcangeli <aarcange at redhat.com>
Cc: Naoya Horiguchi <n-horiguchi at ah.jp.nec.com>
Cc: David Rientjes <rientjes at google.com>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
 mm/huge_memory.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index e9308d3..a057a7d 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2740,6 +2740,7 @@ void __split_huge_page_pmd(struct vm_area_struct *vma, unsigned long address,

 	mmun_start = haddr;
 	mmun_end   = haddr + HPAGE_PMD_SIZE;
+again:
 	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 	spin_lock(&mm->page_table_lock);
 	if (unlikely(!pmd_trans_huge(*pmd))) {
@@ -2762,7 +2763,14 @@ void __split_huge_page_pmd(struct vm_area_struct *vma, unsigned long address,
 	split_huge_page(page);

 	put_page(page);
-	BUG_ON(pmd_trans_huge(*pmd));
+
+	/*
+	 * We don't always have down_write of mmap_sem here: a racing
+	 * do_huge_pmd_wp_page() might have copied-on-write to another
+	 * huge page before our split_huge_page() got the anon_vma lock.
+	 */
+	if (unlikely(pmd_trans_huge(*pmd)))
+		goto again;
 }

 void split_huge_page_pmd_mm(struct mm_struct *mm, unsigned long address,
--
1.8.1.2





More information about the kernel-team mailing list