Merge "diag: Synchronize threads to fix possible deadlock"

This commit is contained in:
Linux Build Service Account 2017-01-23 04:04:08 -08:00 committed by Gerrit - the friendly Code Review server
commit 17f521e882
4 changed files with 16 additions and 15 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-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
@ -514,7 +514,7 @@ struct diagchar_dev {
struct list_head cmd_reg_list;
struct mutex cmd_reg_mutex;
uint32_t cmd_reg_count;
struct mutex diagfwd_channel_mutex;
struct mutex diagfwd_channel_mutex[NUM_PERIPHERALS];
/* Sizes that reflect memory pool sizes */
unsigned int poolsize;
unsigned int poolsize_hdlc;

View file

@ -3371,7 +3371,7 @@ static int diagchar_cleanup(void)
static int __init diagchar_init(void)
{
dev_t dev;
int error, ret;
int error, ret, i;
pr_debug("diagfwd initializing ..\n");
ret = 0;
@ -3418,7 +3418,8 @@ static int __init diagchar_init(void)
mutex_init(&driver->diag_file_mutex);
mutex_init(&driver->delayed_rsp_mutex);
mutex_init(&apps_data_mutex);
mutex_init(&driver->diagfwd_channel_mutex);
for (i = 0; i < NUM_PERIPHERALS; i++)
mutex_init(&driver->diagfwd_channel_mutex[i]);
init_waitqueue_head(&driver->wait_q);
INIT_WORK(&(driver->diag_drain_work), diag_drain_work_fn);
INIT_WORK(&(driver->update_user_clients),

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 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
@ -655,7 +655,7 @@ void diagfwd_close_transport(uint8_t transport, uint8_t peripheral)
return;
}
mutex_lock(&driver->diagfwd_channel_mutex);
mutex_lock(&driver->diagfwd_channel_mutex[peripheral]);
fwd_info = &early_init_info[transport][peripheral];
if (fwd_info->p_ops && fwd_info->p_ops->close)
fwd_info->p_ops->close(fwd_info->ctxt);
@ -679,7 +679,7 @@ void diagfwd_close_transport(uint8_t transport, uint8_t peripheral)
diagfwd_late_open(dest_info);
diagfwd_cntl_open(dest_info);
init_fn(peripheral);
mutex_unlock(&driver->diagfwd_channel_mutex);
mutex_unlock(&driver->diagfwd_channel_mutex[peripheral]);
diagfwd_queue_read(&peripheral_info[TYPE_DATA][peripheral]);
diagfwd_queue_read(&peripheral_info[TYPE_CMD][peripheral]);
}

View file

@ -1088,9 +1088,9 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
(info->data_ready > 0) || (!info->hdl) ||
(atomic_read(&info->diag_state) == 0));
if (err) {
mutex_lock(&driver->diagfwd_channel_mutex);
mutex_lock(&driver->diagfwd_channel_mutex[info->peripheral]);
diagfwd_channel_read_done(info->fwd_ctxt, buf, 0);
mutex_unlock(&driver->diagfwd_channel_mutex);
mutex_unlock(&driver->diagfwd_channel_mutex[info->peripheral]);
return -ERESTARTSYS;
}
@ -1102,9 +1102,9 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
"%s closing read thread. diag state is closed\n",
info->name);
mutex_lock(&driver->diagfwd_channel_mutex);
mutex_lock(&driver->diagfwd_channel_mutex[info->peripheral]);
diagfwd_channel_read_done(info->fwd_ctxt, buf, 0);
mutex_unlock(&driver->diagfwd_channel_mutex);
mutex_unlock(&driver->diagfwd_channel_mutex[info->peripheral]);
return 0;
}
@ -1171,10 +1171,10 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
if (total_recd > 0) {
DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s read total bytes: %d\n",
info->name, total_recd);
mutex_lock(&driver->diagfwd_channel_mutex);
mutex_lock(&driver->diagfwd_channel_mutex[info->peripheral]);
err = diagfwd_channel_read_done(info->fwd_ctxt,
buf, total_recd);
mutex_unlock(&driver->diagfwd_channel_mutex);
mutex_unlock(&driver->diagfwd_channel_mutex[info->peripheral]);
if (err)
goto fail;
} else {
@ -1187,9 +1187,9 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
return 0;
fail:
mutex_lock(&driver->diagfwd_channel_mutex);
mutex_lock(&driver->diagfwd_channel_mutex[info->peripheral]);
diagfwd_channel_read_done(info->fwd_ctxt, buf, 0);
mutex_unlock(&driver->diagfwd_channel_mutex);
mutex_unlock(&driver->diagfwd_channel_mutex[info->peripheral]);
return -EIO;
}