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

Commit 40d14ffc authored by Junjie Wu's avatar Junjie Wu
Browse files

cpufreq: interactive: Use sched_get_cpus_busy() to query busy time



sched_get_cpus_busy() provides a snapshot of all CPUs' busy time
information for the set of CPUs being queried. This avoids race
condition due to migration when CPU load is queried one by one.

Change-Id: I6afdfa74ff9f3ef616872df4e2c3bb04f6233c3f
Signed-off-by: default avatarJunjie Wu <junjiew@codeaurora.org>
parent eea23b7c
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ struct cpufreq_interactive_policyinfo {
	bool reject_notification;
	int governor_enabled;
	struct cpufreq_interactive_tunables *cached_tunables;
	unsigned long *cpu_busy_times;
};

/* Protected by per-policy load_lock */
@@ -421,7 +422,7 @@ static void __cpufreq_interactive_timer(unsigned long data, bool is_notif)
	unsigned int index;
	unsigned long flags;
	unsigned long max_cpu;
	int i;
	int i, fcpu;
	struct cpufreq_govinfo govinfo;

	if (!down_read_trylock(&ppol->enable_sem))
@@ -429,16 +430,20 @@ static void __cpufreq_interactive_timer(unsigned long data, bool is_notif)
	if (!ppol->governor_enabled)
		goto exit;

	fcpu = cpumask_first(ppol->policy->related_cpus);
	now = ktime_to_us(ktime_get());
	spin_lock_irqsave(&ppol->load_lock, flags);
	ppol->last_evaluated_jiffy = get_jiffies_64();

	if (tunables->use_sched_load)
		sched_get_cpus_busy(ppol->cpu_busy_times,
				    ppol->policy->related_cpus);
	max_cpu = cpumask_first(ppol->policy->cpus);
	for_each_cpu(i, ppol->policy->cpus) {
		pcpu = &per_cpu(cpuinfo, i);
		if (tunables->use_sched_load) {
			cputime_speedadj = (u64)sched_get_busy(i) *
				ppol->policy->cpuinfo.max_freq;
			cputime_speedadj = (u64)ppol->cpu_busy_times[i - fcpu]
					* ppol->policy->cpuinfo.max_freq;
			do_div(cputime_speedadj, tunables->timer_rate);
		} else {
			now = update_load(i);
@@ -1446,6 +1451,7 @@ static struct cpufreq_interactive_policyinfo *get_policyinfo(
	struct cpufreq_interactive_policyinfo *ppol =
				per_cpu(polinfo, policy->cpu);
	int i;
	unsigned long *busy;

	/* polinfo already allocated for policy, return */
	if (ppol)
@@ -1455,6 +1461,14 @@ static struct cpufreq_interactive_policyinfo *get_policyinfo(
	if (!ppol)
		return ERR_PTR(-ENOMEM);

	busy = kcalloc(cpumask_weight(policy->related_cpus), sizeof(*busy),
		       GFP_KERNEL);
	if (!busy) {
		kfree(ppol);
		return ERR_PTR(-ENOMEM);
	}
	ppol->cpu_busy_times = busy;

	init_timer_deferrable(&ppol->policy_timer);
	ppol->policy_timer.function = cpufreq_interactive_timer;
	init_timer(&ppol->policy_slack_timer);
@@ -1481,6 +1495,7 @@ static void free_policyinfo(int cpu)
		if (per_cpu(polinfo, j) == ppol)
			per_cpu(polinfo, cpu) = NULL;
	kfree(ppol->cached_tunables);
	kfree(ppol->cpu_busy_times);
	kfree(ppol);
}