Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S942030AbcJ0Rla (ORCPT ); Thu, 27 Oct 2016 13:41:30 -0400 Received: from foss.arm.com ([217.140.101.70]:43276 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S938452AbcJ0RlY (ORCPT ); Thu, 27 Oct 2016 13:41:24 -0400 From: Patrick Bellasi To: linux-kernel@vger.kernel.org Cc: Ingo Molnar , Peter Zijlstra , Vincent Guittot , Steve Muckle , Leo Yan , Viresh Kumar , "Rafael J . Wysocki" , Todd Kjos , Srinath Sridharan , Andres Oportus , Juri Lelli , Morten Rasmussen , Dietmar Eggemann , Chris Redpath , Robin Randhawa , Patrick Bellasi Subject: [RFC v2 3/8] sched/fair: add function to convert boost value into "margin" Date: Thu, 27 Oct 2016 18:41:03 +0100 Message-Id: <20161027174108.31139-4-patrick.bellasi@arm.com> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20161027174108.31139-1-patrick.bellasi@arm.com> References: <20161027174108.31139-1-patrick.bellasi@arm.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4416 Lines: 148 The basic idea of the boost knob is to "artificially inflate" a signal to make a task (or CPU) appears more demanding than what actually it is. Independently from the specific signal, a consistent and possibly simple semantic for the concept of "signal boosting" must define: 1. how we translate a boost percentage into a "margin" value, to be added to the original signal we want to inflate 2. what is the meaning of a boost value from a user-space perspective This patch provides the implementation of a possible boost semantic, namely "Signal Proportional Compensation" (SPC), where the "Boost Percentage" (BP) is used to compute a "Margin" (M) which is proportional to the complement of the "Original Signal" (OS): M = BP * (SCHED_CAPACITY_SCALE - OS) The computed margin can added to the OS to obtain a "Boosted Signal" (BS) BS = OS + M The proposed boost semantic has these main features: - each signal gets a boost which is proportional to its delta with respect to the maximum available capacity in the system, i.e. SCHED_CAPACITY_SCALE - a 100% boosting has a clear understanding from a user-space perspective, it means to run (possibly) "all" tasks at the maximum OPP - each boosting value means to speedup the task by a quantity which is proportional to the maximum speedup achievable by that task on that system Thus this semantics is somehow forcing a behaviour which is: 50% boosting means to run at half-way between the current and the maximum performance which a task could achieve on that system NOTE: this code is suitable for all signals operating in range [0..SCHED_CAPACITY_SCALE] Cc: Ingo Molnar Cc: Peter Zijlstra Signed-off-by: Patrick Bellasi --- kernel/sched/fair.c | 37 +++++++++++++++++++++++++++++++++++++ kernel/sched/tune.c | 9 +++++++++ kernel/sched/tune.h | 13 +++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 kernel/sched/tune.h diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 79d464a..fdacc29 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -34,6 +34,7 @@ #include #include "sched.h" +#include "tune.h" /* * Targeted preemption latency for CPU-bound tasks: @@ -5543,6 +5544,42 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) return target; } +#ifdef CONFIG_SCHED_TUNE + +struct reciprocal_value schedtune_spc_rdiv; + +/* + * schedtune_margin returns the "margin" to be added on top of + * the original value of a "signal". + * + * The Boost (B) value [%] is used to compute a Margin (M) which + * is proportional to the complement of the original Signal (S): + * + * M = B * (SCHED_CAPACITY_SCALE - S) + * + * The obtained value M could be used by the caller to "boost" S. + */ +static unsigned long +schedtune_margin(unsigned long signal, unsigned int boost) +{ + unsigned long long margin = 0; + + /* Do not boost saturated signals */ + if (signal >= SCHED_CAPACITY_SCALE) + return 0UL; + + /* Signal Proportional Compensation (SPC) */ + margin = SCHED_CAPACITY_SCALE - signal; + if (boost < 100) { + margin *= boost; + margin = reciprocal_divide(margin, schedtune_spc_rdiv); + } + + return margin; +} + +#endif /* CONFIG_SCHED_TUNE */ + /* * cpu_util returns the amount of capacity of a CPU that is used by CFS * tasks. The unit of the return value must be the one of capacity so we can diff --git a/kernel/sched/tune.c b/kernel/sched/tune.c index 7336118..c28a06f 100644 --- a/kernel/sched/tune.c +++ b/kernel/sched/tune.c @@ -5,6 +5,7 @@ */ #include "sched.h" +#include "tune.h" unsigned int sysctl_sched_cfs_boost __read_mostly; @@ -21,3 +22,11 @@ sysctl_sched_cfs_boost_handler(struct ctl_table *table, int write, return 0; } +static int +schedtune_init(void) +{ + schedtune_spc_rdiv = reciprocal_value(100); + return 0; +} +late_initcall(schedtune_init); + diff --git a/kernel/sched/tune.h b/kernel/sched/tune.h new file mode 100644 index 0000000..515d02a --- /dev/null +++ b/kernel/sched/tune.h @@ -0,0 +1,13 @@ +/* + * Scheduler Tunability (SchedTune) Extensions for CFS + * + * Copyright (C) 2016 ARM Ltd, Patrick Bellasi + */ + +#ifdef CONFIG_SCHED_TUNE + +#include + +extern struct reciprocal_value schedtune_spc_rdiv; + +#endif /* CONFIG_SCHED_TUNE */ -- 2.10.1