]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm/hugetlb: copy the CMA flag when demoting
authorFrank van der Linden <fvdl@google.com>
Thu, 1 May 2025 04:43:24 +0000 (04:43 +0000)
committerAndrew Morton <akpm@linux-foundation.org>
Thu, 8 May 2025 06:39:42 +0000 (23:39 -0700)
Since commit d2d786714080 ("mm/hugetlb: enable bootmem allocation from CMA
areas"), a flag is used to mark hugetlb folios as allocated from CMA.
This flag is also used to decide if it should be freed to CMA.

However, the flag isn't copied to the smaller folios when a hugetlb folio
is broken up for demotion, which would cause it to be freed incorrectly.

Fix this by copying the flag to the smaller order hugetlb pages created
from the original one.

Link: https://lkml.kernel.org/r/20250501044325.20365-1-fvdl@google.com
Fixes: d2d786714080 ("mm/hugetlb: enable bootmem allocation from CMA areas")
Signed-off-by: Frank van der Linden <fvdl@google.com>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Reviewed-by: Oscar Salvador <osalvador@suse.de>
Reviewed-by: Jane Chu <Jane.Chu@oracle.com>
Cc: Muchun Song <muchun.song@linux.dev>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/hugetlb.c

index e3e6ac991b9c6bd53f5c0ebf6aa74ea9740592cf..6ea1be71aa429e42f746965b75e5f95404cb70e2 100644 (file)
@@ -4034,10 +4034,13 @@ static long demote_free_hugetlb_folios(struct hstate *src, struct hstate *dst,
 
        list_for_each_entry_safe(folio, next, src_list, lru) {
                int i;
+               bool cma;
 
                if (folio_test_hugetlb_vmemmap_optimized(folio))
                        continue;
 
+               cma = folio_test_hugetlb_cma(folio);
+
                list_del(&folio->lru);
 
                split_page_owner(&folio->page, huge_page_order(src), huge_page_order(dst));
@@ -4053,6 +4056,9 @@ static long demote_free_hugetlb_folios(struct hstate *src, struct hstate *dst,
 
                        new_folio->mapping = NULL;
                        init_new_hugetlb_folio(dst, new_folio);
+                       /* Copy the CMA flag so that it is freed correctly */
+                       if (cma)
+                               folio_set_hugetlb_cma(new_folio);
                        list_add(&new_folio->lru, &dst_list);
                }
        }