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

Commit 0f34ee93 authored by Saravana Kannan's avatar Saravana Kannan
Browse files

cpufreq: schedutil: Keep track of average policy capacity



Average policy capacity will be used in future patches to improve detection
of hispeed load condition.

Change-Id: Icab992243b83eb5feaae619d16b22510010f54c5
Signed-off-by: default avatarSaravana Kannan <skannan@codeaurora.org>
parent af541e19
Loading
Loading
Loading
Loading
+62 −7
Original line number Diff line number Diff line
@@ -36,6 +36,10 @@ struct sugov_policy {
	raw_spinlock_t update_lock;  /* For shared policies */
	u64 last_freq_update_time;
	s64 freq_update_delay_ns;
	u64 last_ws;
	u64 curr_cycles;
	u64 last_cyc_update_time;
	unsigned long avg_cap;
	unsigned int next_freq;
	unsigned int cached_raw_freq;
	unsigned long hispeed_util;
@@ -199,6 +203,51 @@ static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util,
	sg_cpu->iowait_boost >>= 1;
}

static unsigned long freq_to_util(struct sugov_policy *sg_policy,
				  unsigned int freq)
{
	return mult_frac(sg_policy->max, freq,
			 sg_policy->policy->cpuinfo.max_freq);
}

#define KHZ 1000
static void sugov_track_cycles(struct sugov_policy *sg_policy,
				unsigned int prev_freq,
				u64 upto)
{
	u64 delta_ns, cycles;
	/* Track cycles in current window */
	delta_ns = upto - sg_policy->last_cyc_update_time;
	cycles = (prev_freq * delta_ns) / (NSEC_PER_SEC / KHZ);
	sg_policy->curr_cycles += cycles;
	sg_policy->last_cyc_update_time = upto;
}

static void sugov_calc_avg_cap(struct sugov_policy *sg_policy, u64 curr_ws,
				unsigned int prev_freq)
{
	u64 last_ws = sg_policy->last_ws;
	unsigned int avg_freq;

	WARN_ON(curr_ws < last_ws);
	if (curr_ws <= last_ws)
		return;

	/* If we skipped some windows */
	if (curr_ws > (last_ws + sched_ravg_window)) {
		avg_freq = prev_freq;
		/* Reset tracking history */
		sg_policy->last_cyc_update_time = curr_ws;
	} else {
		sugov_track_cycles(sg_policy, prev_freq, curr_ws);
		avg_freq = sg_policy->curr_cycles;
		avg_freq /= sched_ravg_window / (NSEC_PER_SEC / KHZ);
	}
	sg_policy->avg_cap = freq_to_util(sg_policy, avg_freq);
	sg_policy->curr_cycles = 0;
	sg_policy->last_ws = curr_ws;
}

#define NL_RATIO 75
#define HISPEED_LOAD 90
static void sugov_walt_adjust(struct sugov_cpu *sg_cpu, unsigned long *util,
@@ -225,13 +274,6 @@ static void sugov_walt_adjust(struct sugov_cpu *sg_cpu, unsigned long *util,
		*util = max(*util, sg_cpu->walt_load.pl);
}

static unsigned long freq_to_util(struct sugov_policy *sg_policy,
				  unsigned int freq)
{
	return mult_frac(sg_policy->max, freq,
			 sg_policy->policy->cpuinfo.max_freq);
}

static void sugov_update_single(struct update_util_data *hook, u64 time,
				unsigned int flags)
{
@@ -254,6 +296,8 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
	} else {
		sugov_get_util(&util, &max, sg_cpu->cpu);
		sugov_iowait_boost(sg_cpu, &util, &max);
		sugov_calc_avg_cap(sg_policy, sg_cpu->walt_load.ws,
				   sg_policy->policy->cur);
		sugov_walt_adjust(sg_cpu, &util, &max);
		next_f = get_next_freq(sg_policy, util, max);
	}
@@ -343,6 +387,9 @@ static void sugov_update_shared(struct update_util_data *hook, u64 time,
	sugov_set_iowait_boost(sg_cpu, time, flags);
	sg_cpu->last_update = time;

	sugov_calc_avg_cap(sg_policy, sg_cpu->walt_load.ws,
			   sg_policy->policy->cur);

	trace_sugov_util_update(sg_cpu->cpu, sg_cpu->util, max,
				sg_cpu->walt_load.nl,
				sg_cpu->walt_load.pl, flags);
@@ -360,6 +407,10 @@ static void sugov_work(struct kthread_work *work)
	struct sugov_policy *sg_policy = container_of(work, struct sugov_policy, work);

	mutex_lock(&sg_policy->work_lock);
	raw_spin_lock(&sg_policy->update_lock);
	sugov_track_cycles(sg_policy, sg_policy->policy->cur,
			   sched_ktime_clock());
	raw_spin_unlock(&sg_policy->update_lock);
	__cpufreq_driver_target(sg_policy->policy, sg_policy->next_freq,
				CPUFREQ_RELATION_L);
	mutex_unlock(&sg_policy->work_lock);
@@ -730,6 +781,10 @@ static void sugov_limits(struct cpufreq_policy *policy)

	if (!policy->fast_switch_enabled) {
		mutex_lock(&sg_policy->work_lock);
		raw_spin_lock(&sg_policy->update_lock);
		sugov_track_cycles(sg_policy, sg_policy->policy->cur,
				   sched_ktime_clock());
		raw_spin_unlock(&sg_policy->update_lock);
		cpufreq_policy_apply_limits(policy);
		mutex_unlock(&sg_policy->work_lock);
	}