hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I9K8D1 CVE: NA
--------------------------------
Add check of resv_huge_pages in hugetlb_pool_merge_all_pages() and print more accurate error information. Reset the counter to prevent allocation.
Fixes: 29617b44eb8a ("mm/dynamic_hugetlb: add merge page function") Signed-off-by: Liu Shixin liushixin2@huawei.com --- mm/dynamic_hugetlb.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/mm/dynamic_hugetlb.c b/mm/dynamic_hugetlb.c index c40d436b1d2b..72061fd0395e 100644 --- a/mm/dynamic_hugetlb.c +++ b/mm/dynamic_hugetlb.c @@ -393,32 +393,49 @@ static int hpool_merge_page(struct dhugetlb_pool *hpool, int hpages_pool_idx, bo
static int hugetlb_pool_merge_all_pages(struct dhugetlb_pool *hpool) { + struct huge_pages_pool *hpages_pool; int ret = 0;
lockdep_assert_held(&hpool->lock);
- while (hpool->hpages_pool[HUGE_PAGES_POOL_2M].split_normal_pages) { + hpages_pool = &hpool->hpages_pool[HUGE_PAGES_POOL_2M]; + while (hpages_pool->split_normal_pages) { ret = hpool_merge_page(hpool, HUGE_PAGES_POOL_2M, true); if (ret) { - pr_err("dynamic_hugetlb: some 4K pages are still in use, delete memcg: %s failed!\n", + pr_err("dynamic_hugetlb: %s: merge 4K failed!\n", hpool->attach_memcg->css.cgroup->kn->name); goto out; } } - while (hpool->hpages_pool[HUGE_PAGES_POOL_1G].split_normal_pages) { + if (hpages_pool->used_huge_pages || hpages_pool->resv_huge_pages) { + ret = -ENOMEM; + pr_err("dynamic_hugetlb: %s: 2M pages in use or resv\n", + hpool->attach_memcg->css.cgroup->kn->name); + goto out; + } + hpages_pool->free_normal_pages += hpages_pool->nr_huge_pages; + hpages_pool->nr_huge_pages = 0; + hpages_pool->free_huge_pages = 0; + + hpages_pool = &hpool->hpages_pool[HUGE_PAGES_POOL_1G]; + while (hpages_pool->split_normal_pages) { ret = hpool_merge_page(hpool, HUGE_PAGES_POOL_1G, true); if (ret) { - pr_err("dynamic_hugetlb: some 2M pages are still in use, delete memcg: %s failed!\n", + pr_err("dynamic_hugetlb: %s: merge 2M failed!\n", hpool->attach_memcg->css.cgroup->kn->name); goto out; } } - if (hpool->hpages_pool[HUGE_PAGES_POOL_1G].used_huge_pages) { + if (hpages_pool->used_huge_pages || hpages_pool->resv_huge_pages) { ret = -ENOMEM; - pr_err("dynamic_hugetlb: some 1G pages are still in use, delete memcg: %s failed!\n", + pr_err("dynamic_hugetlb: %s: 1G pages in use or resv\n", hpool->attach_memcg->css.cgroup->kn->name); goto out; } + hpages_pool->free_normal_pages += hpages_pool->nr_huge_pages; + hpages_pool->nr_huge_pages = 0; + hpages_pool->free_huge_pages = 0; + out: return ret; }