Skip to content

Commit 0d2b595

Browse files
committed
cgroup: Allocate cgroup_file_ctx for kernfs_open_file->priv
of->priv is currently used by each interface file implementation to store private information. This patch collects the current two private data usages into struct cgroup_file_ctx which is allocated and freed by the common path. This allows generic private data which applies to multiple files, which will be used to in the following patch. Note that cgroup_procs iterator is now embedded as procs.iter in the new cgroup_file_ctx so that it doesn't need to be allocated and freed separately. v2: union dropped from cgroup_file_ctx and the procs iterator is embedded in cgroup_file_ctx as suggested by Linus. v3: Michal pointed out that cgroup1's procs pidlist uses of->priv too. Converted. Didn't change to embedded allocation as cgroup1 pidlists get stored for caching. Signed-off-by: Tejun Heo <[email protected]> Cc: Linus Torvalds <[email protected]> Reviewed-by: Michal Koutný <[email protected]>
1 parent 1756d79 commit 0d2b595

File tree

3 files changed

+65
-31
lines changed

3 files changed

+65
-31
lines changed

kernel/cgroup/cgroup-internal.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,23 @@ static inline struct cgroup_fs_context *cgroup_fc2context(struct fs_context *fc)
6565
return container_of(kfc, struct cgroup_fs_context, kfc);
6666
}
6767

68+
struct cgroup_pidlist;
69+
70+
struct cgroup_file_ctx {
71+
struct {
72+
void *trigger;
73+
} psi;
74+
75+
struct {
76+
bool started;
77+
struct css_task_iter iter;
78+
} procs;
79+
80+
struct {
81+
struct cgroup_pidlist *pidlist;
82+
} procs1;
83+
};
84+
6885
/*
6986
* A cgroup can be associated with multiple css_sets as different tasks may
7087
* belong to different cgroups on different hierarchies. In the other

kernel/cgroup/cgroup-v1.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
394394
* next pid to display, if any
395395
*/
396396
struct kernfs_open_file *of = s->private;
397+
struct cgroup_file_ctx *ctx = of->priv;
397398
struct cgroup *cgrp = seq_css(s)->cgroup;
398399
struct cgroup_pidlist *l;
399400
enum cgroup_filetype type = seq_cft(s)->private;
@@ -403,25 +404,24 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
403404
mutex_lock(&cgrp->pidlist_mutex);
404405

405406
/*
406-
* !NULL @of->priv indicates that this isn't the first start()
407-
* after open. If the matching pidlist is around, we can use that.
408-
* Look for it. Note that @of->priv can't be used directly. It
409-
* could already have been destroyed.
407+
* !NULL @ctx->procs1.pidlist indicates that this isn't the first
408+
* start() after open. If the matching pidlist is around, we can use
409+
* that. Look for it. Note that @ctx->procs1.pidlist can't be used
410+
* directly. It could already have been destroyed.
410411
*/
411-
if (of->priv)
412-
of->priv = cgroup_pidlist_find(cgrp, type);
412+
if (ctx->procs1.pidlist)
413+
ctx->procs1.pidlist = cgroup_pidlist_find(cgrp, type);
413414

