Merge branch 'for-5.3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup fix from Tejun Heo: "Roman found and fixed a bug in the cgroup2 freezer which allows new child cgroup to escape frozen state" * 'for-5.3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: cgroup: freezer: fix frozen state inheritance kselftests: cgroup: add freezer mkdir test
This commit is contained in:
commit
a7f89616b7
|
@ -5255,8 +5255,16 @@ static struct cgroup *cgroup_create(struct cgroup *parent)
|
||||||
* if the parent has to be frozen, the child has too.
|
* if the parent has to be frozen, the child has too.
|
||||||
*/
|
*/
|
||||||
cgrp->freezer.e_freeze = parent->freezer.e_freeze;
|
cgrp->freezer.e_freeze = parent->freezer.e_freeze;
|
||||||
if (cgrp->freezer.e_freeze)
|
if (cgrp->freezer.e_freeze) {
|
||||||
|
/*
|
||||||
|
* Set the CGRP_FREEZE flag, so when a process will be
|
||||||
|
* attached to the child cgroup, it will become frozen.
|
||||||
|
* At this point the new cgroup is unpopulated, so we can
|
||||||
|
* consider it frozen immediately.
|
||||||
|
*/
|
||||||
|
set_bit(CGRP_FREEZE, &cgrp->flags);
|
||||||
set_bit(CGRP_FROZEN, &cgrp->flags);
|
set_bit(CGRP_FROZEN, &cgrp->flags);
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irq(&css_set_lock);
|
spin_lock_irq(&css_set_lock);
|
||||||
for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) {
|
for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) {
|
||||||
|
|
|
@ -447,6 +447,59 @@ cleanup:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The test creates a cgroups and freezes it. Then it creates a child cgroup
|
||||||
|
* and populates it with a task. After that it checks that the child cgroup
|
||||||
|
* is frozen and the parent cgroup remains frozen too.
|
||||||
|
*/
|
||||||
|
static int test_cgfreezer_mkdir(const char *root)
|
||||||
|
{
|
||||||
|
int ret = KSFT_FAIL;
|
||||||
|
char *parent, *child = NULL;
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
parent = cg_name(root, "cg_test_mkdir_A");
|
||||||
|
if (!parent)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
child = cg_name(parent, "cg_test_mkdir_B");
|
||||||
|
if (!child)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (cg_create(parent))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (cg_freeze_wait(parent, true))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (cg_create(child))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
pid = cg_run_nowait(child, child_fn, NULL);
|
||||||
|
if (pid < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (cg_wait_for_proc_count(child, 1))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (cg_check_frozen(child, true))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (cg_check_frozen(parent, true))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = KSFT_PASS;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (child)
|
||||||
|
cg_destroy(child);
|
||||||
|
free(child);
|
||||||
|
if (parent)
|
||||||
|
cg_destroy(parent);
|
||||||
|
free(parent);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The test creates two nested cgroups, freezes the parent
|
* The test creates two nested cgroups, freezes the parent
|
||||||
* and removes the child. Then it checks that the parent cgroup
|
* and removes the child. Then it checks that the parent cgroup
|
||||||
|
@ -815,6 +868,7 @@ struct cgfreezer_test {
|
||||||
T(test_cgfreezer_simple),
|
T(test_cgfreezer_simple),
|
||||||
T(test_cgfreezer_tree),
|
T(test_cgfreezer_tree),
|
||||||
T(test_cgfreezer_forkbomb),
|
T(test_cgfreezer_forkbomb),
|
||||||
|
T(test_cgfreezer_mkdir),
|
||||||
T(test_cgfreezer_rmdir),
|
T(test_cgfreezer_rmdir),
|
||||||
T(test_cgfreezer_migrate),
|
T(test_cgfreezer_migrate),
|
||||||
T(test_cgfreezer_ptrace),
|
T(test_cgfreezer_ptrace),
|
||||||
|
|
Loading…
Reference in New Issue