Skip to content

Commit

Permalink
soc: qcom: msm_bus: add mutex lock for cllist data
Browse files Browse the repository at this point in the history
Cldata needed to be protected by lock since crash
happened when synchronous update and free.

CRs-Fixed: 2034222
Change-Id: Ied86461b784d69d9758dc3fc793a8a0de86e7f9c
Signed-off-by: Maria Yu <aiquny@codeaurora.org>
  • Loading branch information
sixtaku committed May 31, 2017
1 parent 1fd1999 commit 23d9b90
Showing 1 changed file with 74 additions and 26 deletions.
100 changes: 74 additions & 26 deletions drivers/platform/msm/msm_bus/msm_bus_dbg.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2010-2012, 2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2012, 2014-2015, 2017 The Linux Foundation. All rights
* reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
Expand Down Expand Up @@ -37,6 +38,7 @@
static struct dentry *clients;
static struct dentry *dir;
static DEFINE_MUTEX(msm_bus_dbg_fablist_lock);
static DEFINE_RT_MUTEX(msm_bus_dbg_cllist_lock);
struct msm_bus_dbg_state {
uint32_t cl;
uint8_t enable;
Expand Down Expand Up @@ -288,7 +290,9 @@ static ssize_t client_data_read(struct file *file, char __user *buf,
struct msm_bus_cldata *cldata = NULL;
const struct msm_bus_client_handle *handle = file->private_data;
int found = 0;
ssize_t ret;

rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if ((cldata->clid == cl) ||
(cldata->handle && (cldata->handle == handle))) {
Expand All @@ -297,12 +301,17 @@ static ssize_t client_data_read(struct file *file, char __user *buf,
}
}

if (!found)
if (!found) {
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return 0;
}

bsize = cldata->size;
return simple_read_from_buffer(buf, count, ppos,
ret = simple_read_from_buffer(buf, count, ppos,
cldata->buffer, bsize);
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);

return ret;
}

static int client_data_open(struct inode *inode, struct file *file)
Expand Down Expand Up @@ -338,7 +347,9 @@ int msm_bus_dbg_add_client(const struct msm_bus_client_handle *pdata)
return -ENOMEM;
}
cldata->handle = pdata;
rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_add_tail(&cldata->list, &cl_list);
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return 0;
}

Expand All @@ -351,19 +362,23 @@ int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata,
bool found = false;
char *buf = NULL;

rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->handle == pdata) {
found = true;
break;
}
}

if (!found)
if (!found) {
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return -ENOENT;
}

if (cldata->file == NULL) {
if (pdata->name == NULL) {
MSM_BUS_DBG("Client doesn't have a name\n");
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return -EINVAL;
}
pr_err("\n%s setting up debugfs %s", __func__, pdata->name);
Expand Down Expand Up @@ -393,6 +408,7 @@ int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata,
i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%llu ", ib);
i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n");
cldata->size = i;
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);

trace_bus_update_request((int)ts.tv_sec, (int)ts.tv_nsec,
pdata->name, pdata->mas, pdata->slv, ab, ib,
Expand All @@ -405,6 +421,7 @@ void msm_bus_dbg_remove_client(const struct msm_bus_client_handle *pdata)
{
struct msm_bus_cldata *cldata = NULL;

rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->handle == pdata) {
debugfs_remove(cldata->file);
Expand All @@ -413,6 +430,7 @@ void msm_bus_dbg_remove_client(const struct msm_bus_client_handle *pdata)
break;
}
}
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
}

static int msm_bus_dbg_record_client(const struct msm_bus_scale_pdata *pdata,
Expand All @@ -430,14 +448,17 @@ static int msm_bus_dbg_record_client(const struct msm_bus_scale_pdata *pdata,
cldata->clid = clid;
cldata->file = file;
cldata->size = 0;
rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_add_tail(&cldata->list, &cl_list);
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return 0;
}

static void msm_bus_dbg_free_client(uint32_t clid)
{
struct msm_bus_cldata *cldata = NULL;

rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->clid == clid) {
debugfs_remove(cldata->file);
Expand All @@ -446,6 +467,7 @@ static void msm_bus_dbg_free_client(uint32_t clid)
break;
}
}
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
}

static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,
Expand All @@ -457,18 +479,22 @@ static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,
struct timespec ts;
int found = 0;

rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->clid == clid) {
found = 1;
break;
}
}

if (!found)
if (!found) {
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return -ENOENT;
}

if (cldata->file == NULL) {
if (pdata->name == NULL) {
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
MSM_BUS_DBG("Client doesn't have a name\n");
return -EINVAL;
}
Expand Down Expand Up @@ -517,19 +543,9 @@ static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,

cldata->index = index;
cldata->size = i;
return i;
}
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);

