hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8S9BY CVE: NA
--------------------------------
When merge 4K subpages to 2M size, some subpages may be in used. Call do_migrate_range() to free these pages.
Signed-off-by: Liu Shixin liushixin2@huawei.com --- include/linux/memory_hotplug.h | 5 +++++ mm/dynamic_pool.c | 5 +++++ mm/memory_hotplug.c | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index a7164c67dcd8..0580ddf546fc 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -308,6 +308,7 @@ static inline void pgdat_resize_init(struct pglist_data *pgdat) {}
#ifdef CONFIG_MEMORY_HOTREMOVE
+extern void do_migrate_range(unsigned long start_pfn, unsigned long end_pfn); extern void try_offline_node(int nid); extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages, struct zone *zone, struct memory_group *group); @@ -316,6 +317,10 @@ extern void __remove_memory(u64 start, u64 size); extern int offline_and_remove_memory(u64 start, u64 size);
#else +static inline void do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) +{ +} + static inline void try_offline_node(int nid) {}
static inline int offline_pages(unsigned long start_pfn, unsigned long nr_pages, diff --git a/mm/dynamic_pool.c b/mm/dynamic_pool.c index da442a9afdc8..51f4d0cd04f8 100644 --- a/mm/dynamic_pool.c +++ b/mm/dynamic_pool.c @@ -310,6 +310,8 @@ static int dpool_promote_pool(struct dynamic_pool *dpool, int type) ret = dpool_promote_gigantic_page(src_pool, dst_pool, spage); break; case PAGES_POOL_2M: { + unsigned long nr_pages = 1 << PMD_ORDER; + /* * Since the dpool_mutex is already locked, * there is no way to free spage_next, so @@ -317,6 +319,9 @@ static int dpool_promote_pool(struct dynamic_pool *dpool, int type) */ spin_unlock(&dpool->lock); cond_resched(); + lru_add_drain_all(); + do_migrate_range(spage->start_pfn, + spage->start_pfn + nr_pages); spin_lock(&dpool->lock); ret = dpool_promote_huge_page(src_pool, dst_pool, spage); break; diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 144758820e3a..6f949d1b2eb0 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1698,7 +1698,7 @@ static int scan_movable_pages(unsigned long start, unsigned long end, return 0; }
-static void do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) +void do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) { unsigned long pfn; struct page *page, *head;