mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 04:42:04 -04:00
msm: mhi_dev: Serialize UCI open and close file node operations
Multiple clients might perform open and close file operations simultaneously on the same file node created by UCI. To avoid race conditions which might result in invalid accesses or crashes, the open and close operations are serialized. Change-Id: Ic6a290a2c6af25bcd60983a7b531bf1287201821 Signed-off-by: Subramanian Ananthanarayanan <skananth@codeaurora.org> Signed-off-by: Gauri Joshi <gaurjosh@codeaurora.org>
This commit is contained in:
parent
bb1be52e1c
commit
db6c7f0843
1 changed files with 17 additions and 1 deletions
|
|
@ -372,6 +372,7 @@ struct uci_client {
|
|||
struct mhi_uci_ctxt_t *uci_ctxt;
|
||||
struct mutex in_chan_lock;
|
||||
struct mutex out_chan_lock;
|
||||
struct mutex client_lock;
|
||||
spinlock_t req_lock;
|
||||
unsigned int f_flags;
|
||||
/* Pointer to dynamically allocated mhi_req structs */
|
||||
|
|
@ -779,6 +780,8 @@ static unsigned int mhi_uci_client_poll(struct file *file, poll_table *wait)
|
|||
if (!uci_handle)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&uci_handle->client_lock);
|
||||
|
||||
poll_wait(file, &uci_handle->read_wq, wait);
|
||||
poll_wait(file, &uci_handle->write_wq, wait);
|
||||
/*
|
||||
|
|
@ -786,8 +789,10 @@ static unsigned int mhi_uci_client_poll(struct file *file, poll_table *wait)
|
|||
* to poll are in connected state and return with the
|
||||
* appropriate mask if channels are disconnected.
|
||||
*/
|
||||
if (!mhi_uci_are_channels_connected(uci_handle)) {
|
||||
if (!atomic_read(&uci_handle->mhi_chans_open) ||
|
||||
!mhi_uci_are_channels_connected(uci_handle)) {
|
||||
mask = POLLHUP;
|
||||
mutex_unlock(&uci_handle->client_lock);
|
||||
return mask;
|
||||
}
|
||||
mask = uci_handle->at_ctrl_mask;
|
||||
|
|
@ -807,6 +812,8 @@ static unsigned int mhi_uci_client_poll(struct file *file, poll_table *wait)
|
|||
uci_log(UCI_DBG_VERBOSE,
|
||||
"Client attempted to poll chan %d, returning mask 0x%x\n",
|
||||
uci_handle->in_chan, mask);
|
||||
mutex_unlock(&uci_handle->client_lock);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
|
@ -1066,6 +1073,7 @@ static int mhi_uci_client_open(struct inode *mhi_inode,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&uci_handle->client_lock);
|
||||
uci_log(UCI_DBG_DBG,
|
||||
"Client opened struct device node 0x%x, ref count 0x%x\n",
|
||||
iminor(mhi_inode), atomic_read(&uci_handle->ref_count));
|
||||
|
|
@ -1073,6 +1081,7 @@ static int mhi_uci_client_open(struct inode *mhi_inode,
|
|||
if (!uci_handle) {
|
||||
atomic_dec(&uci_handle->ref_count);
|
||||
uci_log(UCI_DBG_DBG, "No memory, returning failure\n");
|
||||
mutex_unlock(&uci_handle->client_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
uci_handle->uci_ctxt = &uci_ctxt;
|
||||
|
|
@ -1090,11 +1099,13 @@ static int mhi_uci_client_open(struct inode *mhi_inode,
|
|||
uci_log(UCI_DBG_INFO,
|
||||
"Closing failed channel\n");
|
||||
}
|
||||
mutex_unlock(&uci_handle->client_lock);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
file_handle->private_data = uci_handle;
|
||||
mutex_unlock(&uci_handle->client_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -1111,10 +1122,12 @@ static int mhi_uci_client_release(struct inode *mhi_inode,
|
|||
if (!uci_handle)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&uci_handle->client_lock);
|
||||
in_chan_attr = uci_handle->in_chan_attr;
|
||||
if (!in_chan_attr) {
|
||||
uci_log(UCI_DBG_ERROR, "Null channel attributes for chan %d\n",
|
||||
uci_handle->in_chan);
|
||||
mutex_unlock(&uci_handle->client_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -1122,6 +1135,7 @@ static int mhi_uci_client_release(struct inode *mhi_inode,
|
|||
uci_log(UCI_DBG_DBG, "Client close chan %d, ref count 0x%x\n",
|
||||
iminor(mhi_inode),
|
||||
atomic_read(&uci_handle->ref_count));
|
||||
mutex_unlock(&uci_handle->client_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1185,6 +1199,7 @@ static int mhi_uci_client_release(struct inode *mhi_inode,
|
|||
atomic_set(&uci_handle->read_data_ready, 0);
|
||||
atomic_set(&uci_handle->write_data_ready, 0);
|
||||
file_handle->private_data = NULL;
|
||||
mutex_unlock(&uci_handle->client_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1667,6 +1682,7 @@ static int mhi_register_client(struct uci_client *mhi_client, int index)
|
|||
|
||||
mutex_init(&mhi_client->in_chan_lock);
|
||||
mutex_init(&mhi_client->out_chan_lock);
|
||||
mutex_init(&mhi_client->client_lock);
|
||||
spin_lock_init(&mhi_client->req_lock);
|
||||
/* Init the completion event for AT ctrl read */
|
||||
init_completion(&mhi_client->at_ctrl_read_done);
|
||||
|
|
|
|||
Loading…
Reference in a new issue