[RHEL7,COMMIT] cpuset/cpus: don't propagate changes to empty descendant cgroups

Submitted by Konstantin Khorenko on May 31, 2018, 4:13 p.m.

Details

Message ID 201805311613.w4VGDfSW015515@finist_ce7.work
State New
Series "cpuset/mems: don't propagate changes to empty descendant cgroups"
Headers show

Commit Message

Konstantin Khorenko May 31, 2018, 4:13 p.m.
The commit is pushed to "branch-rh7-3.10.0-862.vz7.48.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.el7
------>
commit 765ff2f6ad512f35b7d658e6f3a0d8334da8b7fa
Author: Konstantin Khorenko <khorenko@virtuozzo.com>
Date:   Thu May 31 18:47:33 2018 +0300

    cpuset/cpus: don't propagate changes to empty descendant cgroups
    
    When we configure cpuset::cpus for a cgroup, we scan and update
    descendant cgroups as well not allowing them to have wider
    cpu mask than the parent's one.
    
    But if we face an empty (not configured yet) cpuset cgroup,
    1) we should not complain via WARN_ON
    2) we better leave the configuration as is, not setting cpus
       from parent.
       Userspace has to configure cpuset cgroup anyway before putting
       tasks inside, so no reasons for propagation.
    
    https://jira.sw.ru/browse/PSBM-85052
    
    Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 kernel/cpuset.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 7fe31171fa0e..c3c7859a049c 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -976,8 +976,19 @@  static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus,
 		if (cpumask_empty(new_cpus))
 			cpumask_copy(new_cpus, parent->effective_cpus);
 
-		/* skip the whole subtree if the cpumask remains the same. */
-		if (cpumask_equal(new_cpus, cp->effective_cpus)) {
+		/*
+		 * Skip the whole subtree if the cpumask remains the same
+		 * or existing cpumask is empty, for example:
+		 * - cpuset/machine.slice has zero cpumask before first CT start
+		 * - we create cpuset/machine.slice/$CTID cpuset cgroup
+		 *   (with zero cpumask)
+		 * - we set non-zero cpumask to cpuset/machine.slice
+		 *   (otherwise we can't configure cpuset for CT)
+		 * - and now we don't want to change empty cpumask for
+		 *   cpuset/machine.slice/$CTID
+		 */
+		if (cpumask_equal(new_cpus, cp->effective_cpus) ||
+		    cpumask_empty(cp->cpus_allowed)) {
 			pos_cgrp = cgroup_rightmost_descendant(pos_cgrp);
 			continue;
 		}