Commit 6f1e0f63 authored by Liu Shixin's avatar Liu Shixin
Browse files

mm/dynamic_pool: add interface to configure the count of hugepages

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


CVE: NA

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

Add two interfaces to configure the count of 1G/2M hugepages.
	`echo <number> > dhugetlb.1G.reserved_page`
	`echo <number> > dhugetlb.2M.reserved_page`

Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
parent 4bd64dfd
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -22,6 +22,12 @@ struct pages_pool {
	unsigned long free_pages;
	unsigned long used_pages;
	struct list_head freelist;

	/* Used for hugepage allocation */
	unsigned long nr_huge_pages;
	unsigned long free_huge_pages;
	unsigned long resv_huge_pages;
	unsigned long used_huge_pages;
};

struct dynamic_pool_ops;
@@ -49,6 +55,8 @@ bool dynamic_pool_hide_files(struct cftype *cft);
int dynamic_pool_add_memory(struct mem_cgroup *memcg, int nid,
			    unsigned long size);
void dynamic_pool_show(struct mem_cgroup *memcg, struct seq_file *m);
int dynamic_pool_reserve_hugepage(struct mem_cgroup *memcg,
				  unsigned long nr_pages, int type);

#else
struct dynamic_pool {};
+57 −0
Original line number Diff line number Diff line
@@ -430,6 +430,22 @@ void dynamic_pool_show(struct mem_cgroup *memcg, struct seq_file *m)

	seq_printf(m, "nid %d\n", dpool->nid);
	seq_printf(m, "dhugetlb_total_pages %lu\n", dpool->total_pages);
	seq_printf(m, "1G_total_reserved_pages %lu\n",
		   dpool->pool[PAGES_POOL_1G].nr_huge_pages);
	seq_printf(m, "1G_free_reserved_pages %lu\n",
		   dpool->pool[PAGES_POOL_1G].free_huge_pages);
	seq_printf(m, "1G_mmap_reserved_pages %lu\n",
		   dpool->pool[PAGES_POOL_1G].resv_huge_pages);
	seq_printf(m, "1G_used_pages %lu\n",
		   dpool->pool[PAGES_POOL_1G].used_huge_pages);
	seq_printf(m, "2M_total_reserved_pages %lu\n",
		   dpool->pool[PAGES_POOL_2M].nr_huge_pages);
	seq_printf(m, "2M_free_reserved_pages %lu\n",
		   dpool->pool[PAGES_POOL_2M].free_huge_pages);
	seq_printf(m, "2M_mmap_reserved_pages %lu\n",
		   dpool->pool[PAGES_POOL_2M].resv_huge_pages);
	seq_printf(m, "2M_used_pages %lu\n",
		   dpool->pool[PAGES_POOL_2M].used_huge_pages);
	seq_printf(m, "1G_free_unreserved_pages %lu\n",
		   dpool->pool[PAGES_POOL_1G].free_pages);
	seq_printf(m, "2M_free_unreserved_pages %lu\n",
@@ -442,3 +458,44 @@ void dynamic_pool_show(struct mem_cgroup *memcg, struct seq_file *m)
	spin_unlock(&dpool->lock);
	dpool_put(dpool);
}

int dynamic_pool_reserve_hugepage(struct mem_cgroup *memcg,
				  unsigned long nr_pages, int type)
{
	struct dynamic_pool *dpool;
	struct pages_pool *pool;
	unsigned long delta;
	int ret = -EINVAL;

	if (!dpool_enabled)
		return -EINVAL;

	mutex_lock(&dpool_mutex);

	dpool = dpool_get_from_memcg(memcg);
	if (!dpool)
		goto unlock;

	pool = &dpool->pool[type];
	spin_lock(&dpool->lock);
	if (nr_pages > pool->nr_huge_pages) {
		delta = min(nr_pages - pool->nr_huge_pages, pool->free_pages);
		pool->nr_huge_pages += delta;
		pool->free_huge_pages += delta;
		pool->free_pages -= delta;
	} else {
		delta = min(pool->nr_huge_pages - nr_pages,
			    pool->free_huge_pages - pool->resv_huge_pages);
		pool->nr_huge_pages -= delta;
		pool->free_huge_pages -= delta;
		pool->free_pages += delta;
	}
	spin_unlock(&dpool->lock);
	dpool_put(dpool);
	ret = 0;

unlock:
	mutex_unlock(&dpool_mutex);

	return ret;
}
+46 −0
Original line number Diff line number Diff line
@@ -5786,6 +5786,42 @@ static int mem_cgroup_dpool_read(struct seq_file *m, void *v)

	return 0;
}

static ssize_t mem_cgroup_dpool_1G_write(struct kernfs_open_file *of,
					 char *buf, size_t nbytes, loff_t off)
{
	struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
	char *endp;
	unsigned long nr_pages;
	int ret;

	buf = strstrip(buf);
	nr_pages = memparse(buf, &endp);
	if (*endp != '\0')
		return -EINVAL;

	ret = dynamic_pool_reserve_hugepage(memcg, nr_pages, PAGES_POOL_1G);

	return ret ? : nbytes;
}

static ssize_t mem_cgroup_dpool_2M_write(struct kernfs_open_file *of,
					 char *buf, size_t nbytes, loff_t off)
{
	struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
	char *endp;
	unsigned long nr_pages;
	int ret;

	buf = strstrip(buf);
	nr_pages = memparse(buf, &endp);
	if (*endp != '\0')
		return -EINVAL;

	ret = dynamic_pool_reserve_hugepage(memcg, nr_pages, PAGES_POOL_2M);

	return ret ? : nbytes;
}
#endif

static int memory_stat_show(struct seq_file *m, void *v);
@@ -6156,6 +6192,16 @@ static struct cftype mem_cgroup_legacy_files[] = {
		.seq_show = mem_cgroup_dpool_read,
		.flags = CFTYPE_NO_PREFIX | CFTYPE_WORLD_WRITABLE | CFTYPE_NOT_ON_ROOT,
	},
	{
		.name = "dhugetlb.1G.reserved_pages",
		.write = mem_cgroup_dpool_1G_write,
		.flags = CFTYPE_NO_PREFIX | CFTYPE_WORLD_WRITABLE | CFTYPE_NOT_ON_ROOT,
	},
	{
		.name = "dhugetlb.2M.reserved_pages",
		.write = mem_cgroup_dpool_2M_write,
		.flags = CFTYPE_NO_PREFIX | CFTYPE_WORLD_WRITABLE | CFTYPE_NOT_ON_ROOT,
	},
#endif
	{ },	/* terminate */
};