Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755862AbcCaD7z (ORCPT ); Wed, 30 Mar 2016 23:59:55 -0400 Received: from mga09.intel.com ([134.134.136.24]:43861 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751041AbcCaD7v (ORCPT ); Wed, 30 Mar 2016 23:59:51 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,420,1455004800"; d="scan'208";a="76319580" From: Yuyang Du To: peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org Cc: bsegall@google.com, pjt@google.com, morten.rasmussen@arm.com, vincent.guittot@linaro.org, dietmar.eggemann@arm.com, lizefan@huawei.com, umgwanakikbuti@gmail.com, Yuyang Du Subject: [PATCH RESEND v2 1/6] sched/fair: Generalize the load/util averages resolution definition Date: Thu, 31 Mar 2016 04:16:50 +0800 Message-Id: <1459369015-28375-2-git-send-email-yuyang.du@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1459369015-28375-1-git-send-email-yuyang.du@intel.com> References: <1459369015-28375-1-git-send-email-yuyang.du@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4184 Lines: 109 Integer metric needs fixed point arithmetic. In sched/fair, a few metrics, e.g., weight, load, load_avg, util_avg, freq, and capacity, may have different fixed point ranges, which makes their update and usage error-prone. In order to avoid the errors relating to the fixed point range, we definie a basic fixed point range, and then formalize all metrics to base on the basic range. The basic range is 1024 or (1 << 10). Further, one can recursively apply the basic range to have larger range. Pointed out by Ben Segall, weight (visible to user, e.g., NICE-0 has 1024) and load (e.g., NICE_0_LOAD) have independent ranges, but they must be well calibrated. Signed-off-by: Yuyang Du --- include/linux/sched.h | 16 +++++++++++++--- kernel/sched/fair.c | 4 ---- kernel/sched/sched.h | 15 ++++++++++----- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index c617ea1..54784d0 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -934,9 +934,19 @@ enum cpu_idle_type { }; /* + * Integer metrics need fixed point arithmetic, e.g., sched/fair + * has a few: load, load_avg, util_avg, freq, and capacity. + * + * We define a basic fixed point arithmetic range, and then formalize + * all these metrics based on that basic range. + */ +# define SCHED_FIXEDPOINT_SHIFT 10 +# define SCHED_FIXEDPOINT_SCALE (1L << SCHED_FIXEDPOINT_SHIFT) + +/* * Increase resolution of cpu_capacity calculations */ -#define SCHED_CAPACITY_SHIFT 10 +#define SCHED_CAPACITY_SHIFT SCHED_FIXEDPOINT_SHIFT #define SCHED_CAPACITY_SCALE (1L << SCHED_CAPACITY_SHIFT) /* @@ -1202,8 +1212,8 @@ struct load_weight { * 1) load_avg factors frequency scaling into the amount of time that a * sched_entity is runnable on a rq into its weight. For cfs_rq, it is the * aggregated such weights of all runnable and blocked sched_entities. - * 2) util_avg factors frequency and cpu scaling into the amount of time - * that a sched_entity is running on a CPU, in the range [0..SCHED_LOAD_SCALE]. + * 2) util_avg factors frequency and cpu capacity scaling into the amount of time + * that a sched_entity is running on a CPU, in the range [0..SCHED_CAPACITY_SCALE]. * For cfs_rq, it is the aggregated such times of all runnable and * blocked sched_entities. * The 64 bit load_sum can: diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 303d639..1d3fc01 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2609,10 +2609,6 @@ static u32 __compute_runnable_contrib(u64 n) return contrib + runnable_avg_yN_sum[n]; } -#if (SCHED_LOAD_SHIFT - SCHED_LOAD_RESOLUTION) != 10 || SCHED_CAPACITY_SHIFT != 10 -#error "load tracking assumes 2^10 as unit" -#endif - #define cap_scale(v, s) ((v)*(s) >> SCHED_CAPACITY_SHIFT) /* diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index e6d4a3f..15a89ee 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -54,18 +54,23 @@ static inline void update_cpu_load_active(struct rq *this_rq) { } * increased costs. */ #if 0 /* BITS_PER_LONG > 32 -- currently broken: it increases power usage under light load */ -# define SCHED_LOAD_RESOLUTION 10 -# define scale_load(w) ((w) << SCHED_LOAD_RESOLUTION) -# define scale_load_down(w) ((w) >> SCHED_LOAD_RESOLUTION) +# define SCHED_LOAD_SHIFT (SCHED_FIXEDPOINT_SHIFT + SCHED_FIXEDPOINT_SHIFT) +# define scale_load(w) ((w) << SCHED_FIXEDPOINT_SHIFT) +# define scale_load_down(w) ((w) >> SCHED_FIXEDPOINT_SHIFT) #else -# define SCHED_LOAD_RESOLUTION 0 +# define SCHED_LOAD_SHIFT (SCHED_FIXEDPOINT_SHIFT) # define scale_load(w) (w) # define scale_load_down(w) (w) #endif -#define SCHED_LOAD_SHIFT (10 + SCHED_LOAD_RESOLUTION) #define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT) +/* + * NICE_0's weight (visible to user) and its load (invisible to user) have + * independent ranges, but they should be well calibrated. We use scale_load() + * and scale_load_down(w) to convert between them, the following must be true: + * scale_load(sched_prio_to_weight[20]) == NICE_0_LOAD + */ #define NICE_0_LOAD SCHED_LOAD_SCALE #define NICE_0_SHIFT SCHED_LOAD_SHIFT -- 2.1.4