Skip to content

Commit

Permalink
Merge branch 'for-5.3-fixes' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/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
  • Loading branch information
Linus Torvalds committed Sep 13, 2019
2 parents 1b304a1 + 97a6136 commit a7f8961
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
10 changes: 9 additions & 1 deletion kernel/cgroup/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -5255,8 +5255,16 @@ static struct cgroup *cgroup_create(struct cgroup *parent)
* if the parent has to be frozen, the child has too.
*/
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);
}

spin_lock_irq(&css_set_lock);
for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) {
Expand Down
54 changes: 54 additions & 0 deletions tools/testing/selftests/cgroup/test_freezer.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,59 @@ static int test_cgfreezer_forkbomb(const char *root)
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
* and removes the child. Then it checks that the parent cgroup
Expand Down Expand Up @@ -815,6 +868,7 @@ struct cgfreezer_test {
T(test_cgfreezer_simple),
T(test_cgfreezer_tree),
T(test_cgfreezer_forkbomb),
T(test_cgfreezer_mkdir),
T(test_cgfreezer_rmdir),
T(test_cgfreezer_migrate),
T(test_cgfreezer_ptrace),
Expand Down

0 comments on commit a7f8961

Please sign in to comment.