[PATCH OLK-6.6 0/5] memcg: Add new interface for async reclaim

1. memory.wmark_ratio 2. memory.wmark_scale_factor 3. memory.wmark_high 4. memory.wmark_low Liu Shixin (5): memcg: extract function async_high_read/async_low_read memcg: replace memory.high with memory.limit_in_bytes memcg: add memory.wmark_ratio memcg: add memory.wmark_scale_factor memcg: add memory.wmark_high and memory.wmark_low include/linux/memcontrol.h | 5 +- mm/memcontrol.c | 143 +++++++++++++++++++++++++++++++++++-- 2 files changed, 141 insertions(+), 7 deletions(-) -- 2.34.1

Extract function async_high_read/async_low_read. Link: https://www.alibabacloud.com/help/zh/alinux/user-guide/memcg-backend-asynchr... Signed-off-by: Liu Shixin <liushixin2@huawei.com> --- mm/memcontrol.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 00b04c0ce172..c178ffbdb202 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2493,6 +2493,17 @@ static unsigned long reclaim_high(struct mem_cgroup *memcg, } #ifdef CONFIG_MEMCG_V1_RECLAIM +static unsigned long async_high_read(struct mem_cgroup *memcg) +{ + return READ_ONCE(memcg->memory.high) * READ_ONCE(memcg->high_async_ratio) / HIGH_ASYNC_RATIO_BASE; +} + +static unsigned long async_low_read(struct mem_cgroup *memcg) +{ + return async_high_read(memcg) - + READ_ONCE(memcg->memory.high) * HIGH_ASYNC_RATIO_GAP / HIGH_ASYNC_RATIO_BASE; +} + static bool is_high_async_reclaim(struct mem_cgroup *memcg) { int ratio = READ_ONCE(memcg->high_async_ratio); @@ -2501,17 +2512,14 @@ static bool is_high_async_reclaim(struct mem_cgroup *memcg) if (ratio == HIGH_ASYNC_RATIO_BASE || memcg_high == PAGE_COUNTER_MAX) return false; - return page_counter_read(&memcg->memory) > - memcg_high * ratio / HIGH_ASYNC_RATIO_BASE; + return page_counter_read(&memcg->memory) > async_high_read(memcg); } static void async_reclaim_high(struct mem_cgroup *memcg) { unsigned long nr_pages, pflags; - unsigned long memcg_high = READ_ONCE(memcg->memory.high); unsigned long memcg_usage = page_counter_read(&memcg->memory); - int ratio = READ_ONCE(memcg->high_async_ratio) - HIGH_ASYNC_RATIO_GAP; - unsigned long safe_pages = memcg_high * ratio / HIGH_ASYNC_RATIO_BASE; + unsigned long safe_pages = async_low_read(memcg); if (!is_high_async_reclaim(memcg)) { WRITE_ONCE(memcg->high_async_reclaim, false); -- 2.34.1

Use limit_in_bytes to calculate wmark_high and wmark_low as described in document. Link: https://www.alibabacloud.com/help/zh/alinux/user-guide/memcg-backend-asynchr... Signed-off-by: Liu Shixin <liushixin2@huawei.com> --- mm/memcontrol.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index c178ffbdb202..44caef983b6f 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2495,19 +2495,19 @@ static unsigned long reclaim_high(struct mem_cgroup *memcg, #ifdef CONFIG_MEMCG_V1_RECLAIM static unsigned long async_high_read(struct mem_cgroup *memcg) { - return READ_ONCE(memcg->memory.high) * READ_ONCE(memcg->high_async_ratio) / HIGH_ASYNC_RATIO_BASE; + return READ_ONCE(memcg->memory.max) * READ_ONCE(memcg->high_async_ratio) / HIGH_ASYNC_RATIO_BASE; } static unsigned long async_low_read(struct mem_cgroup *memcg) { return async_high_read(memcg) - - READ_ONCE(memcg->memory.high) * HIGH_ASYNC_RATIO_GAP / HIGH_ASYNC_RATIO_BASE; + READ_ONCE(memcg->memory.max) * HIGH_ASYNC_RATIO_GAP / HIGH_ASYNC_RATIO_BASE; } static bool is_high_async_reclaim(struct mem_cgroup *memcg) { int ratio = READ_ONCE(memcg->high_async_ratio); - unsigned long memcg_high = READ_ONCE(memcg->memory.high); + unsigned long memcg_high = READ_ONCE(memcg->memory.max); if (ratio == HIGH_ASYNC_RATIO_BASE || memcg_high == PAGE_COUNTER_MAX) return false; -- 2.34.1

