aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugh Dickins <hughd@google.com>2012-12-16 21:56:58 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-16 22:02:38 -0500
commita4f1de176614f634c367e5994a7bcc428c940df0 (patch)
tree9193f723c6f61442cf1fbc50e2db48d060f417d6
parent2dfea3803dcf70983d14ce1dcbb3e97a7459a28b (diff)
mm: fix kernel BUG at huge_memory.c:1474!
Andrea's autonuma-benchmark numa01 hits kernel BUG at huge_memory.c:1474! in change_huge_pmd called from change_protection from change_prot_numa from task_numa_work. That BUG, introduced in the huge zero page commit cad7f613c4d0 ("thp: change_huge_pmd(): make sure we don't try to make a page writable") was trying to verify that newprot never adds write permission to an anonymous huge page; but Automatic NUMA Balancing's 4b10e7d562c9 ("mm: mempolicy: Implement change_prot_numa() in terms of change_protection()") adds a new prot_numa path into change_huge_pmd(), which makes no use of the newprot provided, and may retain the write bit in the pmd. Just move the BUG_ON(pmd_write(entry)) up into the !prot_numa block. Signed-off-by: Hugh Dickins <hughd@google.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/huge_memory.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index d7ee1691fd21..32754eece63e 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1460,9 +1460,10 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
1460 if (__pmd_trans_huge_lock(pmd, vma) == 1) { 1460 if (__pmd_trans_huge_lock(pmd, vma) == 1) {
1461 pmd_t entry; 1461 pmd_t entry;
1462 entry = pmdp_get_and_clear(mm, addr, pmd); 1462 entry = pmdp_get_and_clear(mm, addr, pmd);
1463 if (!prot_numa) 1463 if (!prot_numa) {
1464 entry = pmd_modify(entry, newprot); 1464 entry = pmd_modify(entry, newprot);
1465 else { 1465 BUG_ON(pmd_write(entry));
1466 } else {
1466 struct page *page = pmd_page(*pmd); 1467 struct page *page = pmd_page(*pmd);
1467 1468
1468 /* only check non-shared pages */ 1469 /* only check non-shared pages */
@@ -1471,7 +1472,6 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
1471 entry = pmd_mknuma(entry); 1472 entry = pmd_mknuma(entry);
1472 } 1473 }
1473 } 1474 }
1474 BUG_ON(pmd_write(entry));
1475 set_pmd_at(mm, addr, pmd, entry); 1475 set_pmd_at(mm, addr, pmd, entry);
1476 spin_unlock(&vma->vm_mm->page_table_lock); 1476 spin_unlock(&vma->vm_mm->page_table_lock);
1477 ret = 1; 1477 ret = 1;