return ret;
 }
 
+static void cgroup_procs_release(struct kernfs_open_file *of)
+{
+       if (of->priv) {
+               css_task_iter_end(of->priv);
+               kfree(of->priv);
+       }
+}
+
+static void *cgroup_procs_next(struct seq_file *s, void *v, loff_t *pos)
+{
+       struct kernfs_open_file *of = s->private;
+       struct css_task_iter *it = of->priv;
+       struct task_struct *task;
+
+       do {
+               task = css_task_iter_next(it);
+       } while (task && !thread_group_leader(task));
+
+       return task;
+}
+
+static void *cgroup_procs_start(struct seq_file *s, loff_t *pos)
+{
+       struct kernfs_open_file *of = s->private;
+       struct cgroup *cgrp = seq_css(s)->cgroup;
+       struct css_task_iter *it = of->priv;
+
+       /*
+        * When a seq_file is seeked, it's always traversed sequentially
+        * from position 0, so we can simply keep iterating on !0 *pos.
+        */
+       if (!it) {
+               if (WARN_ON_ONCE((*pos)++))
+                       return ERR_PTR(-EINVAL);
+
+               it = kzalloc(sizeof(*it), GFP_KERNEL);
+               if (!it)
+                       return ERR_PTR(-ENOMEM);
+               of->priv = it;
+               css_task_iter_start(&cgrp->self, it);
+       } else if (!(*pos)++) {
+               css_task_iter_end(it);
+               css_task_iter_start(&cgrp->self, it);
+       }
+
+       return cgroup_procs_next(s, NULL, NULL);
+}
+
+static int cgroup_procs_show(struct seq_file *s, void *v)
+{
+       seq_printf(s, "%d\n", task_tgid_vnr(v));
+       return 0;
+}
+
 /*
  * Stuff for reading the 'tasks'/'procs' files.
  *
        {
                .name = "cgroup.procs",
                .file_offset = offsetof(struct cgroup, procs_file),
-               .seq_start = cgroup_pidlist_start,
-               .seq_next = cgroup_pidlist_next,
-               .seq_stop = cgroup_pidlist_stop,
-               .seq_show = cgroup_pidlist_show,
-               .private = CGROUP_FILE_PROCS,
+               .release = cgroup_procs_release,
+               .seq_start = cgroup_procs_start,
+               .seq_next = cgroup_procs_next,
+               .seq_show = cgroup_procs_show,
                .write = cgroup_procs_write,
        },
        {