These two interface have the same meaning and almost the same value except the initial value. By default, high_async_ratio return 100, wmark_ratio return 0, but the meaning is the same, all means the async-reclaim is disabeld. Signed-off-by: Liu Shixin <liushixin2@huawei.com> --- mm/memcontrol.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 44caef983b6f..ffc75baeacd4 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -6056,6 +6056,44 @@ static ssize_t memcg_high_async_ratio_write(struct kernfs_open_file *of, return nbytes; } + +static int memcg_wmark_ratio_show(struct seq_file *m, void *v) +{ + int ratio = READ_ONCE(mem_cgroup_from_seq(m)->high_async_ratio); + + if (ratio == HIGH_ASYNC_RATIO_BASE) + ratio = 0; + + seq_printf(m, "%d\n", ratio); + + return 0; +} + +static ssize_t memcg_wmark_ratio_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, high_async_ratio; + + buf = strstrip(buf); + if (!buf) + return -EINVAL; + + ret = kstrtoint(buf, 0, &high_async_ratio); + if (ret) + return ret; + + if (high_async_ratio > HIGH_ASYNC_RATIO_BASE || + high_async_ratio < 0) + return -EINVAL; + + if (high_async_ratio == 0) + high_async_ratio = HIGH_ASYNC_RATIO_BASE; + + WRITE_ONCE(memcg->high_async_ratio, high_async_ratio); + + return nbytes; +} #endif #ifdef CONFIG_CGROUP_V1_WRITEBACK @@ -6314,6 +6352,12 @@ static struct cftype mem_cgroup_legacy_files[] = { .seq_show = memcg_high_async_ratio_show, .write = memcg_high_async_ratio_write, }, + { + .name = "wmark_ratio", + .flags = CFTYPE_NOT_ON_ROOT, + .seq_show = memcg_wmark_ratio_show, + .write = memcg_wmark_ratio_write, + }, { .name = "reclaim", .write = memory_reclaim, -- 2.34.1

