@@ -57,10 +57,12 @@ struct pids_cgroup {
5757 atomic64_t limit ;
5858 int64_t watermark ;
5959
60- /* Handle for " pids.events" */
60+ /* Handles for pids.events[.local] */
6161 struct cgroup_file events_file ;
62+ struct cgroup_file events_local_file ;
6263
6364 atomic64_t events [NR_PIDCG_EVENTS ];
65+ atomic64_t events_local [NR_PIDCG_EVENTS ];
6466};
6567
6668static struct pids_cgroup * css_pids (struct cgroup_subsys_state * css )
@@ -244,21 +246,23 @@ static void pids_event(struct pids_cgroup *pids_forking,
244246 struct pids_cgroup * p = pids_forking ;
245247 bool limit = false;
246248
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 ;
249+ /* Only log the first time limit is hit. */
250+ if (atomic64_inc_return (& p -> events_local [PIDCG_FORKFAIL ]) == 1 ) {
251+ pr_info ("cgroup: fork rejected by pids controller in " );
252+ pr_cont_cgroup_path (p -> css .cgroup );
253+ pr_cont ("\n" );
254+ }
255+ cgroup_file_notify (& p -> events_local_file );
256+ if (!cgroup_subsys_on_dfl (pids_cgrp_subsys ) ||
257+ cgrp_dfl_root .flags & CGRP_ROOT_PIDS_LOCAL_EVENTS )
258+ return ;
259259
260- if (p == pids_over_limit )
260+ for (; parent_pids (p ); p = parent_pids (p )) {
261+ if (p == pids_over_limit ) {
261262 limit = true;
263+ atomic64_inc (& p -> events_local [PIDCG_MAX ]);
264+ cgroup_file_notify (& p -> events_local_file );
265+ }
262266 if (limit )
263267 atomic64_inc (& p -> events [PIDCG_MAX ]);
264268
@@ -368,20 +372,68 @@ static s64 pids_peak_read(struct cgroup_subsys_state *css,
368372 return READ_ONCE (pids -> watermark );
369373}
370374
371- static int pids_events_show (struct seq_file * sf , void * v )
375+ static int __pids_events_show (struct seq_file * sf , bool local )
372376{
373377 struct pids_cgroup * pids = css_pids (seq_css (sf ));
374378 enum pidcg_event pe = PIDCG_MAX ;
379+ atomic64_t * events ;
375380
376381 if (!cgroup_subsys_on_dfl (pids_cgrp_subsys ) ||
377- cgrp_dfl_root .flags & CGRP_ROOT_PIDS_LOCAL_EVENTS )
382+ cgrp_dfl_root .flags & CGRP_ROOT_PIDS_LOCAL_EVENTS ) {
378383 pe = PIDCG_FORKFAIL ;
384+ local = true;
385+ }
386+ events = local ? pids -> events_local : pids -> events ;
379387
380- seq_printf (sf , "max %lld\n" , (s64 )atomic64_read (& pids -> events [pe ]));
388+ seq_printf (sf , "max %lld\n" , (s64 )atomic64_read (& events [pe ]));
389+ return 0 ;
390+ }
391+
392+ static int pids_events_show (struct seq_file * sf , void * v )
393+ {
394+ __pids_events_show (sf , false);
395+ return 0 ;
396+ }
397+
398+ static int pids_events_local_show (struct seq_file * sf , void * v )
399+ {
400+ __pids_events_show (sf , true);
381401 return 0 ;
382402}
383403
384404static struct cftype pids_files [] = {
405+ {
406+ .name = "max" ,
407+ .write = pids_max_write ,
408+ .seq_show = pids_max_show ,
409+ .flags = CFTYPE_NOT_ON_ROOT ,
410+ },
411+ {
412+ .name = "current" ,
413+ .read_s64 = pids_current_read ,
414+ .flags = CFTYPE_NOT_ON_ROOT ,
415+ },
416+ {
417+ .name = "peak" ,
418+ .flags = CFTYPE_NOT_ON_ROOT ,
419+ .read_s64 = pids_peak_read ,
420+ },
421+ {
422+ .name = "events" ,
423+ .seq_show = pids_events_show ,
424+ .file_offset = offsetof(struct pids_cgroup , events_file ),
425+ .flags = CFTYPE_NOT_ON_ROOT ,
426+ },
427+ {
428+ .name = "events.local" ,
429+ .seq_show = pids_events_local_show ,
430+ .file_offset = offsetof(struct pids_cgroup , events_local_file ),
431+ .flags = CFTYPE_NOT_ON_ROOT ,
432+ },
433+ { } /* terminate */
434+ };
435+
436+ static struct cftype pids_files_legacy [] = {
385437 {
386438 .name = "max" ,
387439 .write = pids_max_write ,
@@ -407,6 +459,7 @@ static struct cftype pids_files[] = {
407459 { } /* terminate */
408460};
409461
462+
410463struct cgroup_subsys pids_cgrp_subsys = {
411464 .css_alloc = pids_css_alloc ,
412465 .css_free = pids_css_free ,
@@ -415,7 +468,7 @@ struct cgroup_subsys pids_cgrp_subsys = {
415468 .can_fork = pids_can_fork ,
416469 .cancel_fork = pids_cancel_fork ,
417470 .release = pids_release ,
418- .legacy_cftypes = pids_files ,
471+ .legacy_cftypes = pids_files_legacy ,
419472 .dfl_cftypes = pids_files ,
420473 .threaded = true,
421474};
0 commit comments