Messages in this thread Patch in this message | | | From | "Kirill A. Shutemov" <> | Subject | [PATCH 08/19] mm: prepare migration code for new THP refcounting | Date | Wed, 5 Nov 2014 16:49:43 +0200 |
| |
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@linux.intel.com> --- 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
| |