summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/cgroup.c63
1 files changed, 58 insertions, 5 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 87167e40c4fa..fd684bfd154d 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4426,6 +4426,60 @@ out_err:
4426 return ret; 4426 return ret;
4427} 4427}
4428 4428
4429static void cgroup_procs_release(struct kernfs_open_file *of)
4430{
4431 if (of->priv) {
4432 css_task_iter_end(of->priv);
4433 kfree(of->priv);
4434 }
4435}
4436
4437static void *cgroup_procs_next(struct seq_file *s, void *v, loff_t *pos)
4438{
4439 struct kernfs_open_file *of = s->private;
4440 struct css_task_iter *it = of->priv;
4441 struct task_struct *task;
4442
4443 do {
4444 task = css_task_iter_next(it);
4445 } while (task && !thread_group_leader(task));
4446
4447 return task;
4448}
4449
4450static void *cgroup_procs_start(struct seq_file *s, loff_t *pos)
4451{
4452 struct kernfs_open_file *of = s->private;
4453 struct cgroup *cgrp = seq_css(s)->cgroup;
4454 struct css_task_iter *it = of->priv;
4455
4456 /*
4457 * When a seq_file is seeked, it's always traversed sequentially
4458 * from position 0, so we can simply keep iterating on !0 *pos.
4459 */
4460 if (!it) {
4461 if (WARN_ON_ONCE((*pos)++))
4462 return ERR_PTR(-EINVAL);
4463
4464 it = kzalloc(sizeof(*it), GFP_KERNEL);
4465 if (!it)
4466 return ERR_PTR(-ENOMEM);
4467 of->priv = it;
4468 css_task_iter_start(&cgrp->self, it);
4469 } else if (!(*pos)++) {
4470 css_task_iter_end(it);
4471 css_task_iter_start(&cgrp->self, it);
4472 }
4473
4474 return cgroup_procs_next(s, NULL, NULL);
4475}
4476
4477static int cgroup_procs_show(struct seq_file *s, void *v)
4478{
4479 seq_printf(s, "%d\n", task_tgid_vnr(v));
4480 return 0;
4481}
4482
4429/* 4483/*
4430 * Stuff for reading the 'tasks'/'procs' files. 4484 * Stuff for reading the 'tasks'/'procs' files.
4431 * 4485 *
@@ -4914,11 +4968,10 @@ static struct cftype cgroup_dfl_base_files[] = {
4914 { 4968 {
4915 .name = "cgroup.procs", 4969 .name = "cgroup.procs",
4916 .file_offset = offsetof(struct cgroup, procs_file), 4970 .file_offset = offsetof(struct cgroup, procs_file),
4917 .seq_start = cgroup_pidlist_start, 4971 .release = cgroup_procs_release,
4918 .seq_next = cgroup_pidlist_next, 4972 .seq_start = cgroup_procs_start,
4919 .seq_stop = cgroup_pidlist_stop, 4973 .seq_next = cgroup_procs_next,
4920 .seq_show = cgroup_pidlist_show, 4974 .seq_show = cgroup_procs_show,
4921 .private = CGROUP_FILE_PROCS,
4922 .write = cgroup_procs_write, 4975 .write = cgroup_procs_write,
4923 }, 4976 },
4924 { 4977 {