diff options
-rw-r--r-- | fs/hugetlbfs/inode.c | 10 | ||||
-rw-r--r-- | mm/migrate.c | 10 |
2 files changed, 18 insertions, 2 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 32920a10100e..fb6de1db8806 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -859,6 +859,16 @@ static int hugetlbfs_migrate_page(struct address_space *mapping, rc = migrate_huge_page_move_mapping(mapping, newpage, page); if (rc != MIGRATEPAGE_SUCCESS) return rc; + + /* + * page_private is subpool pointer in hugetlb pages, transfer + * if needed. + */ + if (page_private(page) && !page_private(newpage)) { + set_page_private(newpage, page_private(page)); + set_page_private(page, 0); + } + if (mode != MIGRATE_SYNC_NO_COPY) migrate_page_copy(newpage, page); else diff --git a/mm/migrate.c b/mm/migrate.c index d4fd680be3b0..a4bab46b8890 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -641,8 +641,14 @@ void migrate_page_states(struct page *newpage, struct page *page) */ if (PageSwapCache(page)) ClearPageSwapCache(page); - ClearPagePrivate(page); - set_page_private(page, 0); + /* + * Unlikely, but PagePrivate and page_private could potentially + * contain information needed at hugetlb free page time. + */ + if (!PageHuge(page)) { + ClearPagePrivate(page); + set_page_private(page, 0); + } /* * If any waiters have accumulated on the new page then |