static int msm_bus_dbg_update_request(struct msm_bus_cldata *cldata, int index)
{
int ret = 0;

if ((index < 0) || (index > cldata->pdata->num_usecases)) {
MSM_BUS_DBG("Invalid index!\n");
return -EINVAL;
}
ret = msm_bus_scale_client_update_request(cldata->clid, index);
return ret;
return i;
}

static ssize_t msm_bus_dbg_update_request_write(struct file *file,
Expand All @@ -541,19 +557,26 @@ static ssize_t msm_bus_dbg_update_request_write(struct file *file,
char *chid;
char *buf = kmalloc((sizeof(char) * (cnt + 1)), GFP_KERNEL);
int found = 0;
uint32_t clid;
ssize_t res = cnt;

if (!buf || IS_ERR(buf)) {
MSM_BUS_ERR("Memory allocation for buffer failed\n");
return -ENOMEM;
}
if (cnt == 0)
return 0;
if (copy_from_user(buf, ubuf, cnt))
return -EFAULT;
if (cnt == 0) {
res = 0;
goto out;
}
if (copy_from_user(buf, ubuf, cnt)) {
res = -EFAULT;
goto out;
}
buf[cnt] = '\0';
chid = buf;
MSM_BUS_DBG("buffer: %s\n size: %zu\n", buf, sizeof(ubuf));

rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (strnstr(chid, cldata->pdata->name, cnt)) {
found = 1;
Expand All @@ -564,21 +587,35 @@ static ssize_t msm_bus_dbg_update_request_write(struct file *file,
if (ret) {
MSM_BUS_DBG("Index conversion"
" failed\n");
return -EFAULT;
rt_mutex_unlock(
&msm_bus_dbg_cllist_lock);
res = -EFAULT;
goto out;
}
} else {
MSM_BUS_DBG("Error parsing input. Index not"
" found\n");
found = 0;
}
if ((index < 0) ||
(index > cldata->pdata->num_usecases)) {
MSM_BUS_DBG("Invalid index!\n");
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
res = -EINVAL;
goto out;
}
clid = cldata->clid;
break;
}
}
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);

if (found)
msm_bus_dbg_update_request(cldata, index);
msm_bus_scale_client_update_request(clid, index);

out:
kfree(buf);
return cnt;
return res;
}

/**
Expand All @@ -601,8 +638,10 @@ static ssize_t fabric_data_read(struct file *file, char __user *buf,
break;
}
}
if (!found)
if (!found) {
mutex_unlock(&msm_bus_dbg_fablist_lock);
return -ENOENT;
}
bsize = fablist->size;
ret = simple_read_from_buffer(buf, count, ppos,
fablist->buffer, bsize);
Expand Down Expand Up @@ -691,8 +730,10 @@ static int msm_bus_dbg_fill_fab_buffer(const char *fabname,
break;
}
}
if (!found)
if (!found) {
mutex_unlock(&msm_bus_dbg_fablist_lock);
return -ENOENT;
}

if (fablist->file == NULL) {
MSM_BUS_DBG("Fabric dbg entry does not exist\n");
Expand Down Expand Up @@ -841,6 +882,7 @@ static int __init msm_bus_debugfs_init(void)
goto err;
}

rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->pdata->name == NULL) {
MSM_BUS_DBG("Client name not found\n");
Expand All @@ -849,6 +891,7 @@ static int __init msm_bus_debugfs_init(void)
cldata->file = msm_bus_dbg_create(cldata->
pdata->name, S_IRUGO, clients, cldata->clid);
}
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);

mutex_lock(&msm_bus_dbg_fablist_lock);
list_for_each_entry(fablist, &fabdata_list, list) {
Expand All @@ -857,6 +900,7 @@ static int __init msm_bus_debugfs_init(void)
if (fablist->file == NULL) {
MSM_BUS_DBG("Cannot create files for commit data\n");
kfree(rules_buf);
mutex_unlock(&msm_bus_dbg_fablist_lock);
goto err;
}
}
Expand All @@ -876,10 +920,14 @@ static void __exit msm_bus_dbg_teardown(void)
struct msm_bus_cldata *cldata = NULL, *cldata_temp;

debugfs_remove_recursive(dir);

rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry_safe(cldata, cldata_temp, &cl_list, list) {
list_del(&cldata->list);
kfree(cldata);
}
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);

mutex_lock(&msm_bus_dbg_fablist_lock);
list_for_each_entry_safe(fablist, fablist_temp, &fabdata_list, list) {
list_del(&fablist->list);
Expand Down

0 comments on commit 23d9b90

Please sign in to comment.