summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/hugetlbfs/inode.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 6e97a54ffda1..306da7cb3d8b 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -515,13 +515,13 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
/*
* If page is mapped, it was faulted in after being
- * unmapped in caller. Unmap (again) now after taking
- * the fault mutex. The mutex will prevent faults
- * until we finish removing the page.
- *
- * This race can only happen in the hole punch case.
- * Getting here in a truncate operation is a bug.
+ * unmapped in caller or hugetlb_vmdelete_list() skips
+ * unmapping it due to fail to grab lock. Unmap (again)
+ * while holding the fault mutex. The mutex will prevent
+ * faults until we finish removing the page. Hold page
+ * lock to guarantee no concurrent migration.
*/
+ lock_page(page);
if (unlikely(page_mapped(page))) {
BUG_ON(truncate_op);
@@ -533,8 +533,6 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
(index + 1) * pages_per_huge_page(h));
i_mmap_unlock_write(mapping);
}
-
- lock_page(page);
/*
* We must free the huge page and remove from page
* cache (remove_huge_page) BEFORE removing the