Skip to content

Commit e941484

Browse files
committed
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
2 parents 2c1aca4 + 2e5383d commit e941484

File tree

3 files changed

+29
-14
lines changed

3 files changed

+29
-14
lines changed

include/linux/cgroup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct css_task_iter {
6262
struct list_head *mg_tasks_head;
6363
struct list_head *dying_tasks_head;
6464

65+
struct list_head *cur_tasks_head;
6566
struct css_set *cur_cset;
6667
struct css_set *cur_dcset;
6768
struct task_struct *cur_task;

kernel/cgroup/cgroup-v1.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos)
471471
*/
472472
p++;
473473
if (p >= end) {
474+
(*pos)++;
474475
return NULL;
475476
} else {
476477
*pos = *p;
@@ -782,7 +783,7 @@ void cgroup1_release_agent(struct work_struct *work)
782783

783784
pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
784785
agentbuf = kstrdup(cgrp->root->release_agent_path, GFP_KERNEL);
785-
if (!pathbuf || !agentbuf)
786+
if (!pathbuf || !agentbuf || !strlen(agentbuf))
786787
goto out;
787788

788789
spin_lock_irq(&css_set_lock);

kernel/cgroup/cgroup.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3542,21 +3542,21 @@ static int cpu_stat_show(struct seq_file *seq, void *v)
35423542
static int cgroup_io_pressure_show(struct seq_file *seq, void *v)
35433543
{
35443544
struct cgroup *cgrp = seq_css(seq)->cgroup;
3545-
struct psi_group *psi = cgroup_id(cgrp) == 1 ? &psi_system : &cgrp->psi;
3545+
struct psi_group *psi = cgroup_ino(cgrp) == 1 ? &psi_system : &cgrp->psi;
35463546

35473547
return psi_show(seq, psi, PSI_IO);
35483548
}
35493549
static int cgroup_memory_pressure_show(struct seq_file *seq, void *v)
35503550
{
35513551
struct cgroup *cgrp = seq_css(seq)->cgroup;
3552-
struct psi_group *psi = cgroup_id(cgrp) == 1 ? &psi_system : &cgrp->psi;
3552+
struct psi_group *psi = cgroup_ino(cgrp) == 1 ? &psi_system : &cgrp->psi;
35533553

35543554
return psi_show(seq, psi, PSI_MEM);
35553555
}
35563556
static int cgroup_cpu_pressure_show(struct seq_file *seq, void *v)
35573557
{
35583558
struct cgroup *cgrp = seq_css(seq)->cgroup;
3559-
struct psi_group *psi = cgroup_id(cgrp) == 1 ? &psi_system : &cgrp->psi;
3559+
struct psi_group *psi = cgroup_ino(cgrp) == 1 ? &psi_system : &cgrp->psi;
35603560

35613561
return psi_show(seq, psi, PSI_CPU);
35623562
}
@@ -4400,12 +4400,16 @@ static void css_task_iter_advance_css_set(struct css_task_iter *it)
44004400
}
44014401
} while (!css_set_populated(cset) && list_empty(&cset->dying_tasks));
44024402

4403-
if (!list_empty(&cset->tasks))
4403+
if (!list_empty(&cset->tasks)) {
44044404
it->task_pos = cset->tasks.next;
4405-
else if (!list_empty(&cset->mg_tasks))
4405+
it->cur_tasks_head = &cset->tasks;
4406+
} else if (!list_empty(&cset->mg_tasks)) {
44064407
it->task_pos = cset->mg_tasks.next;
4407-
else
4408+
it->cur_tasks_head = &cset->mg_tasks;
4409+
} else {
44084410
it->task_pos = cset->dying_tasks.next;
4411+
it->cur_tasks_head = &cset->dying_tasks;
4412+
}
44094413

44104414
it->tasks_head = &cset->tasks;
44114415
it->mg_tasks_head = &cset->mg_tasks;
@@ -4463,10 +4467,14 @@ static void css_task_iter_advance(struct css_task_iter *it)
44634467
else
44644468
it->task_pos = it->task_pos->next;
44654469

4466-
if (it->task_pos == it->tasks_head)
4470+
if (it->task_pos == it->tasks_head) {
44674471
it->task_pos = it->mg_tasks_head->next;
4468-
if (it->task_pos == it->mg_tasks_head)
4472+
it->cur_tasks_head = it->mg_tasks_head;
4473+
}
4474+
if (it->task_pos == it->mg_tasks_head) {
44694475
it->task_pos = it->dying_tasks_head->next;
4476+
it->cur_tasks_head = it->dying_tasks_head;
4477+
}
44704478
if (it->task_pos == it->dying_tasks_head)
44714479
css_task_iter_advance_css_set(it);
44724480
} else {
@@ -4485,11 +4493,12 @@ static void css_task_iter_advance(struct css_task_iter *it)
44854493
goto repeat;
44864494

44874495
/* and dying leaders w/o live member threads */
4488-
if (!atomic_read(&task->signal->live))
4496+
if (it->cur_tasks_head == it->dying_tasks_head &&
4497+
!atomic_read(&task->signal->live))
44894498
goto repeat;
44904499
} else {
44914500
/* skip all dying ones */
4492-
if (task->flags & PF_EXITING)
4501+
if (it->cur_tasks_head == it->dying_tasks_head)
44934502
goto repeat;
44944503
}
44954504
}
@@ -4595,6 +4604,9 @@ static void *cgroup_procs_next(struct seq_file *s, void *v, loff_t *pos)
45954604
struct kernfs_open_file *of = s->private;
45964605
struct css_task_iter *it = of->priv;
45974606

4607+
if (pos)
4608+
(*pos)++;
4609+
45984610
return css_task_iter_next(it);
45994611
}
46004612

@@ -4610,18 +4622,19 @@ static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos,
46104622
* from position 0, so we can simply keep iterating on !0 *pos.
46114623
*/
46124624
if (!it) {
4613-
if (WARN_ON_ONCE((*pos)++))
4625+
if (WARN_ON_ONCE((*pos)))
46144626
return ERR_PTR(-EINVAL);
46154627

46164628
it = kzalloc(sizeof(*it), GFP_KERNEL);
46174629
if (!it)
46184630
return ERR_PTR(-ENOMEM);
46194631
of->priv = it;
46204632
css_task_iter_start(&cgrp->self, iter_flags, it);
4621-
} else if (!(*pos)++) {
4633+
} else if (!(*pos)) {
46224634
css_task_iter_end(it);
46234635
css_task_iter_start(&cgrp->self, iter_flags, it);
4624-
}
4636+
} else
4637+
return it->cur_task;
46254638

46264639
return cgroup_procs_next(s, NULL, NULL);
46274640
}

0 commit comments

Comments
 (0)