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

Commit c33be5d1 authored by Dietmar Eggemann's avatar Dietmar Eggemann Committed by Dmitry Shmidt
Browse files

ANDROID: cpufreq: Frequency invariant scheduler load-tracking support



Implements cpufreq_scale_freq_capacity() to provide the scheduler with a
frequency scaling correction factor for more accurate load-tracking.

The factor is:

	current_freq(cpu) << SCHED_CAPACITY_SHIFT / max_freq(cpu)

In fact, freq_scale should be a struct cpufreq_policy data member. But
this would require that the scheduler hot path (__update_load_avg()) would
have to grab the cpufreq lock. This can be avoided by using per-cpu data
initialized to SCHED_CAPACITY_SCALE for freq_scale.

Signed-off-by: default avatarDietmar Eggemann <dietmar.eggemann@arm.com>
Signed-off-by: default avatarAndres Oportus <andresoportus@google.com>
parent 52e61ad4
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -301,6 +301,31 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
#endif
}

/*********************************************************************
 *               FREQUENCY INVARIANT CPU CAPACITY                    *
 *********************************************************************/

static DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE;

static void
scale_freq_capacity(struct cpufreq_policy *policy, struct cpufreq_freqs *freqs)
{
	unsigned long cur = freqs ? freqs->new : policy->cur;
	unsigned long scale = (cur << SCHED_CAPACITY_SHIFT) / policy->max;
	int cpu;

	pr_debug("cpus %*pbl cur/cur max freq %lu/%u kHz freq scale %lu\n",
		 cpumask_pr_args(policy->cpus), cur, policy->max, scale);

	for_each_cpu(cpu, policy->cpus)
		per_cpu(freq_scale, cpu) = scale;
}

unsigned long cpufreq_scale_freq_capacity(struct sched_domain *sd, int cpu)
{
	return per_cpu(freq_scale, cpu);
}

static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
		struct cpufreq_freqs *freqs, unsigned int state)
{
@@ -405,6 +430,8 @@ void cpufreq_freq_transition_begin(struct cpufreq_policy *policy,

	spin_unlock(&policy->transition_lock);

	scale_freq_capacity(policy, freqs);

	cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
}
EXPORT_SYMBOL_GPL(cpufreq_freq_transition_begin);
@@ -2192,6 +2219,8 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
	blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
			CPUFREQ_NOTIFY, new_policy);

	scale_freq_capacity(new_policy, NULL);

	policy->min = new_policy->min;
	policy->max = new_policy->max;
	trace_cpu_frequency_limits(policy->max, policy->min, policy->cpu);
+3 −0
Original line number Diff line number Diff line
@@ -886,4 +886,7 @@ unsigned int cpufreq_generic_get(unsigned int cpu);
int cpufreq_generic_init(struct cpufreq_policy *policy,
		struct cpufreq_frequency_table *table,
		unsigned int transition_latency);

struct sched_domain;
unsigned long cpufreq_scale_freq_capacity(struct sched_domain *sd, int cpu);
#endif /* _LINUX_CPUFREQ_H */