diff options
Diffstat (limited to 'drivers/char')
| -rw-r--r-- | drivers/char/diag/diag_debugfs.c | 7 | ||||
| -rw-r--r-- | drivers/char/diag/diag_memorydevice.c | 1 | ||||
| -rw-r--r-- | drivers/char/diag/diagchar.h | 5 | ||||
| -rw-r--r-- | drivers/char/diag/diagchar_core.c | 35 | ||||
| -rw-r--r-- | drivers/char/diag/diagfwd.c | 10 |
5 files changed, 41 insertions, 17 deletions
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c index c963e4658c07..5e455878ac3e 100644 --- a/drivers/char/diag/diag_debugfs.c +++ b/drivers/char/diag/diag_debugfs.c @@ -52,7 +52,7 @@ static int diag_dbgfs_bridgeinfo_index; static int diag_dbgfs_finished; static int diag_dbgfs_dci_data_index; static int diag_dbgfs_dci_finished; - +static struct mutex diag_dci_dbgfs_mutex; static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { @@ -159,6 +159,7 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file, buf_size = ksize(buf); bytes_remaining = buf_size; + mutex_lock(&diag_dci_dbgfs_mutex); if (diag_dbgfs_dci_data_index == 0) { bytes_written = scnprintf(buf, buf_size, @@ -214,8 +215,8 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file, } temp_data++; } - diag_dbgfs_dci_data_index = (i >= DIAG_DCI_DEBUG_CNT) ? 0 : i + 1; + mutex_unlock(&diag_dci_dbgfs_mutex); bytes_written = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buf); kfree(buf); @@ -1186,6 +1187,7 @@ int diag_debugfs_init(void) pr_warn("diag: could not allocate memory for dci debug info\n"); mutex_init(&dci_stat_mutex); + mutex_init(&diag_dci_dbgfs_mutex); return 0; err: kfree(dci_traffic); @@ -1202,6 +1204,7 @@ void diag_debugfs_cleanup(void) kfree(dci_traffic); mutex_destroy(&dci_stat_mutex); + mutex_destroy(&diag_dci_dbgfs_mutex); } #else int diag_debugfs_init(void) { return 0; } diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c index 986aeed169f5..072c55ca3c4e 100644 --- a/drivers/char/diag/diag_memorydevice.c +++ b/drivers/char/diag/diag_memorydevice.c @@ -202,6 +202,7 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx) found = 1; driver->data_ready[i] |= USER_SPACE_DATA_TYPE; + atomic_inc(&driver->data_ready_notif[i]); pr_debug("diag: wake up logging process\n"); wake_up_interruptible(&driver->wait_q); } diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h index d81a39e2c637..80f004b8435e 100644 --- a/drivers/char/diag/diagchar.h +++ b/drivers/char/diag/diagchar.h @@ -26,6 +26,8 @@ #include <asm/atomic.h> #include "diagfwd_bridge.h" +#define THRESHOLD_CLIENT_LIMIT 50 + /* Size of the USB buffers used for read and write*/ #define USB_MAX_OUT_BUF 4096 #define APPS_BUF_SIZE 4096 @@ -34,7 +36,7 @@ #define DIAG_MAX_REQ_SIZE (16 * 1024) #define DIAG_MAX_RSP_SIZE (16 * 1024) -#define APF_DIAG_PADDING 256 +#define APF_DIAG_PADDING 0 /* * In the worst case, the HDLC buffer can be atmost twice the size of the * original packet. Add 3 bytes for 16 bit CRC (2 bytes) and a delimiter @@ -508,6 +510,7 @@ struct diagchar_dev { wait_queue_head_t wait_q; struct diag_client_map *client_map; int *data_ready; + atomic_t data_ready_notif[THRESHOLD_CLIENT_LIMIT]; int num_clients; int polling_reg_flag; int use_device_tree; diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 4111e599877a..ae0182ae77db 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -139,7 +139,6 @@ module_param(poolsize_qsc_usb, uint, 0); /* This is the max number of user-space clients supported at initialization*/ static unsigned int max_clients = 15; -static unsigned int threshold_client_limit = 50; module_param(max_clients, uint, 0); /* Timer variables */ @@ -328,7 +327,7 @@ static int diagchar_open(struct inode *inode, struct file *file) if (i < driver->num_clients) { diag_add_client(i, file); } else { - if (i < threshold_client_limit) { + if (i < THRESHOLD_CLIENT_LIMIT) { driver->num_clients++; temp = krealloc(driver->client_map , (driver->num_clients) * sizeof(struct @@ -358,11 +357,17 @@ static int diagchar_open(struct inode *inode, struct file *file) } } driver->data_ready[i] = 0x0; + atomic_set(&driver->data_ready_notif[i], 0); driver->data_ready[i] |= MSG_MASKS_TYPE; + atomic_inc(&driver->data_ready_notif[i]); driver->data_ready[i] |= EVENT_MASKS_TYPE; + atomic_inc(&driver->data_ready_notif[i]); driver->data_ready[i] |= LOG_MASKS_TYPE; + atomic_inc(&driver->data_ready_notif[i]); driver->data_ready[i] |= DCI_LOG_MASKS_TYPE; + atomic_inc(&driver->data_ready_notif[i]); driver->data_ready[i] |= DCI_EVENT_MASKS_TYPE; + atomic_inc(&driver->data_ready_notif[i]); if (driver->ref_count == 0) diag_mempool_init(); @@ -1866,6 +1871,7 @@ static int diag_ioctl_lsm_deinit(void) } driver->data_ready[i] |= DEINIT_TYPE; + atomic_inc(&driver->data_ready_notif[i]); mutex_unlock(&driver->diagchar_mutex); wake_up_interruptible(&driver->wait_q); @@ -3029,16 +3035,6 @@ static int diag_user_process_apps_data(const char __user *buf, int len, return 0; } -static int check_data_ready(int index) -{ - int data_type = 0; - - mutex_lock(&driver->diagchar_mutex); - data_type = driver->data_ready[index]; - mutex_unlock(&driver->diagchar_mutex); - return data_type; -} - static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -3065,7 +3061,8 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, pr_err("diag: bad address from user side\n"); return -EFAULT; } - wait_event_interruptible(driver->wait_q, (check_data_ready(index)) > 0); + wait_event_interruptible(driver->wait_q, + atomic_read(&driver->data_ready_notif[index]) > 0); mutex_lock(&driver->diagchar_mutex); @@ -3076,6 +3073,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, /*Copy the type of data being passed*/ data_type = driver->data_ready[index] & USER_SPACE_DATA_TYPE; driver->data_ready[index] ^= USER_SPACE_DATA_TYPE; + atomic_dec(&driver->data_ready_notif[index]); COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int)); /* place holder for number of data field */ ret += sizeof(int); @@ -3089,11 +3087,13 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, /* In case, the thread wakes up and the logging mode is not memory device any more, the condition needs to be cleared */ driver->data_ready[index] ^= USER_SPACE_DATA_TYPE; + atomic_dec(&driver->data_ready_notif[index]); } if (driver->data_ready[index] & HDLC_SUPPORT_TYPE) { data_type = driver->data_ready[index] & HDLC_SUPPORT_TYPE; driver->data_ready[index] ^= HDLC_SUPPORT_TYPE; + atomic_dec(&driver->data_ready_notif[index]); COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int)); mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_pid(current->tgid); @@ -3110,6 +3110,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, data_type = driver->data_ready[index] & DEINIT_TYPE; COPY_USER_SPACE_OR_EXIT(buf, data_type, 4); driver->data_ready[index] ^= DEINIT_TYPE; + atomic_dec(&driver->data_ready_notif[index]); mutex_unlock(&driver->diagchar_mutex); diag_remove_client_entry(file); return ret; @@ -3125,6 +3126,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, if (write_len > 0) ret += write_len; driver->data_ready[index] ^= MSG_MASKS_TYPE; + atomic_dec(&driver->data_ready_notif[index]); goto exit; } @@ -3144,6 +3146,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, event_mask.mask_len); } driver->data_ready[index] ^= EVENT_MASKS_TYPE; + atomic_dec(&driver->data_ready_notif[index]); goto exit; } @@ -3157,6 +3160,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, if (write_len > 0) ret += write_len; driver->data_ready[index] ^= LOG_MASKS_TYPE; + atomic_dec(&driver->data_ready_notif[index]); goto exit; } @@ -3168,6 +3172,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, *(driver->apps_req_buf), driver->apps_req_buf_len); driver->data_ready[index] ^= PKT_TYPE; + atomic_dec(&driver->data_ready_notif[index]); driver->in_busy_pktdata = 0; goto exit; } @@ -3179,6 +3184,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, COPY_USER_SPACE_OR_EXIT(buf+4, *(driver->dci_pkt_buf), driver->dci_pkt_length); driver->data_ready[index] ^= DCI_PKT_TYPE; + atomic_dec(&driver->data_ready_notif[index]); driver->in_busy_dcipktdata = 0; goto exit; } @@ -3191,6 +3197,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, COPY_USER_SPACE_OR_EXIT(buf + 8, (dci_ops_tbl[DCI_LOCAL_PROC]. event_mask_composite), DCI_EVENT_MASK_SIZE); driver->data_ready[index] ^= DCI_EVENT_MASKS_TYPE; + atomic_dec(&driver->data_ready_notif[index]); goto exit; } @@ -3202,6 +3209,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, COPY_USER_SPACE_OR_EXIT(buf+8, (dci_ops_tbl[DCI_LOCAL_PROC]. log_mask_composite), DCI_LOG_MASK_SIZE); driver->data_ready[index] ^= DCI_LOG_MASKS_TYPE; + atomic_dec(&driver->data_ready_notif[index]); goto exit; } @@ -3233,6 +3241,7 @@ exit: exit_stat = diag_copy_dci(buf, count, entry, &ret); mutex_lock(&driver->diagchar_mutex); driver->data_ready[index] ^= DCI_DATA_TYPE; + atomic_dec(&driver->data_ready_notif[index]); mutex_unlock(&driver->diagchar_mutex); if (exit_stat == 1) { mutex_unlock(&driver->dci_mutex); diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c index ef08f939c36e..40412ba87897 100644 --- a/drivers/char/diag/diagfwd.c +++ b/drivers/char/diag/diagfwd.c @@ -226,6 +226,7 @@ void chk_logging_wakeup(void) * situation. */ driver->data_ready[i] |= USER_SPACE_DATA_TYPE; + atomic_inc(&driver->data_ready_notif[i]); pr_debug("diag: Force wakeup of logging process\n"); wake_up_interruptible(&driver->wait_q); break; @@ -480,8 +481,10 @@ void diag_update_userspace_clients(unsigned int type) mutex_lock(&driver->diagchar_mutex); for (i = 0; i < driver->num_clients; i++) - if (driver->client_map[i].pid != 0) + if (driver->client_map[i].pid != 0) { driver->data_ready[i] |= type; + atomic_inc(&driver->data_ready_notif[i]); + } wake_up_interruptible(&driver->wait_q); mutex_unlock(&driver->diagchar_mutex); } @@ -498,6 +501,8 @@ void diag_update_md_clients(unsigned int type) driver->client_map[j].pid == driver->md_session_map[i]->pid) { driver->data_ready[j] |= type; + atomic_inc( + &driver->data_ready_notif[j]); break; } } @@ -513,6 +518,7 @@ void diag_update_sleeping_process(int process_id, int data_type) for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i].pid == process_id) { driver->data_ready[i] |= data_type; + atomic_inc(&driver->data_ready_notif[i]); break; } wake_up_interruptible(&driver->wait_q); @@ -1703,6 +1709,8 @@ int diagfwd_init(void) , GFP_KERNEL)) == NULL) goto err; kmemleak_not_leak(driver->data_ready); + for (i = 0; i < THRESHOLD_CLIENT_LIMIT; i++) + atomic_set(&driver->data_ready_notif[i], 0); if (driver->apps_req_buf == NULL) { driver->apps_req_buf = kzalloc(DIAG_MAX_REQ_SIZE, GFP_KERNEL); if (!driver->apps_req_buf) |
