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

Commit 59dd7b8b authored by Junjie Wu's avatar Junjie Wu Committed by Matt Wagantall
Browse files

cpufreq: interactive: Implement cluster-based min_sample_time



min_sample_time needs to be cluster-based to match
above_hispeed_delay. If each CPU keeps making local decisions, it's
possible min_sample_time is not correctly enforced at cluster level,
which results in undesired frequency drops.

Change-Id: I3eb24971b5d57260426f4932f37bb9ec170c3e42
Signed-off-by: default avatarJunjie Wu <junjiew@codeaurora.org>
parent d540f7a6
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ struct cpufreq_interactive_cpuinfo {
	unsigned int floor_freq;
	unsigned int max_freq;
	u64 floor_validate_time;
	u64 local_fvtime; /* per-cpu floor_validate_time */
	u64 hispeed_validate_time; /* cluster hispeed_validate_time */
	u64 local_hvtime; /* per-cpu hispeed_validate_time */
	u64 max_freq_hyst_start_time;
@@ -400,6 +401,7 @@ static void cpufreq_interactive_timer(unsigned long data)
	unsigned int index;
	unsigned long flags;
	struct cpufreq_govinfo int_info;
	u64 max_fvtime;

	if (!down_read_trylock(&pcpu->enable_sem))
		return;
@@ -501,9 +503,10 @@ static void cpufreq_interactive_timer(unsigned long data)
	 * Do not scale below floor_freq unless we have been at or above the
	 * floor frequency for the minimum sample time since last validated.
	 */
	if (new_freq < pcpu->floor_freq) {
		if (now - pcpu->floor_validate_time <
				tunables->min_sample_time) {
	max_fvtime = max(pcpu->floor_validate_time, pcpu->local_fvtime);
	if (new_freq < pcpu->floor_freq &&
	    pcpu->target_freq >= pcpu->policy->cur) {
		if (now - max_fvtime < tunables->min_sample_time) {
			trace_cpufreq_interactive_notyet(
				data, cpu_load, pcpu->target_freq,
				pcpu->policy->cur, new_freq);
@@ -522,7 +525,9 @@ static void cpufreq_interactive_timer(unsigned long data)

	if (!tunables->boosted || new_freq > tunables->hispeed_freq) {
		pcpu->floor_freq = new_freq;
		pcpu->floor_validate_time = now;
		if (pcpu->target_freq >= pcpu->policy->cur ||
		    new_freq >= pcpu->policy->cur)
			pcpu->local_fvtime = now;
	}

	if (new_freq == pcpu->policy->max)
@@ -612,7 +617,7 @@ static int cpufreq_interactive_speedchange_task(void *data)
			unsigned int j;
			unsigned int max_freq = 0;
			struct cpufreq_interactive_cpuinfo *pjcpu;
			u64 hvt = ~0ULL;
			u64 hvt = ~0ULL, fvt = 0;

			pcpu = &per_cpu(cpuinfo, cpu);
			if (!down_read_trylock(&pcpu->enable_sem))
@@ -625,6 +630,7 @@ static int cpufreq_interactive_speedchange_task(void *data)
			for_each_cpu(j, pcpu->policy->cpus) {
				pjcpu = &per_cpu(cpuinfo, j);

				fvt = max(fvt, pjcpu->local_fvtime);
				if (pjcpu->target_freq > max_freq) {
					max_freq = pjcpu->target_freq;
					hvt = pjcpu->local_hvtime;
@@ -632,6 +638,10 @@ static int cpufreq_interactive_speedchange_task(void *data)
					hvt = min(hvt, pjcpu->local_hvtime);
				}
			}
			for_each_cpu(j, pcpu->policy->cpus) {
				pjcpu = &per_cpu(cpuinfo, j);
				pjcpu->floor_validate_time = fvt;
			}

			if (max_freq != pcpu->policy->cur) {
				__cpufreq_driver_target(pcpu->policy,
@@ -1595,6 +1605,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
			pcpu->floor_freq = pcpu->target_freq;
			pcpu->floor_validate_time =
				ktime_to_us(ktime_get());
			pcpu->local_fvtime = pcpu->floor_validate_time;
			pcpu->hispeed_validate_time =
				pcpu->floor_validate_time;
			pcpu->local_hvtime = pcpu->floor_validate_time;