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

Commit 5f61b6cc authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cpufreq: interactive: Permanently cache tunable values"

parents b276bfa9 75c12acc
Loading
Loading
Loading
Loading
+61 −18
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ struct cpufreq_interactive_tunables {

/* For cases where we have single governor instance for system */
struct cpufreq_interactive_tunables *common_tunables;
static DEFINE_PER_CPU(struct cpufreq_interactive_tunables *, cached_tunables);

static struct attribute_group *get_sysfs_attr(void);

@@ -1223,6 +1224,54 @@ static struct notifier_block cpufreq_interactive_idle_nb = {
	.notifier_call = cpufreq_interactive_idle_notifier,
};

static struct cpufreq_interactive_tunables *alloc_tunable(
					struct cpufreq_policy *policy)
{
	struct cpufreq_interactive_tunables *tunables;

	tunables = kzalloc(sizeof(*tunables), GFP_KERNEL);
	if (!tunables) {
		pr_err("%s: POLICY_INIT: kzalloc failed\n", __func__);
		return ERR_PTR(-ENOMEM);
	}

	tunables->above_hispeed_delay = default_above_hispeed_delay;
	tunables->nabove_hispeed_delay =
		ARRAY_SIZE(default_above_hispeed_delay);
	tunables->go_hispeed_load = DEFAULT_GO_HISPEED_LOAD;
	tunables->target_loads = default_target_loads;
	tunables->ntarget_loads = ARRAY_SIZE(default_target_loads);
	tunables->min_sample_time = DEFAULT_MIN_SAMPLE_TIME;
	tunables->timer_rate = DEFAULT_TIMER_RATE;
	tunables->boostpulse_duration_val = DEFAULT_MIN_SAMPLE_TIME;
	tunables->timer_slack_val = DEFAULT_TIMER_SLACK;

	spin_lock_init(&tunables->target_loads_lock);
	spin_lock_init(&tunables->above_hispeed_delay_lock);

	return tunables;
}

static void save_tunables(struct cpufreq_policy *policy,
			  struct cpufreq_interactive_tunables *tunables)
{
	int cpu;

	if (have_governor_per_policy()) {
		for_each_cpu(cpu, policy->related_cpus) {
			WARN_ON(per_cpu(cached_tunables, cpu) &&
				per_cpu(cached_tunables, cpu) != tunables);
			per_cpu(cached_tunables, cpu) = tunables;
		}
	} else {
		for_each_possible_cpu(cpu) {
			WARN_ON(per_cpu(cached_tunables, cpu) &&
				per_cpu(cached_tunables, cpu) != tunables);
			per_cpu(cached_tunables, cpu) = tunables;
		}
	}
}

static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
		unsigned int event)
{
@@ -1250,27 +1299,14 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
			return 0;
		}

		tunables = kzalloc(sizeof(*tunables), GFP_KERNEL);
		tunables = per_cpu(cached_tunables, policy->cpu);
		if (!tunables) {
			pr_err("%s: POLICY_INIT: kzalloc failed\n", __func__);
			return -ENOMEM;
			tunables = alloc_tunable(policy);
			if (IS_ERR(tunables))
				return PTR_ERR(tunables);
		}

		tunables->usage_count = 1;
		tunables->above_hispeed_delay = default_above_hispeed_delay;
		tunables->nabove_hispeed_delay =
			ARRAY_SIZE(default_above_hispeed_delay);
		tunables->go_hispeed_load = DEFAULT_GO_HISPEED_LOAD;
		tunables->target_loads = default_target_loads;
		tunables->ntarget_loads = ARRAY_SIZE(default_target_loads);
		tunables->min_sample_time = DEFAULT_MIN_SAMPLE_TIME;
		tunables->timer_rate = DEFAULT_TIMER_RATE;
		tunables->boostpulse_duration_val = DEFAULT_MIN_SAMPLE_TIME;
		tunables->timer_slack_val = DEFAULT_TIMER_SLACK;

		spin_lock_init(&tunables->target_loads_lock);
		spin_lock_init(&tunables->above_hispeed_delay_lock);

		policy->governor_data = tunables;
		if (!have_governor_per_policy()) {
			WARN_ON(cpufreq_get_global_kobject());
@@ -1309,7 +1345,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
					get_sysfs_attr());
			if (!have_governor_per_policy())
				cpufreq_put_global_kobject();
			kfree(tunables);
			save_tunables(policy, tunables);
			common_tunables = NULL;
		}

@@ -1479,9 +1515,16 @@ module_init(cpufreq_interactive_init);

static void __exit cpufreq_interactive_exit(void)
{
	int cpu;

	cpufreq_unregister_governor(&cpufreq_gov_interactive);
	kthread_stop(speedchange_task);
	put_task_struct(speedchange_task);

	for_each_possible_cpu(cpu) {
		kfree(per_cpu(cached_tunables, cpu));
		per_cpu(cached_tunables, cpu) = NULL;
	}
}

module_exit(cpufreq_interactive_exit);