Commit 93b77bfa authored by Liu Shixin's avatar Liu Shixin
Browse files

mm/dynamic_pool: compatible with HugeTLB dissolve

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8S9BY


CVE: NA

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

Hugetlb may be dissolved from compaction or hwpoison. Do not dissolve
pages in dpool.

Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
parent 35e812f6
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ static inline bool file_in_dynamic_pool(struct hugetlbfs_inode_info *p)
	return p && p->dpool;
}

bool page_in_dynamic_pool(struct page *page);
int dynamic_pool_can_attach(struct task_struct *tsk, struct mem_cgroup *memcg);
struct page *dynamic_pool_alloc_page(gfp_t gfp, unsigned int order,
				     unsigned int alloc_flags);
@@ -143,6 +144,11 @@ static inline bool task_in_dynamic_pool(struct task_struct *tsk)
	return false;
}

static inline bool page_in_dynamic_pool(const struct page *page)
{
	return false;
}

static inline int dynamic_pool_can_attach(struct task_struct *tsk,
					  struct mem_cgroup *memcg)
{
+39 −0
Original line number Diff line number Diff line
@@ -149,6 +149,45 @@ bool __task_in_dynamic_pool(struct task_struct *tsk)
	return !!dpool;
}

bool page_in_dynamic_pool(struct page *page)
{
	struct dynamic_pool *dpool;
	bool ret;

	if (!dpool_enabled)
		return false;

	if (PageDpool(page))
		return true;

	/*
	 * If the page don't have the flags, it may be in pcp list.
	 * Check it using the page range.
	 */
	dpool = dpool_get_from_page(page);
	if (enable_dpagelist && dpool) {
		unsigned long pfn = page_to_pfn(page);
		int range_cnt = dpool->range_cnt;
		struct range *range;
		int i;

		for (i = 0; i < range_cnt; i++) {
			range = &dpool->pfn_ranges[i];
			if (pfn >= range->start && pfn <= range->end)
				goto out;
		}

		/* The pfn is not in the range, set dpool to NULL */
		dpool = NULL;
	}

out:
	ret = dpool ? !PagePool(page) : false;
	dpool_put(dpool);

	return ret;
}

/* === demote and promote function ==================================== */

static void dpool_disable_pcp_pool(struct dynamic_pool *dpool, bool drain);
+6 −0
Original line number Diff line number Diff line
@@ -2399,6 +2399,9 @@ int dissolve_free_huge_page(struct page *page)
	if (!folio_test_hugetlb(folio))
		return 0;

	if (page_from_dynamic_pool(page) || page_in_dynamic_pool(page))
		return -EBUSY;

	spin_lock_irq(&hugetlb_lock);
	if (!folio_test_hugetlb(folio)) {
		rc = 0;
@@ -3101,6 +3104,9 @@ int isolate_or_dissolve_huge_page(struct page *page, struct list_head *list)
	struct folio *folio = page_folio(page);
	int ret = -EBUSY;

	if (page_from_dynamic_pool(page) || page_in_dynamic_pool(page))
		return -EBUSY;

	/*
	 * The page might have been dissolved from under our feet, so make sure
	 * to carefully check the state under the lock.