Skip to content

Commit 385a635

Browse files
Werkovhtejun
authored andcommitted
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ý <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent 73e75e6 commit 385a635

File tree

2 files changed

+36
-19
lines changed

2 files changed

+36
-19
lines changed

Documentation/admin-guide/cgroup-v2.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,11 @@ cgroup v2 currently supports the following mount options.
240240
v2 is remounted later on).
241241

242242
pids_localevents
243-
Represent fork failures inside cgroup's pids.events:max (v1 behavior),
244-
not its limit being hit (v2 behavior).
243+
The option restores v1-like behavior of pids.events:max, that is only
244+
local (inside cgroup proper) fork failures are counted. Without this
245+
option pids.events.max represents any pids.max enforcemnt across
246+
cgroup's subtree.
247+
245248

246249

247250
Organizing Processes and Threads
@@ -2214,7 +2217,7 @@ PID Interface Files
22142217
modified event. The following entries are defined.
22152218

22162219
max
2217-
The number of times the cgroup's number of processes hit the
2220+
The number of times the cgroup's total number of processes hit the pids.max
22182221
limit (see also pids_localevents).
22192222

22202223
Organisational operations are not blocked by cgroup policies, so it is

kernel/cgroup/pids.c

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,34 @@ static void pids_cancel_attach(struct cgroup_taskset *tset)
238238
}
239239
}
240240

241+
static void pids_event(struct pids_cgroup *pids_forking,
242+
struct pids_cgroup *pids_over_limit)
243+
{
244+
struct pids_cgroup *p = pids_forking;
245+
bool limit = false;
246+
247+
for (; parent_pids(p); p = parent_pids(p)) {
248+
/* Only log the first time limit is hit. */
249+
if (atomic64_inc_return(&p->events[PIDCG_FORKFAIL]) == 1) {
250+
pr_info("cgroup: fork rejected by pids controller in ");
251+
pr_cont_cgroup_path(p->css.cgroup);
252+
pr_cont("\n");
253+
}
254+
cgroup_file_notify(&p->events_file);
255+
256+
if (!cgroup_subsys_on_dfl(pids_cgrp_subsys) ||
257+
cgrp_dfl_root.flags & CGRP_ROOT_PIDS_LOCAL_EVENTS)
258+
break;
259+
260+
if (p == pids_over_limit)
261+
limit = true;
262+
if (limit)
263+
atomic64_inc(&p->events[PIDCG_MAX]);
264+
265+
cgroup_file_notify(&p->events_file);
266+
}
267+
}
268+
241269
/*
242270
* task_css_check(true) in pids_can_fork() and pids_cancel_fork() relies
243271
* 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)
254282
css = task_css_check(current, pids_cgrp_id, true);
255283
pids = css_pids(css);
256284
err = pids_try_charge(pids, 1, &pids_over_limit);
257-
if (err) {
258-
/* compatibility on v1 where events were notified in leaves. */
259-
if (!cgroup_subsys_on_dfl(pids_cgrp_subsys))
260-
pids_over_limit = pids;
261-
262-
/* Only log the first time limit is hit. */
263-
if (atomic64_inc_return(&pids->events[PIDCG_FORKFAIL]) == 1) {
264-
pr_info("cgroup: fork rejected by pids controller in ");
265-
pr_cont_cgroup_path(pids->css.cgroup);
266-
pr_cont("\n");
267-
}
268-
atomic64_inc(&pids_over_limit->events[PIDCG_MAX]);
285+
if (err)
286+
pids_event(pids, pids_over_limit);
269287

270-
cgroup_file_notify(&pids->events_file);
271-
if (pids_over_limit != pids)
272-
cgroup_file_notify(&pids_over_limit->events_file);
273-
}
274288
return err;
275289
}
276290

0 commit comments

Comments
 (0)