soc: qcom: msm_perf: fix invalid usage of dev freq qos apis

msm_perf is attempting to add freq qos requests without waiting
for policy create notifications.
This may cause corruption at latter point of time when it
attempts to trigger freq qos update requests.
The changes registers for policy create notifications and
defers the add requests until dev freq is up.

Change-Id: Idee4268ded948062e627cc4dcdf85ceaf48e5ce7
Signed-off-by: Kishore Sri venkata Ganesh Bolisetty <bsrivenk@codeaurora.org>
This commit is contained in:
Kishore Sri venkata Ganesh Bolisetty 2020-07-30 08:50:58 -07:00
commit 02103dc49e

View file

@ -59,6 +59,68 @@ static unsigned int curr_cap[CLUSTER_MAX];
static cpumask_var_t limit_mask_min;
static cpumask_var_t limit_mask_max;
static bool ready_for_freq_updates;
static int freq_qos_request_init(void)
{
unsigned int cpu;
int ret;
struct cpufreq_policy *policy;
struct freq_qos_request *req;
for_each_present_cpu(cpu) {
policy = cpufreq_cpu_get(cpu);
if (!policy) {
pr_err("%s: Failed to get cpufreq policy for cpu%d\n",
__func__, cpu);
ret = -EAGAIN;
goto cleanup;
}
per_cpu(msm_perf_cpu_stats, cpu).min = 0;
req = &per_cpu(qos_req_min, cpu);
ret = freq_qos_add_request(&policy->constraints, req,
FREQ_QOS_MIN, policy->min);
if (ret < 0) {
pr_err("%s: Failed to add min freq constraint (%d)\n",
__func__, ret);
cpufreq_cpu_put(policy);
goto cleanup;
}
per_cpu(msm_perf_cpu_stats, cpu).max = UINT_MAX;
req = &per_cpu(qos_req_max, cpu);
ret = freq_qos_add_request(&policy->constraints, req,
FREQ_QOS_MAX, policy->max);
if (ret < 0) {
pr_err("%s: Failed to add max freq constraint (%d)\n",
__func__, ret);
cpufreq_cpu_put(policy);
goto cleanup;
}
cpufreq_cpu_put(policy);
}
return 0;
cleanup:
for_each_present_cpu(cpu) {
req = &per_cpu(qos_req_min, cpu);
if (req)
freq_qos_remove_request(req);
req = &per_cpu(qos_req_max, cpu);
if (req)
freq_qos_remove_request(req);
per_cpu(msm_perf_cpu_stats, cpu).min = 0;
per_cpu(msm_perf_cpu_stats, cpu).max = UINT_MAX;
}
return ret;
}
/*******************************sysfs start************************************/
static int set_cpu_min_freq(const char *buf, const struct kernel_param *kp)
{
@ -68,6 +130,17 @@ static int set_cpu_min_freq(const char *buf, const struct kernel_param *kp)
struct cpu_status *i_cpu_stats;
struct cpufreq_policy policy;
struct freq_qos_request *req;
int ret = 0;
if (!ready_for_freq_updates) {
ret = freq_qos_request_init();
if (ret) {
pr_err("%s: Failed to init qos requests policy for ret=%d\n",
__func__, ret);
return ret;
}
ready_for_freq_updates = true;
}
while ((cp = strpbrk(cp + 1, " :")))
ntokens++;
@ -108,7 +181,7 @@ static int set_cpu_min_freq(const char *buf, const struct kernel_param *kp)
continue;
if (cpu_online(i) && (policy.min != i_cpu_stats->min)) {
req = &per_cpu(qos_req_min, cpu);
req = &per_cpu(qos_req_min, i);
if (freq_qos_update_request(req, i_cpu_stats->min) < 0)
break;
}
@ -148,7 +221,17 @@ static int set_cpu_max_freq(const char *buf, const struct kernel_param *kp)
struct cpu_status *i_cpu_stats;
struct cpufreq_policy policy;
struct freq_qos_request *req;
int ret = 0;
if (!ready_for_freq_updates) {
ret = freq_qos_request_init();
if (ret) {
pr_err("%s: Failed to init qos requests policy for ret=%d\n",
__func__, ret);
return ret;
}
ready_for_freq_updates = true;
}
while ((cp = strpbrk(cp + 1, " :")))
ntokens++;
@ -181,7 +264,7 @@ static int set_cpu_max_freq(const char *buf, const struct kernel_param *kp)
continue;
if (cpu_online(i) && (policy.max != i_cpu_stats->max)) {
req = &per_cpu(qos_req_max, cpu);
req = &per_cpu(qos_req_max, i);
if (freq_qos_update_request(req, i_cpu_stats->max) < 0)
break;
}
@ -474,35 +557,7 @@ module_param_cb(core_ctl_register, &param_ops_cc_register,
static int __init msm_performance_init(void)
{
unsigned int cpu;
int ret;
struct cpufreq_policy *policy;
struct freq_qos_request *req;
for_each_present_cpu(cpu) {
per_cpu(msm_perf_cpu_stats, cpu).max = UINT_MAX;
req = &per_cpu(qos_req_min, cpu);
policy = cpufreq_cpu_get(cpu);
if (!policy)
continue;
ret = freq_qos_add_request(&policy->constraints, req,
FREQ_QOS_MIN, policy->min);
if (ret < 0) {
pr_err("%s: Failed to add min freq constraint (%d)\n",
__func__, ret);
return ret;
}
req = &per_cpu(qos_req_max, cpu);
ret = freq_qos_add_request(&policy->constraints, req,
FREQ_QOS_MAX, policy->max);
if (ret < 0) {
pr_err("%s: Failed to add max freq constraint (%d)\n",
__func__, ret);
return ret;
}
}
if (!alloc_cpumask_var(&limit_mask_min, GFP_KERNEL))
return -ENOMEM;