Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp426264ybl; Fri, 24 Jan 2020 03:02:15 -0800 (PST) X-Google-Smtp-Source: APXvYqwENFUehVWMuDOwjyatonZSV/ayJknW6YKoryflS1a9cvhmoJMlMEncXgosrpsBP8H+nDTI X-Received: by 2002:a9d:7757:: with SMTP id t23mr2315639otl.315.1579863735373; Fri, 24 Jan 2020 03:02:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579863735; cv=none; d=google.com; s=arc-20160816; b=Uk+HFaMIjfnSmwFkLb/HlFvzgTfV4fo1k0bSp7dEqTW7UfbP4AdA1Wuaa3+jqxM1hR AZsSMJETD7IV8G/z0ytxMPzZhx+93ng5sRAGBtVTj8Eyuqp1JA5rTascEawov6YwGdDb rTDzan0F4xmWPTC0mlvqBNW4bEzzUcEobyDzP82/r1FdXOGDPKSrIsJQiQyEyAVgkroF WuHOaZN0mJqgCOFxHJiWQhgp2lvNBb416UnxUBak8dWO26/bKi1AG8EgzMbeOX749YAD 1VOitKCCoxc/R4N5AYEMLBuepXYwd6mJxHvs5wsSUjJuXjIcmtZq4eeD/qn9zviQVS8I F5Nw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=PX91zzZKE41Y5Z1YaqnxzUx5B8YWL+Rd9pdAPtnFoMg=; b=V2oOXu6Vv1YRkPQjGeonko3MMCAcYMV9CW1olnLCHEeljxGo4CYit2IhSBzMUTaZuZ 2KiJQuxKNcxMygLRCX6BPI8qufaRvSEcJsQq/eO1oOY0CZBNRPVoPBt9hqpCvwjH+3lX UZPNAFxqtDcIw+H0AJUYQb8P0LHh987r+PSD5MqIBV/DSDSrxdboKvAF37sAR89PzzxY ROFHa+3Gq6uQB99NeeuVakARQ4B6FE7N2ELEkokGVbZPLkql/OM4KeOCfKkmbRmFNlGK Vdz9O1QAbwyEpgCPyE22SRsELj28FyP2pTUjGc/fZTE/JVRJuFOafEuAhLeoGmx4IXgi hgtg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=RLBq39WE; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p62si2174635oig.101.2020.01.24.03.02.01; Fri, 24 Jan 2020 03:02:15 -0800 (PST) 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; dkim=pass header.i=@kernel.org header.s=default header.b=RLBq39WE; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733087AbgAXJly (ORCPT + 99 others); Fri, 24 Jan 2020 04:41:54 -0500 Received: from mail.kernel.org ([198.145.29.99]:39470 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731675AbgAXJlx (ORCPT ); Fri, 24 Jan 2020 04:41:53 -0500 Received: from localhost (unknown [145.15.244.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 70E9421556; Fri, 24 Jan 2020 09:41:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1579858912; bh=5KaAIMkJ6gMEzrwfSHsXucmw+DcKAeTRBjq9Y7V1UWQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RLBq39WEv6XWttUY18dSb152nYZOCyloDp+GyvcBnw9BAJ6n6UUFXbTmpdAS5UrwX jPTsk71CERXGluBi/shm2tQO/E5JjPdGgxE9KCLHiia3w8oshaeNhqvKfGTzN7Vicy OoSA3/pS7vwCoa0cmqAQVT+a+zLAF762RwlAep+A= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Doug Smythies , Vincent Guittot , "Peter Zijlstra (Intel)" , Dietmar Eggemann , "Rafael J. Wysocki" , Linus Torvalds , Thomas Gleixner , juri.lelli@redhat.com, linux-pm@vger.kernel.org, mgorman@suse.de, rostedt@goodmis.org, sargun@sargun.me, srinivas.pandruvada@linux.intel.com, tj@kernel.org, xiexiuqi@huawei.com, xiezhipeng1@huawei.com, Ingo Molnar , Sasha Levin Subject: [PATCH 5.4 089/102] sched/cpufreq: Move the cfs_rq_util_change() call to cpufreq_update_util() Date: Fri, 24 Jan 2020 10:31:30 +0100 Message-Id: <20200124092820.108025708@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200124092806.004582306@linuxfoundation.org> References: <20200124092806.004582306@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vincent Guittot [ Upstream commit bef69dd87828ef5d8ecdab8d857cd3a33cf98675 ] update_cfs_rq_load_avg() calls cfs_rq_util_change() every time PELT decays, which might be inefficient when the cpufreq driver has rate limitation. When a task is attached on a CPU, we have this call path: update_load_avg() update_cfs_rq_load_avg() cfs_rq_util_change -- > trig frequency update attach_entity_load_avg() cfs_rq_util_change -- > trig frequency update The 1st frequency update will not take into account the utilization of the newly attached task and the 2nd one might be discarded because of rate limitation of the cpufreq driver. update_cfs_rq_load_avg() is only called by update_blocked_averages() and update_load_avg() so we can move the call to cfs_rq_util_change/cpufreq_update_util() into these two functions. It's also interesting to note that update_load_avg() already calls cfs_rq_util_change() directly for the !SMP case. This change will also ensure that cpufreq_update_util() is called even when there is no more CFS rq in the leaf_cfs_rq_list to update, but only IRQ, RT or DL PELT signals. [ mingo: Minor updates. ] Reported-by: Doug Smythies Tested-by: Doug Smythies Signed-off-by: Vincent Guittot Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Dietmar Eggemann Acked-by: Rafael J. Wysocki Cc: Linus Torvalds Cc: Thomas Gleixner Cc: juri.lelli@redhat.com Cc: linux-pm@vger.kernel.org Cc: mgorman@suse.de Cc: rostedt@goodmis.org Cc: sargun@sargun.me Cc: srinivas.pandruvada@linux.intel.com Cc: tj@kernel.org Cc: xiexiuqi@huawei.com Cc: xiezhipeng1@huawei.com Fixes: 039ae8bcf7a5 ("sched/fair: Fix O(nr_cgroups) in the load balancing path") Link: https://lkml.kernel.org/r/1574083279-799-1-git-send-email-vincent.guittot@linaro.org Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- kernel/sched/fair.c | 111 +++++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 49 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 2b7034e6fa241..c87a798d14562 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3504,9 +3504,6 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq) cfs_rq->load_last_update_time_copy = sa->last_update_time; #endif - if (decayed) - cfs_rq_util_change(cfs_rq, 0); - return decayed; } @@ -3616,8 +3613,12 @@ static inline void update_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *s attach_entity_load_avg(cfs_rq, se, SCHED_CPUFREQ_MIGRATION); update_tg_load_avg(cfs_rq, 0); - } else if (decayed && (flags & UPDATE_TG)) - update_tg_load_avg(cfs_rq, 0); + } else if (decayed) { + cfs_rq_util_change(cfs_rq, 0); + + if (flags & UPDATE_TG) + update_tg_load_avg(cfs_rq, 0); + } } #ifndef CONFIG_64BIT @@ -7517,6 +7518,28 @@ static inline bool others_have_blocked(struct rq *rq) { return false; } static inline void update_blocked_load_status(struct rq *rq, bool has_blocked) {} #endif +static bool __update_blocked_others(struct rq *rq, bool *done) +{ + const struct sched_class *curr_class; + u64 now = rq_clock_pelt(rq); + bool decayed; + + /* + * update_load_avg() can call cpufreq_update_util(). Make sure that RT, + * DL and IRQ signals have been updated before updating CFS. + */ + curr_class = rq->curr->sched_class; + + decayed = update_rt_rq_load_avg(now, rq, curr_class == &rt_sched_class) | + update_dl_rq_load_avg(now, rq, curr_class == &dl_sched_class) | + update_irq_load_avg(rq, 0); + + if (others_have_blocked(rq)) + *done = false; + + return decayed; +} + #ifdef CONFIG_FAIR_GROUP_SCHED static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq) @@ -7536,29 +7559,11 @@ static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq) return true; } -static void update_blocked_averages(int cpu) +static bool __update_blocked_fair(struct rq *rq, bool *done) { - struct rq *rq = cpu_rq(cpu); struct cfs_rq *cfs_rq, *pos; - const struct sched_class *curr_class; - struct rq_flags rf; - bool done = true; - - rq_lock_irqsave(rq, &rf); - update_rq_clock(rq); - - /* - * update_cfs_rq_load_avg() can call cpufreq_update_util(). Make sure - * that RT, DL and IRQ signals have been updated before updating CFS. - */ - curr_class = rq->curr->sched_class; - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); - update_irq_load_avg(rq, 0); - - /* Don't need periodic decay once load/util_avg are null */ - if (others_have_blocked(rq)) - done = false; + bool decayed = false; + int cpu = cpu_of(rq); /* * Iterates the task_group tree in a bottom up fashion, see @@ -7567,9 +7572,13 @@ static void update_blocked_averages(int cpu) for_each_leaf_cfs_rq_safe(rq, cfs_rq, pos) { struct sched_entity *se; - if (update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq)) + if (update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq)) { update_tg_load_avg(cfs_rq, 0); + if (cfs_rq == &rq->cfs) + decayed = true; + } + /* Propagate pending load changes to the parent, if any: */ se = cfs_rq->tg->se[cpu]; if (se && !skip_blocked_update(se)) @@ -7584,11 +7593,10 @@ static void update_blocked_averages(int cpu) /* Don't need periodic decay once load/util_avg are null */ if (cfs_rq_has_blocked(cfs_rq)) - done = false; + *done = false; } - update_blocked_load_status(rq, !done); - rq_unlock_irqrestore(rq, &rf); + return decayed; } /* @@ -7638,29 +7646,16 @@ static unsigned long task_h_load(struct task_struct *p) cfs_rq_load_avg(cfs_rq) + 1); } #else -static inline void update_blocked_averages(int cpu) +static bool __update_blocked_fair(struct rq *rq, bool *done) { - struct rq *rq = cpu_rq(cpu); struct cfs_rq *cfs_rq = &rq->cfs; - const struct sched_class *curr_class; - struct rq_flags rf; - - rq_lock_irqsave(rq, &rf); - update_rq_clock(rq); - - /* - * update_cfs_rq_load_avg() can call cpufreq_update_util(). Make sure - * that RT, DL and IRQ signals have been updated before updating CFS. - */ - curr_class = rq->curr->sched_class; - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); - update_irq_load_avg(rq, 0); + bool decayed; - update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq); + decayed = update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq); + if (cfs_rq_has_blocked(cfs_rq)) + *done = false; - update_blocked_load_status(rq, cfs_rq_has_blocked(cfs_rq) || others_have_blocked(rq)); - rq_unlock_irqrestore(rq, &rf); + return decayed; } static unsigned long task_h_load(struct task_struct *p) @@ -7669,6 +7664,24 @@ static unsigned long task_h_load(struct task_struct *p) } #endif +static void update_blocked_averages(int cpu) +{ + bool decayed = false, done = true; + struct rq *rq = cpu_rq(cpu); + struct rq_flags rf; + + rq_lock_irqsave(rq, &rf); + update_rq_clock(rq); + + decayed |= __update_blocked_others(rq, &done); + decayed |= __update_blocked_fair(rq, &done); + + update_blocked_load_status(rq, !done); + if (decayed) + cpufreq_update_util(rq, 0); + rq_unlock_irqrestore(rq, &rf); +} + /********** Helpers for find_busiest_group ************************/ /* -- 2.20.1