Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp4362515imm; Mon, 15 Oct 2018 13:31:37 -0700 (PDT) X-Google-Smtp-Source: ACcGV61+C2mrSmRJNaakGR3VUOIpr1et12+OqkMp8Lsj6avLHAJI0O3el6aGx3UMnMEHLFULI8zZ X-Received: by 2002:a63:dd58:: with SMTP id g24-v6mr17052251pgj.86.1539635497187; Mon, 15 Oct 2018 13:31:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539635497; cv=none; d=google.com; s=arc-20160816; b=pgpBqOZMt8u/f64Hcrt4r/3mbT4Xi4JihbgqujMb9UgnluJJub/J1UiZLz4Hg0ON6r hW3TeipZd1GTC684zKOff1xYxUC9cxPAo0FmjAG7bERRRAX3RauQXX4lrAssZNKAQ4cS gXGBfZWYTo07pjZOtA8/wZ8X9YuDbQQKR0BYY5Lu+dMEB16VPPUzbMa4hXpieB9ZFRrq mW8Cn46W5PEycvTzJ24hCjUHgBUYuXD4rJN4Ex+Y4jj9zueictirUj17UnxG74vR+Nku UnCEqGHz8a+3Ns9GC6UWQEtvdKulsR65ibtBn4WMNEHJRnfdsUYZHmhxNDX3L46Mqb2x gXAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=LYlhcI4PAc5l1t6b10/vnpM+FQuxHYVrhtZshWB2QzQ=; b=b3OPOSJzKH1rNN6BPtZfpJZIg8Ke/JCYP0KwRjzzoHBoqKSKKvGp0vpkfKlo0jlEtz orVKDZHmI5zc1qcr8vRE+RzxGjGS+0Qc3UbpMkFodqlp382NQUxIKODNpYLghttSeBkA LLEahPAVT3uqrcZAwrXtV+UJsjpEzcHbGrNSB9f7s0gf01PxYTkIqDCEsGVOieO3huAD jw5u+hcXJl4wsPOkZ9OuDGxiCDOQLvOf3i+n09uLhLO9rjOhSWLDqQYy2MB4vlATJsMa t8Cyeeec8owNDtU6H1bCVRseGLmFwmzjTzmZ+CE56bS2H/fUeDT9ynkEud8uQ2ZTpMMn DFVw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q10-v6si10935564pls.344.2018.10.15.13.31.21; Mon, 15 Oct 2018 13:31:37 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727101AbeJPERa (ORCPT + 99 others); Tue, 16 Oct 2018 00:17:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41332 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725917AbeJPERa (ORCPT ); Tue, 16 Oct 2018 00:17:30 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 97EC15F72C; Mon, 15 Oct 2018 20:30:39 +0000 (UTC) Received: from llong.com (dhcp-17-8.bos.redhat.com [10.18.17.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id B55E3768B1; Mon, 15 Oct 2018 20:30:31 +0000 (UTC) From: Waiman Long To: Tejun Heo , Li Zefan , Johannes Weiner , Peter Zijlstra , Ingo Molnar Cc: cgroups@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, kernel-team@fb.com, pjt@google.com, luto@amacapital.net, Mike Galbraith , torvalds@linux-foundation.org, Roman Gushchin , Juri Lelli , Patrick Bellasi , Tom Hromatka , Waiman Long Subject: [PATCH v14 06/12] cpuset: Track cpusets that use parent's effective_cpus Date: Mon, 15 Oct 2018 16:29:31 -0400 Message-Id: <1539635377-22335-7-git-send-email-longman@redhat.com> In-Reply-To: <1539635377-22335-1-git-send-email-longman@redhat.com> References: <1539635377-22335-1-git-send-email-longman@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 15 Oct 2018 20:30:39 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In the default hierarchy, a cpuset will use the parent's effective_cpus if none of the requested CPUs can be granted from the parent. That can be a problem if a parent is a partition root with children partition roots. Changes to a parent's effective_cpus list due to changes in a child partition root may not be properly reflected in a child cpuset that use parent's effective_cpus because the cpu_exclusive rule of a partition root will not guard against that. In order to avoid the mismatch, two new tracking variables are added to the cpuset structure to track if a cpuset uses parent's effective_cpus and the number of children cpusets that use its effective_cpus. So whenever cpumask changes are made to a parent, it will also check to see if it has other children cpusets that use its effective_cpus and call update_cpumasks_hier() if that is the case. Signed-off-by: Waiman Long --- kernel/cgroup/cpuset.c | 71 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index a1f6fdb6be02..596e0b16fb96 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -147,6 +147,14 @@ struct cpuset { /* partition root state */ int partition_root_state; + + /* + * Default hierarchy only: + * use_parent_ecpus - set if using parent's effective_cpus + * child_ecpus_count - # of children with use_parent_ecpus set + */ + int use_parent_ecpus; + int child_ecpus_count; }; /* @@ -1227,8 +1235,17 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp) * If it becomes empty, inherit the effective mask of the * parent, which is guaranteed to have some CPUs. */ - if (is_in_v2_mode() && cpumask_empty(tmp->new_cpus)) + if (is_in_v2_mode() && cpumask_empty(tmp->new_cpus)) { cpumask_copy(tmp->new_cpus, parent->effective_cpus); + if (!cp->use_parent_ecpus) { + cp->use_parent_ecpus = true; + parent->child_ecpus_count++; + } + } else if (cp->use_parent_ecpus) { + cp->use_parent_ecpus = false; + WARN_ON_ONCE(!parent->child_ecpus_count); + parent->child_ecpus_count--; + } /* * Skip the whole subtree if the cpumask remains the same @@ -1340,6 +1357,35 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp) rebuild_sched_domains_locked(); } +/** + * update_sibling_cpumasks - Update siblings cpumasks + * @parent: Parent cpuset + * @cs: Current cpuset + * @tmp: Temp variables + */ +static void update_sibling_cpumasks(struct cpuset *parent, struct cpuset *cs, + struct tmpmasks *tmp) +{ + struct cpuset *sibling; + struct cgroup_subsys_state *pos_css; + + /* + * Check all its siblings and call update_cpumasks_hier() + * if their use_parent_ecpus flag is set in order for them + * to use the right effective_cpus value. + */ + rcu_read_lock(); + cpuset_for_each_child(sibling, pos_css, parent) { + if (sibling == cs) + continue; + if (!sibling->use_parent_ecpus) + continue; + + update_cpumasks_hier(sibling, tmp); + } + rcu_read_unlock(); +} + /** * update_cpumask - update the cpus_allowed mask of a cpuset and all tasks in it * @cs: the cpuset to consider @@ -1415,6 +1461,17 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, spin_unlock_irq(&callback_lock); update_cpumasks_hier(cs, &tmp); + + if (cs->partition_root_state) { + struct cpuset *parent = parent_cs(cs); + + /* + * For partition root, update the cpumasks of sibling + * cpusets if they use parent's effective_cpus. + */ + if (parent->child_ecpus_count) + update_sibling_cpumasks(parent, cs, &tmp); + } return 0; } @@ -1851,6 +1908,9 @@ static int update_prstate(struct cpuset *cs, int val) if (parent != &top_cpuset) update_tasks_cpumask(parent); + if (parent->child_ecpus_count) + update_sibling_cpumasks(parent, cs, &tmp); + rebuild_sched_domains_locked(); out: free_cpumasks(NULL, &tmp); @@ -2545,6 +2605,8 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) if (is_in_v2_mode()) { cpumask_copy(cs->effective_cpus, parent->effective_cpus); cs->effective_mems = parent->effective_mems; + cs->use_parent_ecpus = true; + parent->child_ecpus_count++; } spin_unlock_irq(&callback_lock); @@ -2608,6 +2670,13 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css) is_sched_load_balance(cs)) update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); + if (cs->use_parent_ecpus) { + struct cpuset *parent = parent_cs(cs); + + cs->use_parent_ecpus = false; + parent->child_ecpus_count--; + } + cpuset_dec(); clear_bit(CS_ONLINE, &cs->flags); -- 2.18.0