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

mm/dynamic_hugetlb: fix clear PagePool without lock protection

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


CVE: NA

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

Since free_pages_prepare() will clear the PagePool without lock in
free_page_to_dhugetlb_pool() and free_page_list_to_dhugetlb_pool(),
it is unreliable to check whether a page is freed by PagePool in
hpool_merge_page().
Move free_pages_prepare() after ClearPagePool(), which can guarantee
all allocated page has PagePool flag.

Fixes: 71197c63 ("mm/dynamic_hugetlb: free pages to dhugetlb_pool")
Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
Reviewed-by: default avatarTong Tiangen <tongtiangen@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 5b627e2b
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -577,6 +577,10 @@ static void __free_page_to_dhugetlb_pool(struct page *page)
	spin_lock_irqsave(&percpu_pool->lock, flags);

	ClearPagePool(page);
	if (!free_pages_prepare(page, 0, true)) {
		SetPagePool(page);
		goto out;
	}
	list_add(&page->lru, &percpu_pool->head_page);
	percpu_pool->free_pages++;
	percpu_pool->used_pages--;
@@ -585,7 +589,7 @@ static void __free_page_to_dhugetlb_pool(struct page *page)
		reclaim_pages_from_percpu_pool(hpool, percpu_pool, PERCPU_POOL_PAGE_BATCH);
		spin_unlock(&hpool->lock);
	}

out:
	spin_unlock_irqrestore(&percpu_pool->lock, flags);
	put_hpool(hpool);
}
@@ -595,7 +599,6 @@ bool free_page_to_dhugetlb_pool(struct page *page)
	if (!dhugetlb_enabled || !PagePool(page))
		return false;

	if (free_pages_prepare(page, 0, true))
	__free_page_to_dhugetlb_pool(page);
	return true;
}
@@ -610,7 +613,6 @@ void free_page_list_to_dhugetlb_pool(struct list_head *list)
	list_for_each_entry_safe(page, next, list, lru) {
		if (PagePool(page)) {
			list_del(&page->lru);
			if (free_pages_prepare(page, 0, true))
			__free_page_to_dhugetlb_pool(page);
		}
	}