From 20f0535e57da26c55284cac6f364f27c399e3656 Mon Sep 17 00:00:00 2001 From: Liu Shixin Date: Sat, 4 Feb 2023 07:55:03 +0000 Subject: [PATCH] dhugetlb: skip dissolve hugepage belonging to dynamic hugetlb hulk inclusion category: feature bugzilla: 46904, https://gitee.com/openeuler/kernel/issues/I6BDME CVE: NA -------------------------------- The memory hotplug and memory failure will dissolve freed hugepages to buddy system, this is not the expected behavior for dynamic hugetlb. Skip the dissolve operation for hugepages belonging to dynamic hugetlb. For memory hotplug, the hotplug operation is not allowed, if dhugetlb pool existed. For memory failure, the hugepage will be discard directly. Signed-off-by: Liu Shixin Reviewed-by: Kefeng Wang Signed-off-by: Yongqiang Liu --- include/linux/hugetlb.h | 5 +++++ mm/hugetlb.c | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 92fd6e2cbaf3..a26cbc4398a4 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -751,6 +751,11 @@ static inline struct dhugetlb_pool *get_dhugetlb_pool_from_task( { return NULL; } +static inline struct dhugetlb_pool *get_dhugetlb_pool_from_dhugetlb_pagelist( + struct page *page) +{ + return NULL; +} static inline void dhugetlb_pool_put(struct dhugetlb_pool *hpool) { return; } #endif /* CONFIG_DYNAMIC_HUGETLB */ diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 8b88ac4620d5..625882b7cd97 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1769,12 +1769,20 @@ static int free_pool_huge_page(struct hstate *h, nodemask_t *nodes_allowed, int dissolve_free_huge_page(struct page *page) { int rc = -EBUSY; + struct dhugetlb_pool *hpool; retry: /* Not to disrupt normal path by vainly holding hugetlb_lock */ if (!PageHuge(page)) return 0; + /* Skip dissolve hugepage for dynamic hugetlb */ + hpool = get_dhugetlb_pool_from_dhugetlb_pagelist(page); + if (hpool) { + dhugetlb_pool_put(hpool); + return -EBUSY; + } + spin_lock(&hugetlb_lock); if (!PageHuge(page)) { rc = 0; @@ -3426,8 +3434,12 @@ struct dhugetlb_pool *get_dhugetlb_pool_from_dhugetlb_pagelist( struct page *page) { struct dhugetlb_pool *hpool = NULL; - unsigned long idx = page_to_pfn(page) >> (PUD_SHIFT - PAGE_SHIFT); + unsigned long idx; + + if (!dhugetlb_enabled) + return NULL; + idx = page_to_pfn(page) >> (PUD_SHIFT - PAGE_SHIFT); read_lock(&dhugetlb_pagelist_rwlock); if (idx < dhugetlb_pagelist_t->count) hpool = dhugetlb_pagelist_t->hpool[idx]; -- GitLab