414415
/*
415416
* Either this is the first start() after open or the matching
416417
* pidlist has been destroyed inbetween. Create a new one.
417418
*/
418-
if (!of->priv) {
419-
ret = pidlist_array_load(cgrp, type,
420-
(struct cgroup_pidlist **)&of->priv);
419+
if (!ctx->procs1.pidlist) {
420+
ret = pidlist_array_load(cgrp, type, &ctx->procs1.pidlist);
421421
if (ret)
422422
return ERR_PTR(ret);
423423
}
424-
l = of->priv;
424+
l = ctx->procs1.pidlist;
425425

426426
if (pid) {
427427
int end = l->length;
@@ -449,7 +449,8 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
449449
static void cgroup_pidlist_stop(struct seq_file *s, void *v)
450450
{
451451
struct kernfs_open_file *of = s->private;
452-
struct cgroup_pidlist *l = of->priv;
452+
struct cgroup_file_ctx *ctx = of->priv;
453+
struct cgroup_pidlist *l = ctx->procs1.pidlist;
453454

454455
if (l)
455456
mod_delayed_work(cgroup_pidlist_destroy_wq, &l->destroy_dwork,
@@ -460,7 +461,8 @@ static void cgroup_pidlist_stop(struct seq_file *s, void *v)
460461
static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos)
461462
{
462463
struct kernfs_open_file *of = s->private;
463-
struct cgroup_pidlist *l = of->priv;
464+
struct cgroup_file_ctx *ctx = of->priv;
465+
struct cgroup_pidlist *l = ctx->procs1.pidlist;
464466
pid_t *p = v;
465467
pid_t *end = l->list + l->length;
466468
/*

kernel/cgroup/cgroup.c

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3630,6 +3630,7 @@ static int cgroup_cpu_pressure_show(struct seq_file *seq, void *v)
36303630
static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf,
36313631
size_t nbytes, enum psi_res res)
36323632
{
3633+
struct cgroup_file_ctx *ctx = of->priv;
36333634
struct psi_trigger *new;
36343635
struct cgroup *cgrp;
36353636
struct psi_group *psi;
@@ -3648,7 +3649,7 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf,
36483649
return PTR_ERR(new);
36493650
}
36503651

3651-
psi_trigger_replace(&of->priv, new);
3652+
psi_trigger_replace(&ctx->psi.trigger, new);
36523653

36533654
cgroup_put(cgrp);
36543655

@@ -3679,12 +3680,16 @@ static ssize_t cgroup_cpu_pressure_write(struct kernfs_open_file *of,
36793680
static __poll_t cgroup_pressure_poll(struct kernfs_open_file *of,
36803681
poll_table *pt)
36813682
{
3682-
return psi_trigger_poll(&of->priv, of->file, pt);
3683+
struct cgroup_file_ctx *ctx = of->priv;
3684+
3685+
return psi_trigger_poll(&ctx->psi.trigger, of->file, pt);
36833686
}
36843687

36853688
static void cgroup_pressure_release(struct kernfs_open_file *of)
36863689
{
3687-
psi_trigger_replace(&of->priv, NULL);
3690+
struct cgroup_file_ctx *ctx = of->priv;
3691+
3692+
psi_trigger_replace(&ctx->psi.trigger, NULL);
36883693
}
36893694

36903695
bool cgroup_psi_enabled(void)
@@ -3811,18 +3816,31 @@ static ssize_t cgroup_kill_write(struct kernfs_open_file *of, char *buf,
38113816
static int cgroup_file_open(struct kernfs_open_file *of)
38123817
{
38133818
struct cftype *cft = of_cft(of);
3819+
struct cgroup_file_ctx *ctx;
3820+
int ret;
38143821

3815-
if (cft->open)
3816-
return cft->open(of);
3817-
return 0;
3822+
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
3823+
if (!ctx)
3824+
return -ENOMEM;
3825+
of->priv = ctx;
3826+
3827+
if (!cft->open)
3828+
return 0;
3829+
3830+
ret = cft->open(of);
3831+
if (ret)
3832+
kfree(ctx);
3833+
return ret;
38183834
}
38193835

38203836
static void cgroup_file_release(struct kernfs_open_file *of)
38213837
{
38223838
struct cftype *cft = of_cft(of);
3839+
struct cgroup_file_ctx *ctx = of->priv;
38233840

38243841
if (cft->release)
38253842
cft->release(of);
3843+
kfree(ctx);
38263844
}
38273845

38283846
static ssize_t cgroup_file_write(struct kernfs_open_file *of, char *buf,
@@ -4751,43 +4769,40 @@ void css_task_iter_end(struct css_task_iter *it)
47514769

47524770
static void cgroup_procs_release(struct kernfs_open_file *of)
47534771
{
4754-
if (of->priv) {
4755-
css_task_iter_end(of->priv);
4756-
kfree(of->priv);
4757-
}
4772+
struct cgroup_file_ctx *ctx = of->priv;
4773+
4774+
if (ctx->procs.started)
4775+
css_task_iter_end(&ctx->procs.iter);
47584776
}
47594777

47604778
static void *cgroup_procs_next(struct seq_file *s, void *v, loff_t *pos)
47614779
{
47624780
struct kernfs_open_file *of = s->private;
4763-
struct css_task_iter *it = of->priv;
4781+
struct cgroup_file_ctx *ctx = of->priv;
47644782

47654783
if (pos)
47664784
(*pos)++;
47674785

4768-
return css_task_iter_next(it);
4786+
return css_task_iter_next(&ctx->procs.iter);
47694787
}
47704788

47714789
static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos,
47724790
unsigned int iter_flags)
47734791
{
47744792
struct kernfs_open_file *of = s->private;
47754793
struct cgroup *cgrp = seq_css(s)->cgroup;
4776-
struct css_task_iter *it = of->priv;
4794+
struct cgroup_file_ctx *ctx = of->priv;
4795+
struct css_task_iter *it = &ctx->procs.iter;
47774796

47784797
/*
47794798
* When a seq_file is seeked, it's always traversed sequentially
47804799
* from position 0, so we can simply keep iterating on !0 *pos.
47814800
*/
4782-
if (!it) {
4801+
if (!ctx->procs.started) {
47834802
if (WARN_ON_ONCE((*pos)))
47844803
return ERR_PTR(-EINVAL);
4785-
4786-
it = kzalloc(sizeof(*it), GFP_KERNEL);
4787-
if (!it)
4788-
return ERR_PTR(-ENOMEM);
4789-
of->priv = it;
47904804
css_task_iter_start(&cgrp->self, iter_flags, it);
4805+
ctx->procs.started = true;
47914806
} else if (!(*pos)) {
47924807
css_task_iter_end(it);
47934808
css_task_iter_start(&cgrp->self, iter_flags, it);

0 commit comments

Comments
 (0)