Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee81c262 authored by Sreelakshmi Gownipalli's avatar Sreelakshmi Gownipalli Committed by Gerrit - the friendly Code Review server
Browse files

diag: Move userspace mask process to mask handlers



Move userspace mask processing to mask handlers to reduce
mutex complexity while copying mask to userspace.

Change-Id: I1b769054ab6f11350d31e0164c210e6363fc3523
Signed-off-by: default avatarSreelakshmi Gownipalli <sgownipa@codeaurora.org>
parent cd914bbc
Loading
Loading
Loading
Loading
+156 −43
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#define DIAG_SET_FEATURE_MASK(x) (feature_bytes[(x)/8] |= (1 << (x & 0x7)))

#define MAX_USERSPACE_BUF_SIZ	100000
struct diag_mask_info msg_mask;
struct diag_mask_info msg_bt_mask;
struct diag_mask_info log_mask;
@@ -56,6 +57,9 @@ static const struct diag_ssid_range_t msg_mask_tbl[] = {
	{ .ssid_first = MSG_SSID_25, .ssid_last = MSG_SSID_25_LAST }
};

static int diag_save_user_msg_mask(struct diag_md_session_t *info);
static int diag_save_user_log_mask(struct diag_md_session_t *info);

static int __diag_multisim_mask_init(struct diag_mask_info *mask_info,
	int mask_len, int subid_index);

@@ -1064,7 +1068,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
	uint8_t msg_mask_tbl_count = 0;
	struct diag_ssid_range_t ssid_range;
	struct diag_multisim_masks *ms_ptr = NULL;
	int preset = 0;
	int preset = 0, ret_val = 0;

	mutex_lock(&driver->md_session_lock);
	info = diag_md_session_get_pid(pid);