Replace HIGH_ASYNC_RATIO_GAP with variable wmark_scale_factor. Add interface to write/read wmark_scale_factor. Signed-off-by: Liu Shixin <liushixin2@huawei.com> --- include/linux/memcontrol.h | 5 +++- mm/memcontrol.c | 55 +++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index f6a1494ad9ac..402600729147 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -420,8 +420,11 @@ struct mem_cgroup { #ifdef CONFIG_DYNAMIC_POOL struct dynamic_pool *dpool; #endif - +#ifdef CONFIG_MEMCG_V1_RECLAIM + KABI_USE(1, int wmark_scale_factor) +#else KABI_RESERVE(1) +#endif KABI_RESERVE(2) KABI_RESERVE(3) KABI_RESERVE(4) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index ffc75baeacd4..d7a6ffc748f3 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2501,7 +2501,7 @@ static unsigned long async_high_read(struct mem_cgroup *memcg) static unsigned long async_low_read(struct mem_cgroup *memcg) { return async_high_read(memcg) - - READ_ONCE(memcg->memory.max) * HIGH_ASYNC_RATIO_GAP / HIGH_ASYNC_RATIO_BASE; + READ_ONCE(memcg->memory.max) * READ_ONCE(memcg->wmark_scale_factor) / 10000; } static bool is_high_async_reclaim(struct mem_cgroup *memcg) @@ -6094,6 +6094,51 @@ static ssize_t memcg_wmark_ratio_write(struct kernfs_open_file *of, return nbytes; } + +static inline void memcg_wmark_scale_factor_init(struct mem_cgroup *memcg, + struct mem_cgroup *parent) +{ + if (!parent) + memcg->wmark_scale_factor = 50; + else + memcg->wmark_scale_factor = parent->wmark_scale_factor; +} + +static int memcg_wmark_scale_factor_show(struct seq_file *m, void *v) +{ + seq_printf(m, "%d\n", + READ_ONCE(mem_cgroup_from_seq(m)->wmark_scale_factor)); + return 0; +} + +static ssize_t memcg_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 = kstrtoint(buf, 0, &wmark_scale_factor); + if (ret) + return ret; + + if (wmark_scale_factor > 1000 || + wmark_scale_factor < 1) + return -EINVAL; + + WRITE_ONCE(memcg->wmark_scale_factor, wmark_scale_factor); + + return nbytes; + +} +#else +static inline void memcg_wmark_scale_factor_init(struct mem_cgroup *memcg, + struct mem_cgroup *parent) +{ +} #endif #ifdef CONFIG_CGROUP_V1_WRITEBACK @@ -6358,6 +6403,12 @@ static struct cftype mem_cgroup_legacy_files[] = { .seq_show = memcg_wmark_ratio_show, .write = memcg_wmark_ratio_write, }, + { + .name = "wmark_scale_factor", + .flags = CFTYPE_NOT_ON_ROOT, + .seq_show = memcg_wmark_scale_factor_show, + .write = memcg_wmark_scale_factor_write, + }, { .name = "reclaim", .write = memory_reclaim, @@ -6679,6 +6730,7 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) page_counter_init(&memcg->kmem, &parent->kmem); page_counter_init(&memcg->tcpmem, &parent->tcpmem); memcg_swap_device_init(memcg, parent); + memcg_wmark_scale_factor_init(memcg, parent); } else { init_memcg_events(); page_counter_init(&memcg->memory, NULL); @@ -6686,6 +6738,7 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) page_counter_init(&memcg->kmem, NULL); page_counter_init(&memcg->tcpmem, NULL); memcg_swap_device_init(memcg, NULL); + memcg_wmark_scale_factor_init(memcg, NULL); root_mem_cgroup = memcg; return &memcg->css; -- 2.34.1

Add memory.wmark_high and memory.wmark_low. Signed-off-by: Liu Shixin <liushixin2@huawei.com> --- mm/memcontrol.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index d7a6ffc748f3..d740d3736905 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -6134,6 +6134,22 @@ static ssize_t memcg_wmark_scale_factor_write(struct kernfs_open_file *of, return nbytes; } + +static u64 memcg_wmark_high_read(struct cgroup_subsys_state *css, + struct cftype *cft) +{ + struct mem_cgroup *memcg = mem_cgroup_from_css(css); + + return (u64)async_high_read(memcg) * PAGE_SIZE; +} + +static u64 memcg_wmark_low_read(struct cgroup_subsys_state *css, + struct cftype *cft) +{ + struct mem_cgroup *memcg = mem_cgroup_from_css(css); + + return (u64)async_low_read(memcg) * PAGE_SIZE; +} #else static inline void memcg_wmark_scale_factor_init(struct mem_cgroup *memcg, struct mem_cgroup *parent) @@ -6409,6 +6425,16 @@ static struct cftype mem_cgroup_legacy_files[] = { .seq_show = memcg_wmark_scale_factor_show, .write = memcg_wmark_scale_factor_write, }, + { + .name = "wmark_high", + .flags = CFTYPE_NOT_ON_ROOT, + .read_u64 = memcg_wmark_high_read, + }, + { + .name = "wmark_low", + .flags = CFTYPE_NOT_ON_ROOT, + .read_u64 = memcg_wmark_low_read, + }, { .name = "reclaim", .write = memory_reclaim, -- 2.34.1

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/16491 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/HZC... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/16491 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/HZC...
participants (2)
-
Liu Shixin
-
patchwork bot