Commit 687fb2b1 authored by Liu Shixin's avatar Liu Shixin Committed by Zheng Zengkai
Browse files

mm/dynamic_hugetlb: hold the lock until pages back to hugetlb

hulk inclusion
category: bugfix
bugzilla: 46904 https://gitee.com/openeuler/kernel/issues/I4Y0XO



--------------------------------

Do not release the lock after merging all pages, otherwise some other process
may allocate the pages, and then some pages can't be put back to hugetlb.

Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
Reviewed-by: default avatarKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 94c749a3
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -305,7 +305,8 @@ static int hugetlb_pool_merge_all_pages(struct dhugetlb_pool *hpool)
{
	int ret = 0;

	spin_lock(&hpool->lock);
	lockdep_assert_held(&hpool->lock);

	while (hpool->hpages_pool[HUGE_PAGES_POOL_2M].split_normal_pages) {
		ret = hpool_merge_page(hpool, HUGE_PAGES_POOL_2M, true);
		if (ret) {
@@ -329,7 +330,6 @@ static int hugetlb_pool_merge_all_pages(struct dhugetlb_pool *hpool)
		goto out;
	}
out:
	spin_unlock(&hpool->lock);
	return ret;
}

@@ -767,7 +767,8 @@ static int free_hugepage_to_hugetlb(struct dhugetlb_pool *hpool)
	if (!h)
		return ret;

	spin_lock(&hpool->lock);
	lockdep_assert_held(&hpool->lock);

	spin_lock(&hugetlb_lock);
	list_for_each_entry_safe(page, next, &hpages_pool->hugepage_freelists, lru) {
		nr_pages = 1 << huge_page_order(h);
@@ -791,7 +792,6 @@ static int free_hugepage_to_hugetlb(struct dhugetlb_pool *hpool)
			break;
	}
	spin_unlock(&hugetlb_lock);
	spin_unlock(&hpool->lock);
	return ret;
}

@@ -855,12 +855,15 @@ int hugetlb_pool_destroy(struct cgroup *cgrp)
	 */
	mem_cgroup_force_empty(hpool->attach_memcg);

	spin_lock(&hpool->lock);
	ret = hugetlb_pool_merge_all_pages(hpool);
	if (ret)
	if (ret) {
		spin_unlock(&hpool->lock);
		return -ENOMEM;
	}
	ret = free_hugepage_to_hugetlb(hpool);
	memcg->hpool = NULL;

	spin_unlock(&hpool->lock);
	put_hpool(hpool);
	return ret;
}