* next pid to display, if any
         */
        struct kernfs_open_file *of = s->private;
+       struct cgroup_file_ctx *ctx = of->priv;
        struct cgroup *cgrp = seq_css(s)->cgroup;
        struct cgroup_pidlist *l;
        enum cgroup_filetype type = seq_cft(s)->private;
        mutex_lock(&cgrp->pidlist_mutex);
 
        /*
-        * !NULL @of->priv indicates that this isn't the first start()
-        * after open.  If the matching pidlist is around, we can use that.
-        * Look for it.  Note that @of->priv can't be used directly.  It
-        * could already have been destroyed.
+        * !NULL @ctx->procs1.pidlist indicates that this isn't the first
+        * start() after open. If the matching pidlist is around, we can use
+        * that. Look for it. Note that @ctx->procs1.pidlist can't be used
+        * directly. It could already have been destroyed.
         */
-       if (of->priv)
-               of->priv = cgroup_pidlist_find(cgrp, type);
+       if (ctx->procs1.pidlist)
+               ctx->procs1.pidlist = cgroup_pidlist_find(cgrp, type);
 
        /*
         * Either this is the first start() after open or the matching
         * pidlist has been destroyed inbetween.  Create a new one.
         */
-       if (!of->priv) {
-               ret = pidlist_array_load(cgrp, type,
-                                        (struct cgroup_pidlist **)&of->priv);
+       if (!ctx->procs1.pidlist) {
+               ret = pidlist_array_load(cgrp, type, &ctx->procs1.pidlist);
                if (ret)
                        return ERR_PTR(ret);
        }
-       l = of->priv;
+       l = ctx->procs1.pidlist;
 
        if (pid) {
                int end = l->length;
 static void cgroup_pidlist_stop(struct seq_file *s, void *v)
 {
        struct kernfs_open_file *of = s->private;
-       struct cgroup_pidlist *l = of->priv;
+       struct cgroup_file_ctx *ctx = of->priv;
+       struct cgroup_pidlist *l = ctx->procs1.pidlist;
 
        if (l)
                mod_delayed_work(cgroup_pidlist_destroy_wq, &l->destroy_dwork,
 static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos)
 {
        struct kernfs_open_file *of = s->private;
-       struct cgroup_pidlist *l = of->priv;
+       struct cgroup_file_ctx *ctx = of->priv;
+       struct cgroup_pidlist *l = ctx->procs1.pidlist;
        pid_t *p = v;
        pid_t *end = l->list + l->length;
        /*
 
 static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf,
                                          size_t nbytes, enum psi_res res)
 {
+       struct cgroup_file_ctx *ctx = of->priv;
        struct psi_trigger *new;
        struct cgroup *cgrp;
        struct psi_group *psi;
                return PTR_ERR(new);
        }
 
-       psi_trigger_replace(&of->priv, new);
+       psi_trigger_replace(&ctx->psi.trigger, new);
 
        cgroup_put(cgrp);
 
 static __poll_t cgroup_pressure_poll(struct kernfs_open_file *of,
                                          poll_table *pt)
 {
-       return psi_trigger_poll(&of->priv, of->file, pt);
+       struct cgroup_file_ctx *ctx = of->priv;
+
+       return psi_trigger_poll(&ctx->psi.trigger, of->file, pt);
 }
 
 static void cgroup_pressure_release(struct kernfs_open_file *of)
 {
-       psi_trigger_replace(&of->priv, NULL);
+       struct cgroup_file_ctx *ctx = of->priv;
+
+       psi_trigger_replace(&ctx->psi.trigger, NULL);
 }
 
 bool cgroup_psi_enabled(void)
 static int cgroup_file_open(struct kernfs_open_file *of)
 {
        struct cftype *cft = of_cft(of);
+       struct cgroup_file_ctx *ctx;
+       int ret;
 
-       if (cft->open)
-               return cft->open(of);
-       return 0;
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+       of->priv = ctx;
+
+       if (!cft->open)
+               return 0;
+
+       ret = cft->open(of);
+       if (ret)
+               kfree(ctx);
+       return ret;
 }
 
 static void cgroup_file_release(struct kernfs_open_file *of)
 {
        struct cftype *cft = of_cft(of);
+       struct cgroup_file_ctx *ctx = of->priv;
 
        if (cft->release)
                cft->release(of);
+       kfree(ctx);
 }
 
 static ssize_t cgroup_file_write(struct kernfs_open_file *of, char *buf,
 
 static void cgroup_procs_release(struct kernfs_open_file *of)
 {
-       if (of->priv) {
-               css_task_iter_end(of->priv);
-               kfree(of->priv);
-       }
+       struct cgroup_file_ctx *ctx = of->priv;
+
+       if (ctx->procs.started)
+               css_task_iter_end(&ctx->procs.iter);
 }
 
 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 cgroup_file_ctx *ctx = of->priv;
 
        if (pos)
                (*pos)++;
 
-       return css_task_iter_next(it);
+       return css_task_iter_next(&ctx->procs.iter);
 }
 
 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;
+       struct cgroup_file_ctx *ctx = of->priv;
+       struct css_task_iter *it = &ctx->procs.iter;
 
        /*
         * 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 (!ctx->procs.started) {
                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, iter_flags, it);
+               ctx->procs.started = true;
        } else if (!(*pos)) {
                css_task_iter_end(it);
                css_task_iter_start(&cgrp->self, iter_flags, it);