Skip to content

Commit 5251c6c

Browse files
joshdonhtejun
authored andcommitted
cgroup: add pids.peak interface for pids controller
pids.peak tracks the high watermark of usage for number of pids. This helps give a better baseline on which to set pids.max. Polling pids.current isn't really feasible, since it would potentially miss short-lived spikes. This interface is analogous to memory.peak. Signed-off-by: Josh Don <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent dc79ec1 commit 5251c6c

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

kernel/cgroup/pids.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct pids_cgroup {
4747
*/
4848
atomic64_t counter;
4949
atomic64_t limit;
50+
int64_t watermark;
5051

5152
/* Handle for "pids.events" */
5253
struct cgroup_file events_file;
@@ -85,6 +86,16 @@ static void pids_css_free(struct cgroup_subsys_state *css)
8586
kfree(css_pids(css));
8687
}
8788

89+
static void pids_update_watermark(struct pids_cgroup *p, int64_t nr_pids)
90+
{
91+
/*
92+
* This is racy, but we don't need perfectly accurate tallying of
93+
* the watermark, and this lets us avoid extra atomic overhead.
94+
*/
95+
if (nr_pids > READ_ONCE(p->watermark))
96+
WRITE_ONCE(p->watermark, nr_pids);
97+
}
98+
8899
/**
89100
* pids_cancel - uncharge the local pid count
90101
* @pids: the pid cgroup state
@@ -128,8 +139,11 @@ static void pids_charge(struct pids_cgroup *pids, int num)
128139
{
129140
struct pids_cgroup *p;
130141

131-
for (p = pids; parent_pids(p); p = parent_pids(p))
132-
atomic64_add(num, &p->counter);
142+
for (p = pids; parent_pids(p); p = parent_pids(p)) {
143+
int64_t new = atomic64_add_return(num, &p->counter);
144+
145+
pids_update_watermark(p, new);
146+
}
133147
}
134148

135149
/**
@@ -156,6 +170,12 @@ static int pids_try_charge(struct pids_cgroup *pids, int num)
156170
*/
157171
if (new > limit)
158172
goto revert;
173+
174+
/*
175+
* Not technically accurate if we go over limit somewhere up
176+
* the hierarchy, but that's tolerable for the watermark.
177+
*/
178+
pids_update_watermark(p, new);
159179
}
160180

161181
return 0;
@@ -311,6 +331,14 @@ static s64 pids_current_read(struct cgroup_subsys_state *css,
311331
return atomic64_read(&pids->counter);
312332
}
313333

334+
static s64 pids_peak_read(struct cgroup_subsys_state *css,
335+
struct cftype *cft)
336+
{
337+
struct pids_cgroup *pids = css_pids(css);
338+
339+
return READ_ONCE(pids->watermark);
340+
}
341+
314342
static int pids_events_show(struct seq_file *sf, void *v)
315343
{
316344
struct pids_cgroup *pids = css_pids(seq_css(sf));
@@ -331,6 +359,11 @@ static struct cftype pids_files[] = {
331359
.read_s64 = pids_current_read,
332360
.flags = CFTYPE_NOT_ON_ROOT,
333361
},
362+
{
363+
.name = "peak",
364+
.flags = CFTYPE_NOT_ON_ROOT,
365+
.read_s64 = pids_peak_read,
366+
},
334367
{
335368
.name = "events",
336369
.seq_show = pids_events_show,

0 commit comments

Comments
 (0)