@@ -1187,8 +1191,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA, pid))
		diag_update_userspace_clients(MSG_MASKS_TYPE);

	/*
	 * Apps processor must send the response to this command. Frame the
	 * response.
@@ -1215,8 +1218,19 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
	memcpy(dest_buf + write_len, src_buf + header_len, mask_size);
	write_len += mask_size;
	for (i = 0; i < NUM_MD_SESSIONS; i++) {
		if (i == APPS_DATA)
		if (i == APPS_DATA) {
			mutex_lock(&driver->md_session_lock);
			info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
			ret_val = diag_save_user_msg_mask(info);
			if (ret_val < 0)
				pr_err("diag: unable to save msg mask to update userspace clients err:%d\n",
					ret_val);
			mutex_unlock(&driver->md_session_lock);
			if (diag_check_update(APPS_DATA, pid))
				diag_update_userspace_clients(MSG_MASKS_TYPE);
			continue;
		}
		if (!diag_check_update(i, pid))
			continue;
		if (i > NUM_PERIPHERALS)
@@ -1257,7 +1271,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
	uint8_t msg_mask_tbl_count = 0;
	uint32_t rt_mask;
	struct diag_multisim_masks *ms_ptr = NULL;
	int preset = 0;
	int preset = 0, ret_val = 0;

	mutex_lock(&driver->md_session_lock);
	info = diag_md_session_get_pid(pid);
@@ -1326,8 +1340,6 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA, pid))
		diag_update_userspace_clients(MSG_MASKS_TYPE);

	/*
	 * Apps processor must send the response to this command. Frame the
@@ -1348,8 +1360,19 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
		write_len += header_len;
	}
	for (i = 0; i < NUM_MD_SESSIONS; i++) {
		if (i == APPS_DATA)
		if (i == APPS_DATA) {
			mutex_lock(&driver->md_session_lock);
			info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
			ret_val = diag_save_user_msg_mask(info);
			if (ret_val)
				pr_err("diag: unable to save msg mask to update userspace clients err:%d\n",
					ret_val);
			mutex_unlock(&driver->md_session_lock);
			if (diag_check_update(APPS_DATA, pid))
				diag_update_userspace_clients(MSG_MASKS_TYPE);
			continue;
		}
		if (!diag_check_update(i, pid))
			continue;
		if (i > NUM_PERIPHERALS)
@@ -1889,7 +1912,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
	int i, peripheral, write_len = 0;
	int status = LOG_STATUS_SUCCESS;
	int sub_index = INVALID_INDEX, read_len = 0, payload_len = 0;
	int rsp_header_len = 0, preset = 0;
	int rsp_header_len = 0, preset = 0, ret_val = 0;
	uint32_t mask_size = 0;
	struct diag_log_config_req_t *req;
	struct diag_log_config_set_rsp_t rsp;
@@ -2031,8 +2054,6 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
	}
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA, pid))
		diag_update_userspace_clients(LOG_MASKS_TYPE);

	/*
	 * Apps processor must send the response to this command. Frame the
@@ -2077,8 +2098,19 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
	write_len += payload_len;

	for (i = 0; i < NUM_MD_SESSIONS; i++) {
		if (i == APPS_DATA)
		if (i == APPS_DATA) {
			mutex_lock(&driver->md_session_lock);
			info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
			ret_val = diag_save_user_log_mask(info);
			if (ret_val < 0)
				pr_err("diag: unable to save log mask to update userspace clients err:%d\n",
					ret_val);
			mutex_unlock(&driver->md_session_lock);
			if (diag_check_update(APPS_DATA, pid))
				diag_update_userspace_clients(LOG_MASKS_TYPE);
			continue;
		}
		if (!diag_check_update(i, pid))
			continue;
		if (i > NUM_PERIPHERALS)
@@ -2108,7 +2140,7 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
	struct diag_log_config_rsp_sub_t rsp;
	struct diag_log_config_rsp_sub_t *req;
	int write_len = 0, i, peripheral;
	int preset = 0, sub_index = INVALID_INDEX;
	int preset = 0, sub_index = INVALID_INDEX, ret_val = 0;
	struct diag_md_session_t *info = NULL;
	struct diag_multisim_masks *ms_ptr = NULL;

@@ -2163,8 +2195,6 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
	}
	mask_info->status = DIAG_CTRL_MASK_ALL_DISABLED;
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA, pid))
		diag_update_userspace_clients(LOG_MASKS_TYPE);

	/*
	 * Apps processor must send the response to this command. Frame the
@@ -2194,8 +2224,19 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
		preset = req->preset_id;
	}
	for (i = 0; i < NUM_MD_SESSIONS; i++) {
		if (i == APPS_DATA)
		if (i == APPS_DATA) {
			mutex_lock(&driver->md_session_lock);
			info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
			ret_val = diag_save_user_log_mask(info);
			if (ret_val < 0)
				pr_err("diag: unable to save log  mask to update userspace clients err:%d\n",
					ret_val);
			mutex_unlock(&driver->md_session_lock);
			if (diag_check_update(APPS_DATA, pid))
				diag_update_userspace_clients(LOG_MASKS_TYPE);
			continue;
		}
		if (!diag_check_update(i, pid))
			continue;
		if (i > NUM_PERIPHERALS)
@@ -2477,6 +2518,17 @@ static int __diag_mask_init(struct diag_mask_info *mask_info, int mask_len,
			return -ENOMEM;
		}
		kmemleak_not_leak(mask_info->update_buf);
		mask_info->update_buf_client = kzalloc(MAX_USERSPACE_BUF_SIZ,
							GFP_KERNEL);
		if (!mask_info->update_buf_client) {
			kfree(mask_info->update_buf);
			mask_info->update_buf = NULL;
			kfree(mask_info->ptr);
			mask_info->ptr = NULL;
			return -ENOMEM;
		}
		kmemleak_not_leak(mask_info->update_buf_client);
		mask_info->update_buf_client_len = 0;
	}
	return 0;
}
@@ -2626,6 +2678,7 @@ void diag_log_mask_free(struct diag_mask_info *mask_info)
static int diag_msg_mask_init(void)
{
	int err = 0, i;
	struct diag_md_session_t *session_info = NULL;

	mutex_init(&msg_mask.lock);
	err = __diag_mask_init(&msg_mask, MSG_MASK_SIZE, APPS_BUF_SIZE);
@@ -2643,6 +2696,14 @@ static int diag_msg_mask_init(void)
		driver->max_ssid_count[i] = 0;
	mutex_unlock(&driver->msg_mask_lock);

	mutex_lock(&driver->md_session_lock);
	session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
							APPS_DATA);
	err = diag_save_user_msg_mask(session_info);
	if (err < 0)
		pr_err("diag: unable to save msg mask to update userspace clients err:%d\n",
			err);
	mutex_unlock(&driver->md_session_lock);
	return 0;
}

@@ -2830,6 +2891,8 @@ static void diag_msg_mask_exit(void)
		ms_ptr = ms_ptr->next;
	}
	msg_mask.ms_ptr = NULL;
	kfree(msg_mask.update_buf_client);
	msg_mask.update_buf_client = NULL;
	mutex_unlock(&driver->msg_mask_lock);
}

@@ -2871,6 +2934,7 @@ static void diag_build_time_mask_exit(void)
static int diag_log_mask_init(void)
{
	int err = 0, i;
	struct diag_md_session_t *session_info = NULL;

	mutex_init(&log_mask.lock);
	err = __diag_mask_init(&log_mask, LOG_MASK_SIZE, APPS_BUF_SIZE);
@@ -2883,7 +2947,14 @@ static int diag_log_mask_init(void)

	for (i = 0; i < NUM_PERIPHERALS; i++)
		driver->num_equip_id[i] = 0;

	mutex_lock(&driver->md_session_lock);
	session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
							APPS_DATA);
	err = diag_save_user_log_mask(session_info);
	if (err < 0)
		pr_err("diag: unable to save log  mask to update userspace clients err:%d\n",
			err);
	mutex_unlock(&driver->md_session_lock);
	return 0;
}

@@ -2916,6 +2987,8 @@ static void diag_log_mask_exit(void)
		ms_ptr = ms_ptr->next;
	}
	log_mask.ms_ptr = NULL;
	kfree(log_mask.update_buf_client);
	log_mask.update_buf_client = NULL;
}

static int diag_event_mask_init(void)
@@ -3022,6 +3095,59 @@ static void diag_event_mask_exit(void)

int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
			       struct diag_md_session_t *info)
{
	struct diag_mask_info *mask_info = NULL;
	int err = 0;

	if (!buf || count == 0)
		return -EINVAL;
	mask_info = (!info) ? &msg_mask : info->msg_mask;
	if (!mask_info)
		return -EIO;

	if (!mask_info->ptr || !mask_info->update_buf_client) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK, mask_info->update_buf_client: %pK\n",
			__func__, mask_info->ptr, mask_info->update_buf_client);
		return -EINVAL;
	}

	err = copy_to_user(buf, mask_info->update_buf_client,
				mask_info->update_buf_client_len);
	if (err) {
		pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n",
		       __func__, err);
	}
	return err ? err : mask_info->update_buf_client_len;
}

int diag_copy_to_user_log_mask(char __user *buf, size_t count,
			       struct diag_md_session_t *info)
{
	struct diag_mask_info *mask_info = NULL;
	int err = 0;

	if (!buf || count == 0)
		return -EINVAL;
	mask_info = (!info) ? &log_mask : info->log_mask;
	if (!mask_info)
		return -EIO;

	if (!mask_info->ptr || !mask_info->update_buf_client) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK, mask_info->update_buf_client: %pK\n",
			__func__, mask_info->ptr, mask_info->update_buf_client);
		return -EINVAL;
	}

	err = copy_to_user(buf, mask_info->update_buf_client,
				mask_info->update_buf_client_len);
	if (err) {
		pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n",
		       __func__, err);
	}
	return err ? err : mask_info->update_buf_client_len;
}

static int diag_save_user_msg_mask(struct diag_md_session_t *info)
{
	int i, err = 0, len = 0;
	int copy_len = 0, total_len = 0;
@@ -3031,9 +3157,6 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
	unsigned char *ptr = NULL;
	uint8_t msg_mask_tbl_count = 0;

	if (!buf || count == 0)
		return -EINVAL;

	mask_info = (!info) ? &msg_mask : info->msg_mask;
	if (!mask_info)
		return -EIO;
@@ -3079,27 +3202,23 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
		len += copy_len;
		mutex_unlock(&mask->lock);
		/* + sizeof(int) to account for data_type already in buf */
		if (total_len + sizeof(int) + len > count) {
			pr_err("diag: In %s, unable to send msg masks to user space, total_len: %d, count: %zu\n",
			       __func__, total_len, count);
		if (total_len + sizeof(int) + len > MAX_USERSPACE_BUF_SIZ) {
			pr_err("diag: In %s, unable to send msg masks to user space, total_len: %d,\n",
			       __func__, total_len);
			err = -ENOMEM;
			break;
		}
		err = copy_to_user(buf + total_len, (void *)ptr, len);
		if (err) {
			pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n",
			       __func__, err);
			break;
		}
		memcpy(mask_info->update_buf_client + total_len,
			(void *)ptr, len);
		total_len += len;
	}
	mask_info->update_buf_client_len = total_len;
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&mask_info->lock);
	return err ? err : total_len;
}

