#define CGROUP_WEIGHT_DFL              100
 #define CGROUP_WEIGHT_MAX              10000
 
+/* walk only threadgroup leaders */
+#define CSS_TASK_ITER_PROCS            (1U << 0)
+
 /* a css_task_iter should be treated as an opaque object */
 struct css_task_iter {
        struct cgroup_subsys            *ss;
+       unsigned int                    flags;
 
        struct list_head                *cset_pos;
        struct list_head                *cset_head;
 struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset,
                                        struct cgroup_subsys_state **dst_cssp);
 
-void css_task_iter_start(struct cgroup_subsys_state *css,
+void css_task_iter_start(struct cgroup_subsys_state *css, unsigned int flags,
                         struct css_task_iter *it);
 struct task_struct *css_task_iter_next(struct css_task_iter *it);
 void css_task_iter_end(struct css_task_iter *it);
 
         * ->can_attach() fails.
         */
        do {
-               css_task_iter_start(&from->self, &it);
+               css_task_iter_start(&from->self, 0, &it);
                task = css_task_iter_next(&it);
                if (task)
                        get_task_struct(task);
        if (!array)
                return -ENOMEM;
        /* now, populate the array */
-       css_task_iter_start(&cgrp->self, &it);
+       css_task_iter_start(&cgrp->self, 0, &it);
        while ((tsk = css_task_iter_next(&it))) {
                if (unlikely(n == length))
                        break;
        }
        rcu_read_unlock();
 
-       css_task_iter_start(&cgrp->self, &it);
+       css_task_iter_start(&cgrp->self, 0, &it);
        while ((tsk = css_task_iter_next(&it))) {
                switch (tsk->state) {
                case TASK_RUNNING:
 
        lockdep_assert_held(&css_set_lock);
        WARN_ON_ONCE(!l);
 
+repeat:
        /*
         * Advance iterator to find next entry.  cset->tasks is consumed
         * first and then ->mg_tasks.  After ->mg_tasks, we move onto the
                css_task_iter_advance_css_set(it);
        else
                it->task_pos = l;
+
+       /* if PROCS, skip over tasks which aren't group leaders */
+       if ((it->flags & CSS_TASK_ITER_PROCS) && it->task_pos &&
+           !thread_group_leader(list_entry(it->task_pos, struct task_struct,
+                                           cg_list)))
+               goto repeat;
 }
 
 /**
  * css_task_iter_start - initiate task iteration
  * @css: the css to walk tasks of
+ * @flags: CSS_TASK_ITER_* flags
  * @it: the task iterator to use
  *
  * Initiate iteration through the tasks of @css.  The caller can call
  * returns NULL.  On completion of iteration, css_task_iter_end() must be
  * called.
  */
-void css_task_iter_start(struct cgroup_subsys_state *css,
+void css_task_iter_start(struct cgroup_subsys_state *css, unsigned int flags,
                         struct css_task_iter *it)
 {
        /* no one should try to iterate before mounting cgroups */
        spin_lock_irq(&css_set_lock);
 
        it->ss = css->ss;
+       it->flags = flags;
 
        if (it->ss)
                it->cset_pos = &css->cgroup->e_csets[css->ss->id];
 {
        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;
+       return css_task_iter_next(it);
 }
 
 static void *cgroup_procs_start(struct seq_file *s, loff_t *pos)
                if (!it)
                        return ERR_PTR(-ENOMEM);
                of->priv = it;
-               css_task_iter_start(&cgrp->self, it);
+               css_task_iter_start(&cgrp->self, CSS_TASK_ITER_PROCS, it);
        } else if (!(*pos)++) {
                css_task_iter_end(it);
-               css_task_iter_start(&cgrp->self, it);
+               css_task_iter_start(&cgrp->self, CSS_TASK_ITER_PROCS, 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));
+       seq_printf(s, "%d\n", task_pid_vnr(v));
        return 0;
 }
 
 
        struct css_task_iter it;
        struct task_struct *task;
 
-       css_task_iter_start(&cs->css, &it);
+       css_task_iter_start(&cs->css, 0, &it);
        while ((task = css_task_iter_next(&it)))
                set_cpus_allowed_ptr(task, cs->effective_cpus);
        css_task_iter_end(&it);
         * It's ok if we rebind the same mm twice; mpol_rebind_mm()
         * is idempotent.  Also migrate pages in each mm to new nodes.
         */
-       css_task_iter_start(&cs->css, &it);
+       css_task_iter_start(&cs->css, 0, &it);
        while ((task = css_task_iter_next(&it))) {
                struct mm_struct *mm;
                bool migrate;
        struct css_task_iter it;
        struct task_struct *task;
 
-       css_task_iter_start(&cs->css, &it);
+       css_task_iter_start(&cs->css, 0, &it);
        while ((task = css_task_iter_next(&it)))
                cpuset_update_task_spread_flag(cs, task);
        css_task_iter_end(&it);
 
        rcu_read_unlock();
 
        /* are all tasks frozen? */
-       css_task_iter_start(css, &it);
+       css_task_iter_start(css, 0, &it);
 
        while ((task = css_task_iter_next(&it))) {
                if (freezing(task)) {
        struct css_task_iter it;
        struct task_struct *task;
 
-       css_task_iter_start(&freezer->css, &it);
+       css_task_iter_start(&freezer->css, 0, &it);
        while ((task = css_task_iter_next(&it)))
                freeze_task(task);
        css_task_iter_end(&it);
        struct css_task_iter it;
        struct task_struct *task;
 
-       css_task_iter_start(&freezer->css, &it);
+       css_task_iter_start(&freezer->css, 0, &it);
        while ((task = css_task_iter_next(&it)))
                __thaw_task(task);
        css_task_iter_end(&it);
 
                struct css_task_iter it;
                struct task_struct *task;
 
-               css_task_iter_start(&iter->css, &it);
+               css_task_iter_start(&iter->css, 0, &it);
                while (!ret && (task = css_task_iter_next(&it)))
                        ret = fn(task, arg);
                css_task_iter_end(&it);
 
 
        cs->classid = (u32)value;
 
-       css_task_iter_start(css, &it);
+       css_task_iter_start(css, 0, &it);
        while ((p = css_task_iter_next(&it))) {
                task_lock(p);
                iterate_fd(p->files, 0, update_classid_sock,