Merge "soc: qcom: msm_bus: add mutex lock for cllist data"

This commit is contained in:
Linux Build Service Account 2017-05-30 13:08:51 -07:00 committed by Gerrit - the friendly Code Review server
commit a9db53d011
1 changed files with 76 additions and 26 deletions

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2012, 2014-2015, The Linux Foundation. All rights
/* 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
@ -38,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;
@ -289,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))) {
@ -298,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)
@ -339,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;
}
@ -352,6 +362,7 @@ 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;
@ -359,12 +370,15 @@ int msm_bus_dbg_rec_transaction(const struct msm_bus_client_handle *pdata,
}
}
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_debug("\n%s setting up debugfs %s", __func__, pdata->name);
@ -394,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);
@ -405,6 +420,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);
@ -413,6 +429,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,
@ -430,7 +447,9 @@ 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;
}
@ -438,6 +457,7 @@ 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);
@ -446,6 +466,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,
@ -457,6 +478,7 @@ 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;
@ -464,11 +486,14 @@ static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,
}
}
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;
}
@ -516,21 +541,11 @@ static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,
cldata->index = index;
cldata->size = i;
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return i;
}
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;
}
static ssize_t msm_bus_dbg_update_request_write(struct file *file,
const char __user *ubuf, size_t cnt, loff_t *ppos)
{
@ -540,19 +555,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;
@ -563,21 +585,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;
}
/**
@ -600,8 +636,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);
@ -690,8 +728,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");
@ -742,6 +782,8 @@ static ssize_t msm_bus_dbg_dump_clients_read(struct file *file,
"\nDumping curent client votes to trace log\n");
if (*ppos)
goto exit_dump_clients_read;
rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (IS_ERR_OR_NULL(cldata->pdata))
continue;
@ -757,6 +799,7 @@ static ssize_t msm_bus_dbg_dump_clients_read(struct file *file,
cldata->pdata->active_only);
}
}
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
exit_dump_clients_read:
return simple_read_from_buffer(buf, count, ppos, msg, cnt);
}
@ -881,6 +924,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) {
if (cldata->pdata->name == NULL) {
@ -900,6 +944,7 @@ static int __init msm_bus_debugfs_init(void)
&client_data_fops);
}
}
rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
if (debugfs_create_file("dump_clients", S_IRUGO | S_IWUSR,
clients, NULL, &msm_bus_dbg_dump_clients_fops) == NULL)
@ -912,6 +957,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;
}
}
@ -931,10 +977,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);