Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6e04c19 authored by Muchun Song's avatar Muchun Song Committed by Greg Kroah-Hartman
Browse files

mm: hugetlbfs: fix cannot migrate the fallocated HugeTLB page

commit 585fc0d2871c9318c949fbf45b1f081edd489e96 upstream.

If a new hugetlb page is allocated during fallocate it will not be
marked as active (set_page_huge_active) which will result in a later
isolate_huge_page failure when the page migration code would like to
move that page.  Such a failure would be unexpected and wrong.

Only export set_page_huge_active, just leave clear_page_huge_active as
static.  Because there are no external users.

Link: https://lkml.kernel.org/r/20210115124942.46403-3-songmuchun@bytedance.com


Fixes: 70c3547e (hugetlbfs: add hugetlbfs_fallocate())
Signed-off-by: default avatarMuchun Song <songmuchun@bytedance.com>
Acked-by: default avatarMichal Hocko <mhocko@suse.com>
Reviewed-by: default avatarMike Kravetz <mike.kravetz@oracle.com>
Reviewed-by: default avatarOscar Salvador <osalvador@suse.de>
Cc: David Hildenbrand <david@redhat.com>
Cc: Yang Shi <shy828301@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e06c6b69
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -654,9 +654,10 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,

		mutex_unlock(&hugetlb_fault_mutex_table[hash]);

		set_page_huge_active(page);
		/*
		 * unlock_page because locked by add_to_page_cache()
		 * page_put due to reference from alloc_huge_page()
		 * put_page() due to reference from alloc_huge_page()
		 */
		unlock_page(page);
		put_page(page);
+3 −0
Original line number Diff line number Diff line
@@ -541,6 +541,9 @@ static inline void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr
	set_huge_pte_at(mm, addr, ptep, pte);
}
#endif

void set_page_huge_active(struct page *page);

#else	/* CONFIG_HUGETLB_PAGE */
struct hstate {};
#define alloc_huge_page(v, a, r) NULL
+1 −1
Original line number Diff line number Diff line
@@ -1201,7 +1201,7 @@ bool page_huge_active(struct page *page)
}

/* never called for tail page */
static void set_page_huge_active(struct page *page)
void set_page_huge_active(struct page *page)
{
	VM_BUG_ON_PAGE(!PageHeadHuge(page), page);
	SetPagePrivate(&page[1]);