Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

cgroup/pids: Avoid spurious event notification

Currently when a process in a group forks and fails due to it's
parent's max restriction, all the cgroups from 'pids_forking' to root
will generate event notifications but only the cgroups from
'pids_over_limit' to root will increase the counter of PIDCG_MAX.

Consider this scenario: there are 4 groups A, B, C,and D, the
relationships are as follows, and user is watching on C.pids.events.

root->A->B->C->D

When a process in D forks and fails due to B.max restriction, the
user will get a spurious event notification because when he wakes up
and reads C.pids.events, he will find that the content has not changed.

To address this issue, only the cgroups from 'pids_over_limit' to root
will have their PIDCG_MAX counters increased and event notifications
generated.

Fixes: 385a635cacfe ("cgroup/pids: Make event counters hierarchical")
Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
Signed-off-by: Tejun Heo <tj@kernel.org>

authored by

Xiu Jianfeng and committed by
Tejun Heo
d72a00a8 d6326047

+7 -11
+7 -11
kernel/cgroup/pids.c
··· 244 244 struct pids_cgroup *pids_over_limit) 245 245 { 246 246 struct pids_cgroup *p = pids_forking; 247 - bool limit = false; 248 247 249 248 /* Only log the first time limit is hit. */ 250 249 if (atomic64_inc_return(&p->events_local[PIDCG_FORKFAIL]) == 1) { ··· 251 252 pr_cont_cgroup_path(p->css.cgroup); 252 253 pr_cont("\n"); 253 254 } 254 - cgroup_file_notify(&p->events_local_file); 255 255 if (!cgroup_subsys_on_dfl(pids_cgrp_subsys) || 256 - cgrp_dfl_root.flags & CGRP_ROOT_PIDS_LOCAL_EVENTS) 256 + cgrp_dfl_root.flags & CGRP_ROOT_PIDS_LOCAL_EVENTS) { 257 + cgroup_file_notify(&p->events_local_file); 257 258 return; 259 + } 258 260 259 - for (; parent_pids(p); p = parent_pids(p)) { 260 - if (p == pids_over_limit) { 261 - limit = true; 262 - atomic64_inc(&p->events_local[PIDCG_MAX]); 263 - cgroup_file_notify(&p->events_local_file); 264 - } 265 - if (limit) 266 - atomic64_inc(&p->events[PIDCG_MAX]); 261 + atomic64_inc(&pids_over_limit->events_local[PIDCG_MAX]); 262 + cgroup_file_notify(&pids_over_limit->events_local_file); 267 263 264 + for (p = pids_over_limit; parent_pids(p); p = parent_pids(p)) { 265 + atomic64_inc(&p->events[PIDCG_MAX]); 268 266 cgroup_file_notify(&p->events_file); 269 267 } 270 268 }