[PATCH 08/19] mm: prepare migration code for new THP refcounting

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

 



With new refcounting VMAs can start or end in the middle of huge page.
We need to modify code to call split_huge_page() properly.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx>
---
 mm/migrate.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/mm/migrate.c b/mm/migrate.c
index f1a12ced2531..4dc941100388 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1235,7 +1235,7 @@ static int do_move_page_to_node_array(struct mm_struct *mm,
 		vma = find_vma(mm, pp->addr);
 		if (!vma || pp->addr < vma->vm_start || !vma_migratable(vma))
 			goto set_status;
-
+retry:
 		page = follow_page(vma, pp->addr, FOLL_GET);
 
 		err = PTR_ERR(page);
@@ -1246,9 +1246,27 @@ static int do_move_page_to_node_array(struct mm_struct *mm,
 		if (!page)
 			goto set_status;
 
-		if (PageTransHuge(page) && split_huge_page(page)) {
-			err = -EBUSY;
-			goto set_status;
+		if (PageTransCompound(page)) {
+			struct page *head_page = compound_head(page);
+
+			/*
+			 * split_huge_page() wants pin to be only on head page
+			 */
+			if (page != head_page) {
+				get_page(head_page);
+				put_page(page);
+			}
+
+			err = split_huge_page(head_page);
+			if (err) {
+				put_page(head_page);
+				goto set_status;
+			}
+
+			if (page != head_page) {
+				put_page(head_page);
+				goto retry;
+			}
 		}
 
 		/* Use PageReserved to check for zero page */
-- 
2.1.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxx.  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]