int diag_copy_to_user_log_mask(char __user *buf, size_t count,
			       struct diag_md_session_t *info)
static int diag_save_user_log_mask(struct diag_md_session_t *info)
{
	int i, err = 0, len = 0;
	int copy_len = 0, total_len = 0;
@@ -3108,9 +3227,6 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count,
	struct diag_mask_info *mask_info = NULL;
	unsigned char *ptr = NULL;

	if (!buf || count == 0)
		return -EINVAL;

	mask_info = (!info) ? &log_mask : info->log_mask;
	if (!mask_info)
		return -EIO;
@@ -3150,20 +3266,17 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count,
		len += copy_len;
		mutex_unlock(&mask->lock);
		/* + sizeof(int) to account for data_type already in buf */
		if (total_len + sizeof(int) + len > count) {
			pr_err("diag: In %s, unable to send log masks to user space, total_len: %d, count: %zu\n",
			       __func__, total_len, count);
		if (total_len + sizeof(int) + len > MAX_USERSPACE_BUF_SIZ) {
			pr_err("diag: In %s, unable to send log masks to user space, total_len: %d\n",
			       __func__, total_len);
			err = -ENOMEM;
			break;
		}
		err = copy_to_user(buf + total_len, (void *)ptr, len);
		if (err) {
			pr_err("diag: In %s Unable to send log masks to user space clients, err: %d\n",
			       __func__, err);
			break;
		}
		memcpy(mask_info->update_buf_client + total_len,
			(void *)ptr, len);
		total_len += len;
	}
	mask_info->update_buf_client_len = total_len;
	mutex_unlock(&mask_info->lock);

	return err ? err : total_len;
+2 −0
Original line number Diff line number Diff line
@@ -701,6 +701,8 @@ struct diag_mask_info {
	int mask_len;
	uint8_t *update_buf;
	int update_buf_len;
	uint8_t *update_buf_client;
	int update_buf_client_len;
	uint8_t status;
	struct mutex lock;
};
+19 −8
Original line number Diff line number Diff line
@@ -3682,19 +3682,24 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
	if (driver->data_ready[index] & MSG_MASKS_TYPE) {
		/*Copy the type of data being passed*/
		data_type = driver->data_ready[index] & MSG_MASKS_TYPE;
		mutex_unlock(&driver->diagchar_mutex);
		mutex_lock(&driver->md_session_lock);
		session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
		COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int));
		if (ret == -EFAULT) {
			mutex_unlock(&driver->md_session_lock);
			goto exit;
			goto end;
		}
		if (!session_info)
			mutex_unlock(&driver->md_session_lock);
		write_len = diag_copy_to_user_msg_mask(buf + ret, count,
						       session_info);
		if (session_info)
			mutex_unlock(&driver->md_session_lock);
		if (write_len > 0)
			ret += write_len;
		mutex_lock(&driver->diagchar_mutex);
		driver->data_ready[index] ^= MSG_MASKS_TYPE;
		atomic_dec(&driver->data_ready_notif[index]);
		goto exit;
