Commit e9414845 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-5.6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup

Pull cgroup fixes from Tejun Heo:

 - cgroup.procs listing related fixes.

   It didn't interlock properly with exiting tasks leaving a short
   window where a cgroup has empty cgroup.procs but still can't be
   removed and misbehaved on short reads.

 - psi_show() crash fix on 32bit ino archs

 - Empty release_agent handling fix

* 'for-5.6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
  cgroup1: don't call release_agent when it is ""
  cgroup: fix psi_show() crash on 32bit ino archs
  cgroup: Iterate tasks that did not finish do_exit()
  cgroup: cgroup_procs_next should increase position index
  cgroup-v1: cgroup_pidlist_next should update position index
parents 2c1aca4b 2e5383d7
...@@ -62,6 +62,7 @@ struct css_task_iter { ...@@ -62,6 +62,7 @@ struct css_task_iter {
struct list_head *mg_tasks_head; struct list_head *mg_tasks_head;
struct list_head *dying_tasks_head; struct list_head *dying_tasks_head;
struct list_head *cur_tasks_head;
struct css_set *cur_cset; struct css_set *cur_cset;
struct css_set *cur_dcset; struct css_set *cur_dcset;
struct task_struct *cur_task; struct task_struct *cur_task;
......
...@@ -471,6 +471,7 @@ static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos) ...@@ -471,6 +471,7 @@ static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos)
*/ */
p++; p++;
if (p >= end) { if (p >= end) {
(*pos)++;
return NULL; return NULL;
} else { } else {
*pos = *p; *pos = *p;
...@@ -782,7 +783,7 @@ void cgroup1_release_agent(struct work_struct *work) ...@@ -782,7 +783,7 @@ void cgroup1_release_agent(struct work_struct *work)
pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
agentbuf = kstrdup(cgrp->root->release_agent_path, GFP_KERNEL); agentbuf = kstrdup(cgrp->root->release_agent_path, GFP_KERNEL);
if (!pathbuf || !agentbuf) if (!pathbuf || !agentbuf || !strlen(agentbuf))
goto out; goto out;
spin_lock_irq(&css_set_lock); spin_lock_irq(&css_set_lock);
......
...@@ -3542,21 +3542,21 @@ static int cpu_stat_show(struct seq_file *seq, void *v) ...@@ -3542,21 +3542,21 @@ static int cpu_stat_show(struct seq_file *seq, void *v)
static int cgroup_io_pressure_show(struct seq_file *seq, void *v) static int cgroup_io_pressure_show(struct seq_file *seq, void *v)
{ {
struct cgroup *cgrp = seq_css(seq)->cgroup; struct cgroup *cgrp = seq_css(seq)->cgroup;
struct psi_group *psi = cgroup_id(cgrp) == 1 ? &psi_system : &cgrp->psi; struct psi_group *psi = cgroup_ino(cgrp) == 1 ? &psi_system : &cgrp->psi;
return psi_show(seq, psi, PSI_IO); return psi_show(seq, psi, PSI_IO);
} }
static int cgroup_memory_pressure_show(struct seq_file *seq, void *v) static int cgroup_memory_pressure_show(struct seq_file *seq, void *v)
{ {
struct cgroup *cgrp = seq_css(seq)->cgroup; struct cgroup *cgrp = seq_css(seq)->cgroup;
struct psi_group *psi = cgroup_id(cgrp) == 1 ? &psi_system : &cgrp->psi; struct psi_group *psi = cgroup_ino(cgrp) == 1 ? &psi_system : &cgrp->psi;
return psi_show(seq, psi, PSI_MEM); return psi_show(seq, psi, PSI_MEM);
} }
static int cgroup_cpu_pressure_show(struct seq_file *seq, void *v) static int cgroup_cpu_pressure_show(struct seq_file *seq, void *v)
{ {
struct cgroup *cgrp = seq_css(seq)->cgroup; struct cgroup *cgrp = seq_css(seq)->cgroup;
struct psi_group *psi = cgroup_id(cgrp) == 1 ? &psi_system : &cgrp->psi; struct psi_group *psi = cgroup_ino(cgrp) == 1 ? &psi_system : &cgrp->psi;
return psi_show(seq, psi, PSI_CPU); return psi_show(seq, psi, PSI_CPU);
} }
...@@ -4400,12 +4400,16 @@ static void css_task_iter_advance_css_set(struct css_task_iter *it) ...@@ -4400,12 +4400,16 @@ static void css_task_iter_advance_css_set(struct css_task_iter *it)
} }
} while (!css_set_populated(cset) && list_empty(&cset->dying_tasks)); } while (!css_set_populated(cset) && list_empty(&cset->dying_tasks));
if (!list_empty(&cset->tasks)) if (!list_empty(&cset->tasks)) {
it->task_pos = cset->tasks.next; it->task_pos = cset->tasks.next;
else if (!list_empty(&cset->mg_tasks)) it->cur_tasks_head = &cset->tasks;
} else if (!list_empty(&cset->mg_tasks)) {
it->task_pos = cset->mg_tasks.next; it->task_pos = cset->mg_tasks.next;
else it->cur_tasks_head = &cset->mg_tasks;
} else {
it->task_pos = cset->dying_tasks.next; it->task_pos = cset->dying_tasks.next;
it->cur_tasks_head = &cset->dying_tasks;
}
it->tasks_head = &cset->tasks; it->tasks_head = &cset->tasks;
it->mg_tasks_head = &cset->mg_tasks; it->mg_tasks_head = &cset->mg_tasks;
...@@ -4463,10 +4467,14 @@ static void css_task_iter_advance(struct css_task_iter *it) ...@@ -4463,10 +4467,14 @@ static void css_task_iter_advance(struct css_task_iter *it)
else else
it->task_pos = it->task_pos->next; it->task_pos = it->task_pos->next;
if (it->task_pos == it->tasks_head) if (it->task_pos == it->tasks_head) {
it->task_pos = it->mg_tasks_head->next; it->task_pos = it->mg_tasks_head->next;
if (it->task_pos == it->mg_tasks_head) it->cur_tasks_head = it->mg_tasks_head;
}
if (it->task_pos == it->mg_tasks_head) {
it->task_pos = it->dying_tasks_head->next; it->task_pos = it->dying_tasks_head->next;
it->cur_tasks_head = it->dying_tasks_head;
}
if (it->task_pos == it->dying_tasks_head) if (it->task_pos == it->dying_tasks_head)
css_task_iter_advance_css_set(it); css_task_iter_advance_css_set(it);
} else { } else {
...@@ -4485,11 +4493,12 @@ static void css_task_iter_advance(struct css_task_iter *it) ...@@ -4485,11 +4493,12 @@ static void css_task_iter_advance(struct css_task_iter *it)
goto repeat; goto repeat;
/* and dying leaders w/o live member threads */ /* and dying leaders w/o live member threads */
if (!atomic_read(&task->signal->live)) if (it->cur_tasks_head == it->dying_tasks_head &&
!atomic_read(&task->signal->live))
goto repeat; goto repeat;
} else { } else {
/* skip all dying ones */ /* skip all dying ones */
if (task->flags & PF_EXITING) if (it->cur_tasks_head == it->dying_tasks_head)
goto repeat; goto repeat;
} }
} }
...@@ -4595,6 +4604,9 @@ static void *cgroup_procs_next(struct seq_file *s, void *v, loff_t *pos) ...@@ -4595,6 +4604,9 @@ static void *cgroup_procs_next(struct seq_file *s, void *v, loff_t *pos)
struct kernfs_open_file *of = s->private; struct kernfs_open_file *of = s->private;
struct css_task_iter *it = of->priv; struct css_task_iter *it = of->priv;
if (pos)
(*pos)++;
return css_task_iter_next(it); return css_task_iter_next(it);
} }
...@@ -4610,7 +4622,7 @@ static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos, ...@@ -4610,7 +4622,7 @@ static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos,
* from position 0, so we can simply keep iterating on !0 *pos. * from position 0, so we can simply keep iterating on !0 *pos.
*/ */
if (!it) { if (!it) {
if (WARN_ON_ONCE((*pos)++)) if (WARN_ON_ONCE((*pos)))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
it = kzalloc(sizeof(*it), GFP_KERNEL); it = kzalloc(sizeof(*it), GFP_KERNEL);
...@@ -4618,10 +4630,11 @@ static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos, ...@@ -4618,10 +4630,11 @@ static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
of->priv = it; of->priv = it;
css_task_iter_start(&cgrp->self, iter_flags, it); css_task_iter_start(&cgrp->self, iter_flags, it);
} else if (!(*pos)++) { } else if (!(*pos)) {
css_task_iter_end(it); css_task_iter_end(it);
css_task_iter_start(&cgrp->self, iter_flags, it); css_task_iter_start(&cgrp->self, iter_flags, it);
} } else
return it->cur_task;
return cgroup_procs_next(s, NULL, NULL); return cgroup_procs_next(s, NULL, NULL);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment