From mboxrd@z Thu Jan 1 00:00:00 1970 From: Topi Miettinen Subject: [PATCH 1/2] cgroup_pids: track highwater mark of pids Date: Sun, 17 Jul 2016 23:03:38 +0300 Message-ID: <1468785820-3960-3-git-send-email-toiwoton@gmail.com> References: <1468785820-3960-1-git-send-email-toiwoton@gmail.com> Return-path: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=eS0T5mdFzyk1zXbye+t8oSkGVV14yMYqRORcAfZgtBU=; b=rrhxADslDxyK7BEf+QBa5nFNrRwTbcQ1QMV8HJQuKdCoaJ8BiAuXHST2xwg3WnZkuk voGn7fbZIVk5WWhQl54eKqsBvangk3KT5k6VjLUi5mM7i/5LAhzolSa1nJFq2+bli8L0 qh7Cy0PlHIeBdqIz9HjYmMnNKCpPy9Y5IwJfKAB7X8JZCGiKFAMjJHlQ72S1/GAdRLil H7msvQ3zqCRhJ/IFpS6WGI14l4F5lJ8d5RR966wm1SsgkKJUJXbXGWUeTMdTpvoaDo7H kSQjfsdFbJrFnv2N8dtTjH/+Q0M5vB32Ubm+nhvVNvNDVPF6CO6hi3OaiHzcInh83JCh JGLg== In-Reply-To: <1468785820-3960-1-git-send-email-toiwoton@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: linux-kernel@vger.kernel.org Cc: Topi Miettinen , Tejun Heo , Li Zefan , Johannes Weiner , "open list:CONTROL GROUP CGROUP" Track maximum number of processes in cgroup, to be able to configure cgroup pids limits. The information is available in cgroup FS as file pids.highwater_mark. Example case demonstrating how to use the figure for systemd configuration: root@debian:~# cat /sys/fs/cgroup/system.slice/systemd-timesyncd.service/pids.highwater_mark 2 root@debian:~# cat /etc/systemd/system/systemd-timesyncd.service.d/local.conf [Service] TasksMax=2 root@debian:~# systemctl status systemd-timesyncd.service | grep Tasks Tasks: 2 (limit: 2) Signed-off-by: Topi Miettinen --- kernel/cgroup_pids.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/kernel/cgroup_pids.c b/kernel/cgroup_pids.c index 303097b..da5a696 100644 --- a/kernel/cgroup_pids.c +++ b/kernel/cgroup_pids.c @@ -48,6 +48,7 @@ struct pids_cgroup { * %PIDS_MAX = (%PID_MAX_LIMIT + 1). */ atomic64_t counter; + atomic64_t highwater_mark; int64_t limit; }; @@ -72,6 +73,7 @@ pids_css_alloc(struct cgroup_subsys_state *parent) pids->limit = PIDS_MAX; atomic64_set(&pids->counter, 0); + atomic64_set(&pids->highwater_mark, 0); return &pids->css; } @@ -80,6 +82,25 @@ static void pids_css_free(struct cgroup_subsys_state *css) kfree(css_pids(css)); } +static void pids_update_highwater_mark(struct pids_cgroup *p) +{ + while (1) { + int64_t old_mark, new_mark, cur_mark; + + old_mark = atomic64_read(&p->highwater_mark); + new_mark = atomic64_read(&p->counter); + if (old_mark >= new_mark) + return; + cur_mark = atomic64_cmpxchg(&p->highwater_mark, old_mark, + new_mark); + + /* It's OK if the counter was decreased meanwhile */ + if (cur_mark == old_mark && + atomic64_read(&p->counter) <= new_mark) + return; + } +} + /** * pids_cancel - uncharge the local pid count * @pids: the pid cgroup state @@ -106,8 +127,10 @@ static void pids_uncharge(struct pids_cgroup *pids, int num) { struct pids_cgroup *p; - for (p = pids; parent_pids(p); p = parent_pids(p)) + for (p = pids; parent_pids(p); p = parent_pids(p)) { pids_cancel(p, num); + pids_update_highwater_mark(p); + } } /** @@ -123,8 +146,10 @@ static void pids_charge(struct pids_cgroup *pids, int num) { struct pids_cgroup *p; - for (p = pids; parent_pids(p); p = parent_pids(p)) + for (p = pids; parent_pids(p); p = parent_pids(p)) { atomic64_add(num, &p->counter); + pids_update_highwater_mark(p); + } } /** @@ -152,6 +177,7 @@ static int pids_try_charge(struct pids_cgroup *pids, int num) goto revert; } + pids_update_highwater_mark(p); return 0; revert: @@ -236,6 +262,13 @@ static void pids_free(struct task_struct *task) pids_uncharge(pids, 1); } +static void pids_fork(struct task_struct *task) +{ + struct pids_cgroup *pids = css_pids(task_css(task, pids_cgrp_id)); + + pids_update_highwater_mark(pids); +} + static ssize_t pids_max_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { @@ -288,6 +321,14 @@ static s64 pids_current_read(struct cgroup_subsys_state *css, return atomic64_read(&pids->counter); } +static s64 pids_highwater_mark_read(struct cgroup_subsys_state *css, + struct cftype *cft) +{ + struct pids_cgroup *pids = css_pids(css); + + return atomic64_read(&pids->highwater_mark); +} + static struct cftype pids_files[] = { { .name = "max", @@ -300,6 +341,11 @@ static struct cftype pids_files[] = { .read_s64 = pids_current_read, .flags = CFTYPE_NOT_ON_ROOT, }, + { + .name = "highwater_mark", + .read_s64 = pids_highwater_mark_read, + .flags = CFTYPE_NOT_ON_ROOT, + }, { } /* terminate */ }; @@ -313,4 +359,5 @@ struct cgroup_subsys pids_cgrp_subsys = { .free = pids_free, .legacy_cftypes = pids_files, .dfl_cftypes = pids_files, + .fork = pids_fork, }; -- 2.8.1