|
@@ -3643,6 +3643,7 @@ static void css_task_iter_advance(struct css_task_iter *it)
|
|
|
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
|
|
@@ -3657,11 +3658,18 @@ static void css_task_iter_advance(struct css_task_iter *it)
|
|
|
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
|
|
@@ -3669,7 +3677,7 @@ static void css_task_iter_advance(struct css_task_iter *it)
|
|
|
* 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 */
|
|
@@ -3680,6 +3688,7 @@ void css_task_iter_start(struct cgroup_subsys_state *css,
|
|
|
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];
|
|
@@ -3753,13 +3762,8 @@ 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;
|
|
|
+ return css_task_iter_next(it);
|
|
|
}
|
|
|
|
|
|
static void *cgroup_procs_start(struct seq_file *s, loff_t *pos)
|
|
@@ -3780,10 +3784,10 @@ 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);
|
|
@@ -3791,7 +3795,7 @@ static void *cgroup_procs_start(struct seq_file *s, loff_t *pos)
|
|
|
|
|
|
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;
|
|
|
}
|
|
|
|