提交 33ef4784 编写于 作者: Y Yang Shi 提交者: Caspar Zhang

alios: mm: memcontrol: make distance between wmark_low and wmark_high configurable

Introduce a new interface, wmark_scale_factor, which defines the
distance between wmark_high and wmark_low.  The unit is in fractions of
10,000. The default value of 50 means the distance between wmark_high
and wmark_low is 0.5% of the max limit of the cgroup.  The maximum value
is 1000, or 10% of the max limit.

The distance between wmark_low and wmark_high have impact on how hard
memcg kswapd would reclaim.
Reviewed-by: NGavin Shan <shan.gavin@linux.alibaba.com>
Reviewed-by: NXunlei Pang <xlpang@linux.alibaba.com>
Signed-off-by: NYang Shi <yang.shi@linux.alibaba.com>
上级 e10c247b
...@@ -1116,6 +1116,15 @@ PAGE_SIZE multiple when read back. ...@@ -1116,6 +1116,15 @@ PAGE_SIZE multiple when read back.
Memory usage low water mark, which means the available memory is ok. Memory usage low water mark, which means the available memory is ok.
For details, please refer to the above wmark_ratio section. For details, please refer to the above wmark_ratio section.
memory.wmark_scale_factor
A read-write single value file which exists on non-root cgroups.
The default is 50.
The gap between wmark_low and wmark_high. The unit is in fractions
of 10,000. The default value of 50 means the distance between wmark_high
and wmark_low is 0.5% of the max limit of the cgroup. The maximum value
is 1000, or 10% of max limit.
memory.oom.group memory.oom.group
A read-write single value file which exists on non-root A read-write single value file which exists on non-root
cgroups. The default value is "0". cgroups. The default value is "0".
......
...@@ -93,6 +93,10 @@ Brief summary of control files. ...@@ -93,6 +93,10 @@ Brief summary of control files.
read-only) read-only)
memory.wmark_high # high limit (memory usge high water mark, memory.wmark_high # high limit (memory usge high water mark,
read-only) read-only)
memory.wmark_scale_factor # the gap between wmark_low and wmark_high,
percentage of max limit, default is 50 or
0.5% of max limit. The max value is 1000 or
10% of max limit.
1. History 1. History
......
...@@ -292,6 +292,7 @@ struct mem_cgroup { ...@@ -292,6 +292,7 @@ struct mem_cgroup {
unsigned int wmark_ratio; unsigned int wmark_ratio;
struct work_struct wmark_work; struct work_struct wmark_work;
unsigned int wmark_scale_factor;
#ifdef CONFIG_MEMCG_KMEM #ifdef CONFIG_MEMCG_KMEM
/* Index in the kmem_cache->memcg_params.memcg_caches array */ /* Index in the kmem_cache->memcg_params.memcg_caches array */
......
...@@ -2948,10 +2948,19 @@ static void setup_memcg_wmark(struct mem_cgroup *memcg) ...@@ -2948,10 +2948,19 @@ static void setup_memcg_wmark(struct mem_cgroup *memcg)
unsigned long max = memcg->high > memcg->memory.max ? unsigned long max = memcg->high > memcg->memory.max ?
memcg->memory.max : memcg->high; memcg->memory.max : memcg->high;
unsigned int wmark_ratio = memcg->wmark_ratio; unsigned int wmark_ratio = memcg->wmark_ratio;
unsigned int wmark_scale_factor = memcg->wmark_scale_factor;
unsigned long gap;
if (wmark_ratio) { if (wmark_ratio) {
high_wmark = (max * wmark_ratio) / 100; high_wmark = (max * wmark_ratio) / 100;
low_wmark = high_wmark - (high_wmark >> 8);
/*
* Set the memcg watermark distance according to the
* scale factor in proportion to max limit.
*/
gap = mult_frac(max, wmark_scale_factor, 10000);
low_wmark = high_wmark - gap;
page_counter_set_wmark_low(&memcg->memory, low_wmark); page_counter_set_wmark_low(&memcg->memory, low_wmark);
page_counter_set_wmark_high(&memcg->memory, high_wmark); page_counter_set_wmark_high(&memcg->memory, high_wmark);
...@@ -3791,6 +3800,42 @@ static ssize_t memory_wmark_ratio_write(struct kernfs_open_file *of, ...@@ -3791,6 +3800,42 @@ static ssize_t memory_wmark_ratio_write(struct kernfs_open_file *of,
return nbytes; return nbytes;
} }
static int memory_wmark_scale_factor_show(struct seq_file *m, void *v)
{
struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
unsigned int wmark_scale_factor;
wmark_scale_factor = READ_ONCE(memcg->wmark_scale_factor);
seq_printf(m, "%d\n", wmark_scale_factor);
return 0;
}
static ssize_t memory_wmark_scale_factor_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));
int ret, wmark_scale_factor;
buf = strstrip(buf);
if (!buf)
return -EINVAL;
ret = kstrtouint(buf, 0, &wmark_scale_factor);
if (ret)
return ret;
if (wmark_scale_factor > 1000 || wmark_scale_factor < 1)
return -EINVAL;
xchg(&memcg->wmark_scale_factor, wmark_scale_factor);
setup_memcg_wmark(memcg);
return nbytes;
}
static void __mem_cgroup_threshold(struct mem_cgroup *memcg, bool swap) static void __mem_cgroup_threshold(struct mem_cgroup *memcg, bool swap)
{ {
struct mem_cgroup_threshold_ary *t; struct mem_cgroup_threshold_ary *t;
...@@ -4516,6 +4561,12 @@ static struct cftype mem_cgroup_legacy_files[] = { ...@@ -4516,6 +4561,12 @@ static struct cftype mem_cgroup_legacy_files[] = {
.private = MEMFILE_PRIVATE(_MEM, WMARK_LOW_LIMIT), .private = MEMFILE_PRIVATE(_MEM, WMARK_LOW_LIMIT),
.read_u64 = mem_cgroup_read_u64, .read_u64 = mem_cgroup_read_u64,
}, },
{
.name = "wmark_scale_factor",
.flags = CFTYPE_NOT_ON_ROOT,
.seq_show = memory_wmark_scale_factor_show,
.write = memory_wmark_scale_factor_write,
},
{ {
.name = "force_empty", .name = "force_empty",
.write = mem_cgroup_force_empty_write, .write = mem_cgroup_force_empty_write,
...@@ -4817,6 +4868,9 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) ...@@ -4817,6 +4868,9 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
memcg->swappiness = mem_cgroup_swappiness(parent); memcg->swappiness = mem_cgroup_swappiness(parent);
memcg->oom_kill_disable = parent->oom_kill_disable; memcg->oom_kill_disable = parent->oom_kill_disable;
memcg->wmark_ratio = parent->wmark_ratio; memcg->wmark_ratio = parent->wmark_ratio;
/* Default gap is 0.5% max limit */
memcg->wmark_scale_factor = parent->wmark_scale_factor ?
: 50;
} }
if (parent && parent->use_hierarchy) { if (parent && parent->use_hierarchy) {
memcg->use_hierarchy = true; memcg->use_hierarchy = true;
...@@ -6066,6 +6120,12 @@ static struct cftype memory_files[] = { ...@@ -6066,6 +6120,12 @@ static struct cftype memory_files[] = {
.flags = CFTYPE_NOT_ON_ROOT, .flags = CFTYPE_NOT_ON_ROOT,
.seq_show = memory_wmark_low_show, .seq_show = memory_wmark_low_show,
}, },
{
.name = "wmark_scale_factor",
.flags = CFTYPE_NOT_ON_ROOT,
.seq_show = memory_wmark_scale_factor_show,
.write = memory_wmark_scale_factor_write,
},
{ {
.name = "events", .name = "events",
.flags = CFTYPE_NOT_ON_ROOT, .flags = CFTYPE_NOT_ON_ROOT,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册