From: Qi Zheng Long-term pinning treats explicitly CMA-allocated HugeTLB folios as unpinnable, causing unnecessary migration or pinning failures. These folios already own their CMA bitmap ranges, and memory blocks overlapping CMA areas cannot be offlined. Allow HugeTLB folios with HPG_cma to be pinned directly, including in ZONE_MOVABLE. Fixes: cf11e85fc08c ("mm: hugetlb: optionally allocate gigantic hugepages using cma") Cc: stable@vger.kernel.org Suggested-by: Muchun Song Signed-off-by: Qi Zheng Acked-by: Muchun Song Reviewed-by: Oscar Salvador Reviewed-by: Jose A. Perez de Azpillaga --- include/linux/mm.h | 29 +---------------------------- mm/gup.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index b0da9be413098..47d1d96bfc7fd 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2954,35 +2954,8 @@ static inline bool is_zero_folio(const struct folio *folio) return is_zero_page(&folio->page); } -/* MIGRATE_CMA and ZONE_MOVABLE do not allow pin folios */ #ifdef CONFIG_MIGRATION -static inline bool folio_is_longterm_pinnable(struct folio *folio) -{ -#ifdef CONFIG_CMA - int mt = folio_migratetype(folio); - - if (mt == MIGRATE_CMA || mt == MIGRATE_ISOLATE) - return false; -#endif - /* The zero page can be "pinned" but gets special handling. */ - if (is_zero_folio(folio)) - return true; - - /* Coherent device memory must always allow eviction. */ - if (folio_is_device_coherent(folio)) - return false; - - /* - * Filesystems can only tolerate transient delays to truncate and - * hole-punch operations - */ - if (folio_is_fsdax(folio)) - return false; - - /* Otherwise, non-movable zone folios can be pinned. */ - return !folio_is_zone_movable(folio); - -} +bool folio_is_longterm_pinnable(struct folio *folio); #else static inline bool folio_is_longterm_pinnable(struct folio *folio) { diff --git a/mm/gup.c b/mm/gup.c index ebbfee09b7278..fdafc5a1b78ed 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -2219,6 +2219,37 @@ struct page *get_dump_page(unsigned long addr, int *locked) #ifdef CONFIG_MIGRATION +bool folio_is_longterm_pinnable(struct folio *folio) +{ +#ifdef CONFIG_CMA + int mt = folio_migratetype(folio); + + /* These HugeTLB folios own the CMA memory, so they can be long-term pinned. */ + if (folio_test_hugetlb(folio) && folio_test_hugetlb_cma(folio)) + return true; + + if (mt == MIGRATE_CMA || mt == MIGRATE_ISOLATE) + return false; +#endif + /* The zero page can be "pinned" but gets special handling. */ + if (is_zero_folio(folio)) + return true; + + /* Coherent device memory must always allow eviction. */ + if (folio_is_device_coherent(folio)) + return false; + + /* + * Filesystems can only tolerate transient delays to truncate and + * hole-punch operations + */ + if (folio_is_fsdax(folio)) + return false; + + /* Otherwise, non-movable zone folios can be pinned. */ + return !folio_is_zone_movable(folio); +} + /* * An array of either pages or folios ("pofs"). Although it may seem tempting to * avoid this complication, by simply interpreting a list of folios as a list of -- 2.54.0