summaryrefslogtreecommitdiff
path: root/drivers/soc
diff options
context:
space:
mode:
authorTapas Kumar Kundu <tkundu@codeaurora.org>2015-07-17 17:43:31 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:22:33 -0700
commit56f6d6c3529d4fbd4b30156dacbb57f108ec1c62 (patch)
tree68b880a0f1101eb2c5a25090589d726f47500e67 /drivers/soc
parent7a391c8e10fe946dc888be4bd26045dc1411387a (diff)
soc: qcom: msm_perf: free allocated memory if error happens
If any error happens during allocating memory or initializing cluster structure then it returns error but it does not free already allocated memory. This may cause memory leak in certain scenerios. This change prevents memory leak by freeing memory when error happens during initialization. Change-Id: I820acd676dc5baff270c2093ca24a1014c25dabb Signed-off-by: Tapas Kumar Kundu <tkundu@codeaurora.org>
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/qcom/msm_performance.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/drivers/soc/qcom/msm_performance.c b/drivers/soc/qcom/msm_performance.c
index 7e9d9a8013f4..498638272899 100644
--- a/drivers/soc/qcom/msm_performance.c
+++ b/drivers/soc/qcom/msm_performance.c
@@ -1810,7 +1810,7 @@ static void single_mod_exit_timer(unsigned long data)
static int init_cluster_control(void)
{
unsigned int i;
- int ret;
+ int ret = 0;
struct kobject *module_kobj;
managed_clusters = kcalloc(num_clusters, sizeof(struct cluster *),
@@ -1820,19 +1820,24 @@ static int init_cluster_control(void)
for (i = 0; i < num_clusters; i++) {
managed_clusters[i] = kcalloc(1, sizeof(struct cluster),
GFP_KERNEL);
- if (!managed_clusters[i])
- return -ENOMEM;
+ if (!managed_clusters[i]) {
+ pr_err("msm_perf:Cluster %u mem alloc failed\n", i);
+ ret = -ENOMEM;
+ goto error;
+ }
if (!alloc_cpumask_var(&managed_clusters[i]->cpus,
GFP_KERNEL)) {
pr_err("msm_perf:Cluster %u cpu alloc failed\n",
i);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto error;
}
if (!alloc_cpumask_var(&managed_clusters[i]->offlined_cpus,
GFP_KERNEL)) {
pr_err("msm_perf:Cluster %u off_cpus alloc failed\n",
i);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto error;
}
managed_clusters[i]->max_cpu_request = -1;
managed_clusters[i]->single_enter_load = DEF_SINGLE_ENT;
@@ -1861,23 +1866,41 @@ static int init_cluster_control(void)
module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
if (!module_kobj) {
pr_err("msm_perf: Couldn't find module kobject\n");
- return -ENOENT;
+ ret = -ENOENT;
+ goto error;
}
mode_kobj = kobject_create_and_add("workload_modes", module_kobj);
if (!mode_kobj) {
pr_err("msm_perf: Failed to add mode_kobj\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ kobject_put(module_kobj);
+ goto error;
}
ret = sysfs_create_group(mode_kobj, &attr_group);
if (ret) {
pr_err("msm_perf: Failed to create sysfs\n");
- return ret;
+ kobject_put(module_kobj);
+ kobject_put(mode_kobj);
+ goto error;
}
notify_thread = kthread_run(notify_userspace, NULL, "wrkld_notify");
clusters_inited = true;
return 0;
+
+error:
+ for (i = 0; i < num_clusters; i++) {
+ if (!managed_clusters[i])
+ break;
+ if (managed_clusters[i]->offlined_cpus)
+ free_cpumask_var(managed_clusters[i]->offlined_cpus);
+ if (managed_clusters[i]->cpus)
+ free_cpumask_var(managed_clusters[i]->cpus);
+ kfree(managed_clusters[i]);
+ }
+ kfree(managed_clusters);
+ return ret;
}
static int init_events_group(void)