FIX: sched/tune: move schedtune_nornalize_energy into fair.c
The energy normalization function is required to get the proper values for the P-E space filtering function to work. That normalization is part of the hot wakeup path and currently implemented with a function call. Moving the normalization function into fair.c allows the compiler to further optimize that code by reducing overheads in the wakeup hot path. Signed-off-by: Patrick Bellasi <patrick.bellasi@arm.com> [jstultz: fwdported to 4.4] Signed-off-by: John Stultz <john.stultz@linaro.org>
This commit is contained in:
committed by
John Stultz
parent
28e8cb961c
commit
6ba071d89d
@@ -4975,44 +4975,6 @@ static inline bool cpu_in_sg(struct sched_group *sg, int cpu)
|
||||
return cpu != -1 && cpumask_test_cpu(cpu, sched_group_cpus(sg));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCHED_TUNE
|
||||
static int energy_diff_evaluate(struct energy_env *eenv)
|
||||
{
|
||||
unsigned int boost;
|
||||
int nrg_delta;
|
||||
|
||||
/* Return energy diff when boost margin is 0 */
|
||||
#ifdef CONFIG_CGROUP_SCHEDTUNE
|
||||
boost = schedtune_task_boost(eenv->task);
|
||||
#else
|
||||
boost = get_sysctl_sched_cfs_boost();
|
||||
#endif
|
||||
if (boost == 0)
|
||||
return eenv->nrg.diff;
|
||||
|
||||
/* Compute normalized energy diff */
|
||||
nrg_delta = schedtune_normalize_energy(eenv->nrg.diff);
|
||||
eenv->nrg.delta = nrg_delta;
|
||||
|
||||
eenv->payoff = schedtune_accept_deltas(
|
||||
eenv->nrg.delta,
|
||||
eenv->cap.delta,
|
||||
eenv->task);
|
||||
|
||||
/*
|
||||
* When SchedTune is enabled, the energy_diff() function will return
|
||||
* the computed energy payoff value. Since the energy_diff() return
|
||||
* value is expected to be negative by its callers, this evaluation
|
||||
* function return a negative value each time the evaluation return a
|
||||
* positive payoff, which is the condition for the acceptance of
|
||||
* a scheduling decision
|
||||
*/
|
||||
return -eenv->payoff;
|
||||
}
|
||||
#else /* CONFIG_SCHED_TUNE */
|
||||
#define energy_diff_evaluate(eenv) eenv->nrg.diff
|
||||
#endif
|
||||
|
||||
/*
|
||||
* energy_diff(): Estimate the energy impact of changing the utilization
|
||||
* distribution. eenv specifies the change: utilisation amount, source, and
|
||||
@@ -5020,12 +4982,11 @@ static int energy_diff_evaluate(struct energy_env *eenv)
|
||||
* utilization is removed from or added to the system (e.g. task wake-up). If
|
||||
* both are specified, the utilization is migrated.
|
||||
*/
|
||||
static int energy_diff(struct energy_env *eenv)
|
||||
static inline int __energy_diff(struct energy_env *eenv)
|
||||
{
|
||||
struct sched_domain *sd;
|
||||
struct sched_group *sg;
|
||||
int sd_cpu = -1, energy_before = 0, energy_after = 0;
|
||||
int result;
|
||||
|
||||
struct energy_env eenv_before = {
|
||||
.util_delta = 0,
|
||||
@@ -5069,17 +5030,91 @@ static int energy_diff(struct energy_env *eenv)
|
||||
eenv->nrg.diff = eenv->nrg.after - eenv->nrg.before;
|
||||
eenv->payoff = 0;
|
||||
|
||||
result = energy_diff_evaluate(eenv);
|
||||
|
||||
trace_sched_energy_diff(eenv->task,
|
||||
eenv->src_cpu, eenv->dst_cpu, eenv->util_delta,
|
||||
eenv->nrg.before, eenv->nrg.after, eenv->nrg.diff,
|
||||
eenv->cap.before, eenv->cap.after, eenv->cap.delta,
|
||||
eenv->nrg.delta, eenv->payoff);
|
||||
|
||||
return result;
|
||||
return eenv->nrg.diff;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCHED_TUNE
|
||||
|
||||
struct target_nrg schedtune_target_nrg;
|
||||
|
||||
/*
|
||||
* System energy normalization
|
||||
* Returns the normalized value, in the range [0..SCHED_LOAD_SCALE],
|
||||
* corresponding to the specified energy variation.
|
||||
*/
|
||||
static inline int
|
||||
normalize_energy(int energy_diff)
|
||||
{
|
||||
u32 normalized_nrg;
|
||||
#ifdef CONFIG_SCHED_DEBUG
|
||||
int max_delta;
|
||||
|
||||
/* Check for boundaries */
|
||||
max_delta = schedtune_target_nrg.max_power;
|
||||
max_delta -= schedtune_target_nrg.min_power;
|
||||
WARN_ON(abs(energy_diff) >= max_delta);
|
||||
#endif
|
||||
|
||||
/* Do scaling using positive numbers to increase the range */
|
||||
normalized_nrg = (energy_diff < 0) ? -energy_diff : energy_diff;
|
||||
|
||||
/* Scale by energy magnitude */
|
||||
normalized_nrg <<= SCHED_LOAD_SHIFT;
|
||||
|
||||
/* Normalize on max energy for target platform */
|
||||
normalized_nrg = reciprocal_divide(
|
||||
normalized_nrg, schedtune_target_nrg.rdiv);
|
||||
|
||||
return (energy_diff < 0) ? -normalized_nrg : normalized_nrg;
|
||||
}
|
||||
|
||||
static inline int
|
||||
energy_diff(struct energy_env *eenv)
|
||||
{
|
||||
unsigned int boost;
|
||||
int nrg_delta;
|
||||
|
||||
/* Conpute "absolute" energy diff */
|
||||
__energy_diff(eenv);
|
||||
|
||||
/* Return energy diff when boost margin is 0 */
|
||||
#ifdef CONFIG_CGROUP_SCHEDTUNE
|
||||
boost = schedtune_task_boost(eenv->task);
|
||||
#else
|
||||
boost = get_sysctl_sched_cfs_boost();
|
||||
#endif
|
||||
if (boost == 0)
|
||||
return eenv->nrg.diff;
|
||||
|
||||
/* Compute normalized energy diff */
|
||||
nrg_delta = normalize_energy(eenv->nrg.diff);
|
||||
eenv->nrg.delta = nrg_delta;
|
||||
|
||||
eenv->payoff = schedtune_accept_deltas(
|
||||
eenv->nrg.delta,
|
||||
eenv->cap.delta,
|
||||
eenv->task);
|
||||
|
||||
/*
|
||||
* When SchedTune is enabled, the energy_diff() function will return
|
||||
* the computed energy payoff value. Since the energy_diff() return
|
||||
* value is expected to be negative by its callers, this evaluation
|
||||
* function return a negative value each time the evaluation return a
|
||||
* positive payoff, which is the condition for the acceptance of
|
||||
* a scheduling decision
|
||||
*/
|
||||
return -eenv->payoff;
|
||||
}
|
||||
#else /* CONFIG_SCHED_TUNE */
|
||||
#define energy_diff(eenv) __energy_diff(eenv)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Detect M:N waker/wakee relationships via a switching-frequency heuristic.
|
||||
* A waker of many should wake a different task than the one last awakened
|
||||
|
||||
@@ -3,24 +3,17 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/reciprocal_div.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <trace/events/sched.h>
|
||||
|
||||
#include "sched.h"
|
||||
#include "tune.h"
|
||||
|
||||
unsigned int sysctl_sched_cfs_boost __read_mostly;
|
||||
|
||||
/*
|
||||
* System energy normalization constants
|
||||
*/
|
||||
static struct target_nrg {
|
||||
unsigned long min_power;
|
||||
unsigned long max_power;
|
||||
struct reciprocal_value rdiv;
|
||||
} schedtune_target_nrg;
|
||||
extern struct target_nrg schedtune_target_nrg;
|
||||
|
||||
/* Performance Boost region (B) threshold params */
|
||||
static int perf_boost_idx;
|
||||
@@ -587,37 +580,6 @@ sysctl_sched_cfs_boost_handler(struct ctl_table *table, int write,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* System energy normalization
|
||||
* Returns the normalized value, in the range [0..SCHED_LOAD_SCALE],
|
||||
* corresponding to the specified energy variation.
|
||||
*/
|
||||
int
|
||||
schedtune_normalize_energy(int energy_diff)
|
||||
{
|
||||
u32 normalized_nrg;
|
||||
int max_delta;
|
||||
|
||||
#ifdef CONFIG_SCHED_DEBUG
|
||||
/* Check for boundaries */
|
||||
max_delta = schedtune_target_nrg.max_power;
|
||||
max_delta -= schedtune_target_nrg.min_power;
|
||||
WARN_ON(abs(energy_diff) >= max_delta);
|
||||
#endif
|
||||
|
||||
/* Do scaling using positive numbers to increase the range */
|
||||
normalized_nrg = (energy_diff < 0) ? -energy_diff : energy_diff;
|
||||
|
||||
/* Scale by energy magnitude */
|
||||
normalized_nrg <<= SCHED_LOAD_SHIFT;
|
||||
|
||||
/* Normalize on max energy for target platform */
|
||||
normalized_nrg = reciprocal_divide(
|
||||
normalized_nrg, schedtune_target_nrg.rdiv);
|
||||
|
||||
return (energy_diff < 0) ? -normalized_nrg : normalized_nrg;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCHED_DEBUG
|
||||
static void
|
||||
schedtune_test_nrg(unsigned long delta_pwr)
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
|
||||
#ifdef CONFIG_SCHED_TUNE
|
||||
|
||||
#include <linux/reciprocal_div.h>
|
||||
|
||||
/*
|
||||
* System energy normalization constants
|
||||
*/
|
||||
struct target_nrg {
|
||||
unsigned long min_power;
|
||||
unsigned long max_power;
|
||||
struct reciprocal_value rdiv;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CGROUP_SCHEDTUNE
|
||||
|
||||
int schedtune_cpu_boost(int cpu);
|
||||
@@ -25,7 +36,6 @@ int schedtune_accept_deltas(int nrg_delta, int cap_delta,
|
||||
#define schedtune_enqueue_task(task, cpu) do { } while (0)
|
||||
#define schedtune_dequeue_task(task, cpu) do { } while (0)
|
||||
|
||||
#define schedtune_normalize_energy(energy) energy
|
||||
#define schedtune_accept_deltas(nrg_delta, cap_delta, task) nrg_delta
|
||||
|
||||
#endif /* CONFIG_SCHED_TUNE */
|
||||
|
||||
Reference in New Issue
Block a user