cgroup/pids: Make event counters hierarchical
The pids.events file should honor the hierarchy, so make the events propagate from their origin up to the root on the unified hierarchy. The legacy behavior remains non-hierarchical. Signed-off-by: Michal Koutný <mkoutny@suse.com> Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
73e75e6fc3
commit
385a635cac
@ -240,8 +240,11 @@ cgroup v2 currently supports the following mount options.
|
||||
v2 is remounted later on).
|
||||
|
||||
pids_localevents
|
||||
Represent fork failures inside cgroup's pids.events:max (v1 behavior),
|
||||
not its limit being hit (v2 behavior).
|
||||
The option restores v1-like behavior of pids.events:max, that is only
|
||||
local (inside cgroup proper) fork failures are counted. Without this
|
||||
option pids.events.max represents any pids.max enforcemnt across
|
||||
cgroup's subtree.
|
||||
|
||||
|
||||
|
||||
Organizing Processes and Threads
|
||||
@ -2214,7 +2217,7 @@ PID Interface Files
|
||||
modified event. The following entries are defined.
|
||||
|
||||
max
|
||||
The number of times the cgroup's number of processes hit the
|
||||
The number of times the cgroup's total number of processes hit the pids.max
|
||||
limit (see also pids_localevents).
|
||||
|
||||
Organisational operations are not blocked by cgroup policies, so it is
|
||||
|
@ -238,6 +238,34 @@ static void pids_cancel_attach(struct cgroup_taskset *tset)
|
||||
}
|
||||
}
|
||||
|
||||
static void pids_event(struct pids_cgroup *pids_forking,
|
||||
struct pids_cgroup *pids_over_limit)
|
||||
{
|
||||
struct pids_cgroup *p = pids_forking;
|
||||
bool limit = false;
|
||||
|
||||
for (; parent_pids(p); p = parent_pids(p)) {
|
||||
/* Only log the first time limit is hit. */
|
||||
if (atomic64_inc_return(&p->events[PIDCG_FORKFAIL]) == 1) {
|
||||
pr_info("cgroup: fork rejected by pids controller in ");
|
||||
pr_cont_cgroup_path(p->css.cgroup);
|
||||
pr_cont("\n");
|
||||
}
|
||||
cgroup_file_notify(&p->events_file);
|
||||
|
||||
if (!cgroup_subsys_on_dfl(pids_cgrp_subsys) ||
|
||||
cgrp_dfl_root.flags & CGRP_ROOT_PIDS_LOCAL_EVENTS)
|
||||
break;
|
||||
|
||||
if (p == pids_over_limit)
|
||||
limit = true;
|
||||
if (limit)
|
||||
atomic64_inc(&p->events[PIDCG_MAX]);
|
||||
|
||||
cgroup_file_notify(&p->events_file);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* task_css_check(true) in pids_can_fork() and pids_cancel_fork() relies
|
||||
* on cgroup_threadgroup_change_begin() held by the copy_process().
|
||||
@ -254,23 +282,9 @@ static int pids_can_fork(struct task_struct *task, struct css_set *cset)
|
||||
css = task_css_check(current, pids_cgrp_id, true);
|
||||
pids = css_pids(css);
|
||||
err = pids_try_charge(pids, 1, &pids_over_limit);
|
||||
if (err) {
|
||||
/* compatibility on v1 where events were notified in leaves. */
|
||||
if (!cgroup_subsys_on_dfl(pids_cgrp_subsys))
|
||||
pids_over_limit = pids;
|
||||
if (err)
|
||||
pids_event(pids, pids_over_limit);
|
||||
|
||||
/* Only log the first time limit is hit. */
|
||||
if (atomic64_inc_return(&pids->events[PIDCG_FORKFAIL]) == 1) {
|
||||
pr_info("cgroup: fork rejected by pids controller in ");
|
||||
pr_cont_cgroup_path(pids->css.cgroup);
|
||||
pr_cont("\n");
|
||||
}
|
||||
atomic64_inc(&pids_over_limit->events[PIDCG_MAX]);
|
||||
|
||||
cgroup_file_notify(&pids->events_file);
|
||||
if (pids_over_limit != pids)
|
||||
cgroup_file_notify(&pids_over_limit->events_file);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user