提交 b9676dea 编写于 作者: L Liu Shixin 提交者: openeuler-sync-bot

mm/dynamic_hugetlb: isolate hugepage without dissolve

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6XOIE
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: NLiu Shixin <liushixin2@huawei.com>
(cherry picked from commit 2430060b)
上级 8b0a5ac3
......@@ -104,6 +104,7 @@ int dhugetlb_acct_memory(struct hstate *h, long delta, struct hugetlbfs_inode_in
struct page *alloc_huge_page_from_dhugetlb_pool(struct hstate *h, struct dhugetlb_pool *hpool,
bool need_unreserved);
void free_huge_page_to_dhugetlb_pool(struct page *page, bool restore_reserve);
bool page_belong_to_dynamic_hugetlb(struct page *page);
#else
......@@ -171,6 +172,11 @@ static inline
void free_huge_page_to_dhugetlb_pool(struct page *page, bool restore_reserve)
{
}
static inline
bool page_belong_to_dynamic_hugetlb(struct page *page)
{
return false;
}
#endif
#endif /* CONFIG_DYNAMIC_HUGETLB */
......
......@@ -448,6 +448,19 @@ static struct dhugetlb_pool *find_hpool_by_dhugetlb_pagelist(struct page *page)
return hpool;
}
bool page_belong_to_dynamic_hugetlb(struct page *page)
{
struct dhugetlb_pool *hpool;
if (!dhugetlb_enabled)
return false;
hpool = find_hpool_by_dhugetlb_pagelist(page);
if (hpool)
return true;
return false;
}
static struct dhugetlb_pool *find_hpool_by_task(struct task_struct *tsk)
{
struct mem_cgroup *memcg;
......@@ -740,8 +753,15 @@ void free_huge_page_to_dhugetlb_pool(struct page *page, bool restore_reserve)
}
spin_lock(&hpool->lock);
/*
* memory_failure will free the hwpoison hugepage, and then try to
* dissolve it and free subpage to buddy system. Since the page in
* dhugetlb_pool should not free to buudy system, we isolate the
* hugepage here directly, and skip the latter dissolution.
*/
if (PageHWPoison(page))
goto out;
ClearPagePool(page);
set_compound_page_dtor(page, NULL_COMPOUND_DTOR);
if (hstate_is_gigantic(h))
hpages_pool = &hpool->hpages_pool[HUGE_PAGES_POOL_1G];
else
......@@ -757,6 +777,7 @@ void free_huge_page_to_dhugetlb_pool(struct page *page, bool restore_reserve)
}
trace_dynamic_hugetlb_alloc_free(hpool, page, hpages_pool->free_huge_pages,
DHUGETLB_FREE, huge_page_size(h));
out:
spin_unlock(&hpool->lock);
put_hpool(hpool);
}
......
......@@ -2025,6 +2025,13 @@ int dissolve_free_huge_page(struct page *page)
if (!PageHuge(page))
return 0;
/*
* the page belong to dynamic hugetlb will be isolated as a whole
* when free. See free_huge_page_to_dhugetlb_pool() for detail.
*/
if (page_belong_to_dynamic_hugetlb(page))
return -EBUSY;
spin_lock_irq(&hugetlb_lock);
if (!PageHuge(page)) {
rc = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册