hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9935 -------------------------------- Enable longterm pin for pages/task belongs to dpool. User task and its memory must be unpined during dpool removal, otherwise dpool offlinine will failed. Fixes: cf98ffbc116b ("mm/dynamic_pool: fill dpool with pagelist") Signed-off-by: Wupeng Ma <mawupeng1@huawei.com> --- include/linux/dynamic_pool.h | 19 ------------------- include/linux/mm.h | 36 ++++++++++++++++++++++++++++++++++++ mm/gup.c | 3 ++- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/include/linux/dynamic_pool.h b/include/linux/dynamic_pool.h index 88bacd3ddb999..9f53ad2d80647 100644 --- a/include/linux/dynamic_pool.h +++ b/include/linux/dynamic_pool.h @@ -8,9 +8,6 @@ #ifdef CONFIG_DYNAMIC_POOL -DECLARE_STATIC_KEY_FALSE(dynamic_pool_key); -#define dpool_enabled (static_branch_unlikely(&dynamic_pool_key)) - enum pages_pool_type { PAGES_POOL_1G, PAGES_POOL_2M, @@ -77,7 +74,6 @@ struct dpool_info { struct range pfn_ranges[]; }; -bool __mm_in_dynamic_pool(struct mm_struct *mm); static inline bool mm_in_dynamic_pool(struct mm_struct *mm) { if (!dpool_enabled) @@ -86,14 +82,6 @@ static inline bool mm_in_dynamic_pool(struct mm_struct *mm) return __mm_in_dynamic_pool(mm); } -static inline bool page_from_dynamic_pool(struct page *page) -{ - if (!dpool_enabled) - return false; - - return PagePool(page); -} - static inline bool file_in_dynamic_pool(struct hugetlbfs_inode_info *p) { if (!dpool_enabled) @@ -135,16 +123,9 @@ int dpool_init(struct dpool_info *arg); void dynamic_pool_show_meminfo(struct seq_file *m); #else -#define dpool_enabled 0 - struct dynamic_pool {}; struct dpool_info {}; -static inline bool page_from_dynamic_pool(struct page *page) -{ - return false; -} - static inline bool mm_in_dynamic_pool(struct mm_struct *mm) { return false; diff --git a/include/linux/mm.h b/include/linux/mm.h index 39d926160c8ca..4788ff7421b8f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2063,10 +2063,46 @@ static inline bool is_zero_folio(const struct folio *folio) return is_zero_page(&folio->page); } +#ifdef CONFIG_DYNAMIC_POOL +DECLARE_STATIC_KEY_FALSE(dynamic_pool_key); +#define dpool_enabled (static_branch_unlikely(&dynamic_pool_key)) + +static inline bool page_from_dynamic_pool(struct page *page) +{ + if (!dpool_enabled) + return false; + + return PagePool(page); +} + +bool __mm_in_dynamic_pool(struct mm_struct *mm); +#else +#define dpool_enabled 0 + +static inline bool page_from_dynamic_pool(struct page *page) +{ + return false; +} + +static inline bool __mm_in_dynamic_pool(struct mm_struct *mm) +{ + return false; +} +#endif + /* MIGRATE_CMA and ZONE_MOVABLE do not allow pin folios */ #ifdef CONFIG_MIGRATION static inline bool folio_is_longterm_pinnable(struct folio *folio) { + /* + * Memory migration and offlining will be preventd if pages is + * Pinned. However dpool memory must be unpinned and related + * processes terminated before taking the dpool offline, which + * avoids this interference. + */ + if (page_from_dynamic_pool(&folio->page)) + return true; + #ifdef CONFIG_CMA int mt = folio_migratetype(folio); diff --git a/mm/gup.c b/mm/gup.c index 5d8a4866431b3..a39bd5869b98f 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -2128,7 +2128,8 @@ static long __gup_longterm_locked(struct mm_struct *mm, unsigned int flags; long rc, nr_pinned_pages; - if (!(gup_flags & FOLL_LONGTERM)) + if (!(gup_flags & FOLL_LONGTERM) || + __mm_in_dynamic_pool(mm)) return __get_user_pages_locked(mm, start, nr_pages, pages, locked, gup_flags); -- 2.43.0