[PATCH] hugetlb: avoid gratuitous BUG_ON in hugetlb_fault() -> hugetlb_cow()

From: Chris Metcalf
Date: Sun Apr 29 2012 - 15:36:44 EST


Commit 66aebce747eaf added code to avoid a race condition by
elevating the page refcount in hugetlb_fault() while calling
hugetlb_cow(). However, one code path in hugetlb_cow() includes
an assertion that the page count is 1, whereas it may now also
have the value 2 in this path.

Signed-off-by: Chris Metcalf <cmetcalf@xxxxxxxxxx>
---
We discovered this while testing the original path; one particular
application triggered this due to the specific number of huge pages
it started with.

mm/hugetlb.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index cd65cb1..d5b0254 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2498,7 +2498,14 @@ retry_avoidcopy:
if (outside_reserve) {
BUG_ON(huge_pte_none(pte));
if (unmap_ref_private(mm, vma, old_page, address)) {
- BUG_ON(page_count(old_page) != 1);
+ /*
+ * Page refcount may be 1 in the common case,
+ * but since we may do an extra get_page()
+ * when called from hugetlb_fault(), we allow
+ * a page refcount of 2 as well.
+ */
+ BUG_ON(page_count(old_page) != 1 &&
+ page_count(old_page) != 2);
BUG_ON(huge_pte_none(pte));
spin_lock(&mm->page_table_lock);
ptep = huge_pte_offset(mm, address & huge_page_mask(h));
--
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/