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

Commit aceecc06 authored by Junjie Wu's avatar Junjie Wu Committed by Stephen Boyd
Browse files

cpufreq: interactive: Delay evaluation of notification by 1ms



Multiple migrations can happen together within short period if
scheduler is re-arranging a few tasks. In this case, it's only useful
to change frequency at the end of all migrations. Delay handling of
scheduler notification by 1ms.

Change-Id: I9ee7b1e93ce57c28919b5609c40dcde9bd14abed
Suggested-by: default avatarSaravana Kannan <skannan@codeaurora.org>
Signed-off-by: default avatarJunjie Wu <junjiew@codeaurora.org>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
parent 94137b29
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -312,9 +312,9 @@ information such as migration. If non-zero, this also implies governor
sampling windows are aligned across CPUs, with same timer_rate,
regardless what align_windows is set to. Default is zero.

use_migration_notif: If non-zero, reevaluate CPU's frequency
immediately after receiving notification from scheduler. If zero,
ignore scheduler notification. Default is zero.
use_migration_notif: If non-zero, schedule hrtimer to fire in 1ms
to reevaluate frequency of notified CPU, unless the hrtimer is already
pending. If zero, ignore scheduler notification. Default is zero.

max_freq_hysteresis: Each time freq evaluation chooses policy->max,
next max_freq_hysteresis is considered as hysteresis period. During
+35 −12
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <linux/tick.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/hrtimer.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
#include <linux/slab.h>
@@ -37,6 +38,7 @@
struct cpufreq_interactive_policyinfo {
	struct timer_list policy_timer;
	struct timer_list policy_slack_timer;
	struct hrtimer notif_timer;
	spinlock_t load_lock; /* protects load tracking stat */
	u64 last_evaluated_jiffy;
	struct cpufreq_policy *policy;
@@ -52,6 +54,7 @@ struct cpufreq_interactive_policyinfo {
	struct rw_semaphore enable_sem;
	bool reject_notification;
	bool notif_pending;
	unsigned long notif_cpu;
	int governor_enabled;
	struct cpufreq_interactive_tunables *cached_tunables;
	struct sched_load *sl;
@@ -775,33 +778,51 @@ static int load_change_callback(struct notifier_block *nb, unsigned long val,
	struct cpufreq_interactive_tunables *tunables;
	unsigned long flags;

	if (speedchange_task == current)
		return 0;
	if (!ppol || ppol->reject_notification)
		return 0;

	if (!down_read_trylock(&ppol->enable_sem))
		return 0;
	if (!ppol->governor_enabled) {
	if (!ppol->governor_enabled)
		goto exit;

	tunables = ppol->policy->governor_data;
	if (!tunables->use_sched_load || !tunables->use_migration_notif)
		goto exit;

	spin_lock_irqsave(&ppol->target_freq_lock, flags);
	ppol->notif_pending = true;
	ppol->notif_cpu = cpu;
	spin_unlock_irqrestore(&ppol->target_freq_lock, flags);

	if (!hrtimer_is_queued(&ppol->notif_timer))
		hrtimer_start(&ppol->notif_timer, ms_to_ktime(1),
			      HRTIMER_MODE_REL);
exit:
	up_read(&ppol->enable_sem);
	return 0;
}
	tunables = ppol->policy->governor_data;
	if (!tunables->use_sched_load || !tunables->use_migration_notif) {

static enum hrtimer_restart cpufreq_interactive_hrtimer(struct hrtimer *timer)
{
	struct cpufreq_interactive_policyinfo *ppol = container_of(timer,
			struct cpufreq_interactive_policyinfo, notif_timer);
	int cpu;

	if (!down_read_trylock(&ppol->enable_sem))
		return 0;
	if (!ppol->governor_enabled) {
		up_read(&ppol->enable_sem);
		return 0;
	}

	cpu = ppol->notif_cpu;
	trace_cpufreq_interactive_load_change(cpu);
	spin_lock_irqsave(&ppol->target_freq_lock, flags);
	ppol->notif_pending = true;
	spin_unlock_irqrestore(&ppol->target_freq_lock, flags);
	del_timer(&ppol->policy_timer);
	del_timer(&ppol->policy_slack_timer);
	cpufreq_interactive_timer(cpu);

	up_read(&ppol->enable_sem);
	return 0;
	return HRTIMER_NORESTART;
}

static struct notifier_block load_notifier_block = {
@@ -1566,6 +1587,8 @@ static struct cpufreq_interactive_policyinfo *get_policyinfo(
	ppol->policy_timer.function = cpufreq_interactive_timer;
	init_timer(&ppol->policy_slack_timer);
	ppol->policy_slack_timer.function = cpufreq_interactive_nop_timer;
	hrtimer_init(&ppol->notif_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	ppol->notif_timer.function = cpufreq_interactive_hrtimer;
	spin_lock_init(&ppol->load_lock);
	spin_lock_init(&ppol->target_freq_lock);
	init_rwsem(&ppol->enable_sem);