Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b188aa01 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "sched: Support Energy Aware Scheduling irrespective of governor"

parents b4b60f88 37cdece0
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -2470,7 +2470,6 @@ int cpufreq_set_policy(struct cpufreq_policy *policy,
		ret = cpufreq_start_governor(policy);
		if (!ret) {
			pr_debug("governor change\n");
			sched_cpufreq_governor_change(policy, old_gov);
			return 0;
		}
		cpufreq_exit_governor(policy);
+2 −35
Original line number Diff line number Diff line
@@ -973,7 +973,7 @@ static struct kobj_type sugov_tunables_ktype = {

/********************** cpufreq governor interface *********************/

struct cpufreq_governor schedutil_gov;
static struct cpufreq_governor schedutil_gov;

static struct sugov_policy *sugov_policy_alloc(struct cpufreq_policy *policy)
{
@@ -1305,7 +1305,7 @@ static void sugov_limits(struct cpufreq_policy *policy)
	sg_policy->limits_changed = true;
}

struct cpufreq_governor schedutil_gov = {
static struct cpufreq_governor schedutil_gov = {
	.name			= "schedutil",
	.owner			= THIS_MODULE,
	.dynamic_switching	= true,
@@ -1328,36 +1328,3 @@ static int __init sugov_register(void)
	return cpufreq_register_governor(&schedutil_gov);
}
fs_initcall(sugov_register);

#ifdef CONFIG_ENERGY_MODEL
extern bool sched_energy_update;
extern struct mutex sched_energy_mutex;

static void rebuild_sd_workfn(struct work_struct *work)
{
	mutex_lock(&sched_energy_mutex);
	sched_energy_update = true;
	rebuild_sched_domains();
	sched_energy_update = false;
	mutex_unlock(&sched_energy_mutex);
}
static DECLARE_WORK(rebuild_sd_work, rebuild_sd_workfn);

/*
 * EAS shouldn't be attempted without sugov, so rebuild the sched_domains
 * on governor changes to make sure the scheduler knows about it.
 */
void sched_cpufreq_governor_change(struct cpufreq_policy *policy,
				  struct cpufreq_governor *old_gov)
{
	if (old_gov == &schedutil_gov || policy->governor == &schedutil_gov) {
		/*
		 * When called from the cpufreq_register_driver() path, the
		 * cpu_hotplug_lock is already held, so use a work item to
		 * avoid nested locking in rebuild_sched_domains().
		 */
		schedule_work(&rebuild_sd_work);
	}

}
#endif
+1 −2
Original line number Diff line number Diff line
@@ -2827,8 +2827,7 @@ unsigned long scale_irq_capacity(unsigned long util, unsigned long irq, unsigned
}
#endif

#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL)

#ifdef CONFIG_ENERGY_MODEL
#define perf_domain_span(pd) (to_cpumask(((pd)->em_pd->cpus)))

DECLARE_STATIC_KEY_FALSE(sched_energy_present);
+4 −21
Original line number Diff line number Diff line
@@ -201,7 +201,7 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent)
	return 1;
}

#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL)
#if defined(CONFIG_ENERGY_MODEL)
DEFINE_STATIC_KEY_FALSE(sched_energy_present);
unsigned int sysctl_sched_energy_aware = 1;
DEFINE_MUTEX(sched_energy_mutex);
@@ -318,7 +318,6 @@ static void sched_energy_set(bool has_eas)
 *    1. an Energy Model (EM) is available;
 *    2. the SD_ASYM_CPUCAPACITY flag is set in the sched_domain hierarchy.
 *    3. the EM complexity is low enough to keep scheduling overheads low;
 *    4. schedutil is driving the frequency of all CPUs of the rd;
 *
 * The complexity of the Energy Model is defined as:
 *
@@ -338,15 +337,12 @@ static void sched_energy_set(bool has_eas)
 */
#define EM_MAX_COMPLEXITY 2048

extern struct cpufreq_governor schedutil_gov;
static bool build_perf_domains(const struct cpumask *cpu_map)
{
	int i, nr_pd = 0, nr_cs = 0, nr_cpus = cpumask_weight(cpu_map);
	struct perf_domain *pd = NULL, *tmp;
	int cpu = cpumask_first(cpu_map);
	struct root_domain *rd = cpu_rq(cpu)->rd;
	struct cpufreq_policy *policy;
	struct cpufreq_governor *gov;

	if (!sysctl_sched_energy_aware)
		goto free;
@@ -365,19 +361,6 @@ static bool build_perf_domains(const struct cpumask *cpu_map)
		if (find_pd(pd, i))
			continue;

		/* Do not attempt EAS if schedutil is not being used. */
		policy = cpufreq_cpu_get(i);
		if (!policy)
			goto free;
		gov = policy->governor;
		cpufreq_cpu_put(policy);
		if (gov != &schedutil_gov) {
			if (rd->pd)
				pr_warn("rd %*pbl: Disabling EAS, schedutil is mandatory\n",
						cpumask_pr_args(cpu_map));
			goto free;
		}

		/* Create the new pd and add it to the local list. */
		tmp = pd_init(i);
		if (!tmp)
@@ -421,7 +404,7 @@ static bool build_perf_domains(const struct cpumask *cpu_map)
}
#else
static void free_pd(struct perf_domain *pd) { }
#endif /* CONFIG_ENERGY_MODEL && CONFIG_CPU_FREQ_GOV_SCHEDUTIL*/
#endif /* CONFIG_ENERGY_MODEL */

static void free_rootdomain(struct rcu_head *rcu)
{
@@ -2307,10 +2290,10 @@ void partition_sched_domains_locked(int ndoms_new, cpumask_var_t doms_new[],
		;
	}

#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL)
#ifdef CONFIG_ENERGY_MODEL
	/* Build perf. domains: */
	for (i = 0; i < ndoms_new; i++) {
		for (j = 0; j < n && !sched_energy_update; j++) {
		for (j = 0; j < n; j++) {
			if (cpumask_equal(doms_new[i], doms_cur[j]) &&
			    cpu_rq(cpumask_first(doms_cur[j]))->rd->pd) {
				has_eas = true;