@@ -3703,13 +3708,14 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
	if (driver->data_ready[index] & EVENT_MASKS_TYPE) {
		/*Copy the type of data being passed*/
		data_type = driver->data_ready[index] & EVENT_MASKS_TYPE;
		mutex_unlock(&driver->diagchar_mutex);
		mutex_lock(&driver->md_session_lock);
		session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
		COPY_USER_SPACE_OR_ERR(buf, data_type, 4);
		if (ret == -EFAULT) {
			mutex_unlock(&driver->md_session_lock);
			goto exit;
			goto end;
		}
		if (session_info && session_info->event_mask &&
		    session_info->event_mask->ptr) {
@@ -3718,7 +3724,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
					session_info->event_mask->mask_len);
			if (ret == -EFAULT) {
				mutex_unlock(&driver->md_session_lock);
				goto exit;
				goto end;
			}
		} else {
			COPY_USER_SPACE_OR_ERR(buf + sizeof(int),
@@ -3726,10 +3732,11 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
						event_mask.mask_len);
			if (ret == -EFAULT) {
				mutex_unlock(&driver->md_session_lock);
				goto exit;
				goto end;
			}
		}
		mutex_unlock(&driver->md_session_lock);
		mutex_lock(&driver->diagchar_mutex);
		driver->data_ready[index] ^= EVENT_MASKS_TYPE;
		atomic_dec(&driver->data_ready_notif[index]);
		goto exit;
@@ -3738,20 +3745,24 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
	if (driver->data_ready[index] & LOG_MASKS_TYPE) {
		/*Copy the type of data being passed*/
		data_type = driver->data_ready[index] & LOG_MASKS_TYPE;
		mutex_unlock(&driver->diagchar_mutex);
		mutex_lock(&driver->md_session_lock);
		session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
		COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int));
		if (ret == -EFAULT) {
			mutex_unlock(&driver->md_session_lock);
			goto exit;
			goto end;
		}

		if (!session_info)
			mutex_unlock(&driver->md_session_lock);
		write_len = diag_copy_to_user_log_mask(buf + ret, count,
						       session_info);
		if (session_info)
			mutex_unlock(&driver->md_session_lock);
		if (write_len > 0)
			ret += write_len;
		mutex_lock(&driver->diagchar_mutex);
		driver->data_ready[index] ^= LOG_MASKS_TYPE;
		atomic_dec(&driver->data_ready_notif[index]);
		goto exit;