From 5b71d2f57720db15dc8b8f8373a20c61c053ef35 Mon Sep 17 00:00:00 2001 From: Yi Tao Date: Fri, 8 Jan 2021 19:21:10 +0800 Subject: [PATCH 2537/2944] alinux: cgroup: introduce cgroup_limit to #31531504 Until now there is no way to control cache size used by cgroup kernfs node and some subsystems. Thus we introduce an interface called cgroup_limit under procfs. Users can get cgroup_limit by reading /proc/sys/kernel/cgroup_limit and set cgroup_limit by writing it. Default cgrou_limit is 0. If cgroup_limit decreased and become less than current cache size, it may take a while to release extra cache. For example: [root@esc ~]#echo 2000 > /proc/sys/kernel/cgroup_limit [root@esc ~]#cat /proc/sys/kernel/cgroup_limit 2000 Signed-off-by: Yi Tao Suggested-by: Shanpei Chen Acked-by: Xunlei Pang Acked-by: Michael Wang --- include/linux/cgroup.h | 12 ++++++++++++ kernel/cgroup/cgroup.c | 24 ++++++++++++++++++++++++ kernel/sysctl.c | 10 ++++++++++ 3 files changed, 46 insertions(+) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index c513278..58fdbac 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -155,6 +155,18 @@ void css_task_iter_start(struct cgroup_subsys_state *css, unsigned int flags, struct task_struct *css_task_iter_next(struct css_task_iter *it); void css_task_iter_end(struct css_task_iter *it); +#ifdef CONFIG_CGROUP_CACHE +extern unsigned int cgroup_limit; +int cgroup_limit_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos); + +extern struct cache_header cpuacct_cache_header; +extern struct cache_header mem_cgroup_cache_header; +extern struct cache_header fair_sched_cache_header; +extern struct cache_header rt_sched_cache_header; +#endif /* CONFIG_CGROUP_CACHE */ + /** * css_for_each_child - iterate through children of a css * @pos: the css * to use as the loop cursor diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 3c3ef09..121fc50 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -6549,5 +6549,29 @@ bool cache_not_full(struct cache_header *ch) return ch->ready_node < ch->limit; } EXPORT_SYMBOL(cache_not_full); +unsigned int cgroup_limit = DEFAULT_CACHE_SIZE; +int cgroup_limit_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + static DEFINE_MUTEX(cache_mutex); + struct cgroup_root *root; + int ret; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (!ret && write) { + mutex_lock(&cache_mutex); + change_cache_limit(&cpuacct_cache_header, cgroup_limit); + change_cache_limit(&mem_cgroup_cache_header, cgroup_limit); + change_cache_limit(&fair_sched_cache_header, cgroup_limit); +#ifdef CONFIG_RT_GROUP_SCHED + change_cache_limit(&rt_sched_cache_header, cgroup_limit); +#endif + for_each_root(root) + change_cache_limit(&root->orphan_header, cgroup_limit); + mutex_unlock(&cache_mutex); + } + return ret; +} #endif /* CONFIG_CGROUP_CACHE */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 64d07d1..0f1ecba 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -67,6 +67,7 @@ #include #include #include +#include #include "../lib/kstrtox.h" @@ -1330,6 +1331,15 @@ static int sysrq_sysctl_handler(struct ctl_table *table, int write, .extra1 = &two, }, #endif +#ifdef CONFIG_CGROUP_CACHE + { + .procname = "cgroup_limit", + .data = &cgroup_limit, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = cgroup_limit_handler, + }, +#endif { } }; -- 1.8.3.1