Commit 9966b579 authored by Mike Kravetz's avatar Mike Kravetz Committed by Liu Shixin
Browse files

hugetlb: check for hugetlb folio before vmemmap_restore

mainline inclusion
from mainline-v6.7-rc1
commit 30a89adf872d2e46323840964c95dc0ae3bb5843
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I9R3AY
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=30a89adf872d2e46323840964c95dc0ae3bb5843

--------------------------------

In commit d8f5f7e445f0 ("hugetlb: set hugetlb page flag before
optimizing vmemmap") checks were added to print a warning if
hugetlb_vmemmap_restore was called on a non-hugetlb page.

This was mostly due to ordering issues in the hugetlb page set up and tear
down sequencees.  One place missed was the routine
dissolve_free_huge_page.

Naoya Horiguchi noted: "I saw that VM_WARN_ON_ONCE() in
hugetlb_vmemmap_restore is triggered when memory_failure() is called on a
free hugetlb page with vmemmap optimization disabled (the warning is not
triggered if vmemmap optimization is enabled).  I think that we need check
folio_test_hugetlb() before dissolve_free_huge_page() calls
hugetlb_vmemmap_restore_folio()."

Perform the check as suggested by Naoya.

Link: https://lkml.kernel.org/r/20231017032140.GA3680@monkey


Fixes: d8f5f7e445f0 ("hugetlb: set hugetlb page flag before optimizing vmemmap")
Signed-off-by: default avatarMike Kravetz <mike.kravetz@oracle.com>
Suggested-by: default avatarNaoya Horiguchi <naoya.horiguchi@linux.dev>
Tested-by: default avatarNaoya Horiguchi <naoya.horiguchi@linux.dev>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Barry Song <song.bao.hua@hisilicon.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Joao Martins <joao.m.martins@oracle.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Muchun Song <songmuchun@bytedance.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Xiongchun Duan <duanxiongchun@bytedance.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
parent fb24953c
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -2411,17 +2411,23 @@ int dissolve_free_huge_page(struct page *page)
		 * need to adjust max_huge_pages if the page is not freed.
		 * Attempt to allocate vmemmmap here so that we can take
		 * appropriate action on failure.
		 *
		 * The folio_test_hugetlb check here is because
		 * remove_hugetlb_folio will clear hugetlb folio flag for
		 * non-vmemmap optimized hugetlb folios.
		 */
		if (folio_test_hugetlb(folio)) {
			rc = hugetlb_vmemmap_restore(h, &folio->page);
		if (!rc) {
			update_and_free_hugetlb_folio(h, folio, false);
		} else {
			if (rc) {
				spin_lock_irq(&hugetlb_lock);
				add_hugetlb_folio(h, folio, false);
				h->max_huge_pages++;
			spin_unlock_irq(&hugetlb_lock);
				goto out;
			}
		} else
			rc = 0;

		update_and_free_hugetlb_folio(h, folio, false);
		return rc;
	}
out: