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

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

diag: Add mutex protection while writing to smd



Add mutex protection to diag ctrl channel to avoid concurrency
issues with smd_write() to the diag ctrl channel.

Change-Id: Ibd176aabfd5d4f7630db0b5c07c11bba2ed2f75b
Signed-off-by: default avatarSreelakshmi Gownipalli <sgownipa@codeaurora.org>
parent 5830ea78
Loading
Loading
Loading
Loading
+47 −20
Original line number Diff line number Diff line
@@ -327,10 +327,10 @@ void diag_mask_update_fn(struct work_struct *work)
	}

	diag_send_feature_mask_update(smd_info);
	diag_send_msg_mask_update(smd_info->ch, ALL_SSID, ALL_SSID,
	diag_send_msg_mask_update(smd_info, ALL_SSID, ALL_SSID,
						smd_info->peripheral);
	diag_send_log_mask_update(smd_info->ch, ALL_EQUIP_ID);
	diag_send_event_mask_update(smd_info->ch, diag_event_num_bytes);
	diag_send_log_mask_update(smd_info, ALL_EQUIP_ID);
	diag_send_event_mask_update(smd_info, diag_event_num_bytes);

	if (smd_info->notify_context == SMD_EVENT_OPEN)
		diag_send_diag_mode_update_by_smd(smd_info,
@@ -339,7 +339,7 @@ void diag_mask_update_fn(struct work_struct *work)
	smd_info->notify_context = 0;
}

void diag_send_log_mask_update(smd_channel_t *ch, int equip_id)
void diag_send_log_mask_update(struct diag_smd_info *smd_info, int equip_id)
{
	void *buf = driver->buf_log_mask_update;
	struct diag_log_mask_t *log_item = NULL;
@@ -348,6 +348,12 @@ void diag_send_log_mask_update(smd_channel_t *ch, int equip_id)
	int wr_size = -ENOMEM, retry_count = 0;
	int i, header_size, send_once = 0;

	if (!smd_info) {
		pr_err("diag: In %s, null smd info pointer\n",
			__func__);
		return;
	}

	header_size = sizeof(struct diag_ctrl_log_mask);
	log_item = (struct diag_log_mask_t *)driver->log_masks;
	mutex_lock(&driver->diag_cntl_mutex);
@@ -390,10 +396,12 @@ void diag_send_log_mask_update(smd_channel_t *ch, int equip_id)
			       log_mask_size);
		}

		if (ch) {
		if (smd_info->ch) {
			while (retry_count < 3) {
				wr_size = smd_write(ch, buf,
				mutex_lock(&smd_info->smd_ch_mutex);
				wr_size = smd_write(smd_info->ch, buf,
						header_size + log_mask_size);
				mutex_unlock(&smd_info->smd_ch_mutex);
				if (wr_size == -ENOMEM) {
					retry_count++;
					usleep_range(10000, 10100);
@@ -415,12 +423,18 @@ void diag_send_log_mask_update(smd_channel_t *ch, int equip_id)
	mutex_unlock(&driver->diag_cntl_mutex);
}

void diag_send_event_mask_update(smd_channel_t *ch, int num_bytes)
void diag_send_event_mask_update(struct diag_smd_info *smd_info, int num_bytes)
{
	void *buf = driver->buf_event_mask_update;
	int header_size = sizeof(struct diag_ctrl_event_mask);
	int wr_size = -ENOMEM, retry_count = 0;

	if (!smd_info) {
		pr_err("diag: In %s, null smd info pointer\n",
			__func__);
		return;
	}

	mutex_lock(&driver->diag_cntl_mutex);
	if (num_bytes == 0) {
		pr_debug("diag: event mask not set yet, so no update\n");
@@ -459,9 +473,12 @@ void diag_send_event_mask_update(smd_channel_t *ch, int num_bytes)
		return;
	}
	memcpy(buf, driver->event_mask, header_size);
	if (ch) {
	if (smd_info->ch) {
		while (retry_count < 3) {
			wr_size = smd_write(ch, buf, header_size + num_bytes);
			mutex_lock(&smd_info->smd_ch_mutex);
			wr_size = smd_write(smd_info->ch, buf,
						header_size + num_bytes);
			mutex_unlock(&smd_info->smd_ch_mutex);
			if (wr_size == -ENOMEM) {
				retry_count++;
				usleep_range(10000, 10100);
@@ -476,14 +493,20 @@ void diag_send_event_mask_update(smd_channel_t *ch, int num_bytes)
	mutex_unlock(&driver->diag_cntl_mutex);
}

void diag_send_msg_mask_update(smd_channel_t *ch, int updated_ssid_first,
						int updated_ssid_last, int proc)
void diag_send_msg_mask_update(struct diag_smd_info *smd_info,
				int updated_ssid_first, int updated_ssid_last,
				int proc)
{
	void *buf = driver->buf_msg_mask_update;
	int first, last, actual_last, size = -ENOMEM, retry_count = 0;
	int header_size = sizeof(struct diag_ctrl_msg_mask);
	uint8_t *ptr = driver->msg_masks;

	if (!smd_info) {
		pr_err("diag: In %s, null smd info pointer\n",
				__func__);
		return;
	}
	mutex_lock(&driver->diag_cntl_mutex);
	while (*(uint32_t *)(ptr + 4)) {
		first = *(uint32_t *)ptr;
@@ -543,10 +566,12 @@ void diag_send_msg_mask_update(smd_channel_t *ch, int updated_ssid_first,
		driver->msg_mask->ssid_first = first;
		driver->msg_mask->ssid_last = actual_last;
		memcpy(buf, driver->msg_mask, header_size);
		if (ch) {
		if (smd_info->ch) {
			while (retry_count < 3) {
				size = smd_write(ch, buf, header_size +
				 4*(driver->msg_mask->msg_mask_size));
				mutex_lock(&smd_info->smd_ch_mutex);
				size = smd_write(smd_info->ch, buf, header_size
					+ 4*(driver->msg_mask->msg_mask_size));
				mutex_unlock(&smd_info->smd_ch_mutex);
				if (size == -ENOMEM) {
					retry_count++;
					usleep_range(10000, 10100);
@@ -606,7 +631,9 @@ void diag_send_feature_mask_update(struct diag_smd_info *smd_info)
	total_len = header_size + FEATURE_MASK_LEN_BYTES;

	while (retry_count < 3) {
		mutex_lock(&smd_info->smd_ch_mutex);
		wr_size = smd_write(smd_info->ch, buf, total_len);
		mutex_unlock(&smd_info->smd_ch_mutex);
		if (wr_size == -ENOMEM) {
			retry_count++;
			/*
@@ -661,7 +688,7 @@ int diag_process_apps_masks(unsigned char *buf, int len)
			for (i = 0; i < NUM_SMD_CONTROL_CHANNELS; i++) {
				if (driver->smd_cntl[i].ch)
					diag_send_log_mask_update(
						driver->smd_cntl[i].ch,
						&driver->smd_cntl[i],
						*(int *)buf);
			}
			encode_rsp_and_send(12 + payload_length - 1);
@@ -703,7 +730,7 @@ int diag_process_apps_masks(unsigned char *buf, int len)
			for (i = 0; i < NUM_SMD_CONTROL_CHANNELS; i++) {
				if (driver->smd_cntl[i].ch)
					diag_send_log_mask_update(
						driver->smd_cntl[i].ch,
						&driver->smd_cntl[i],
						ALL_EQUIP_ID);

			}
@@ -774,7 +801,7 @@ int diag_process_apps_masks(unsigned char *buf, int len)
			for (i = 0; i < NUM_SMD_CONTROL_CHANNELS; i++) {
				if (driver->smd_cntl[i].ch)
					diag_send_msg_mask_update(
						driver->smd_cntl[i].ch,
						&driver->smd_cntl[i],
						ssid_first, ssid_last,
						driver->smd_cntl[i].peripheral);

@@ -799,7 +826,7 @@ int diag_process_apps_masks(unsigned char *buf, int len)
			for (i = 0; i < NUM_SMD_CONTROL_CHANNELS; i++) {
				if (driver->smd_cntl[i].ch)
					diag_send_msg_mask_update(
						driver->smd_cntl[i].ch,
						&driver->smd_cntl[i],
						ALL_SSID, ALL_SSID,
						driver->smd_cntl[i].peripheral);

@@ -825,7 +852,7 @@ int diag_process_apps_masks(unsigned char *buf, int len)
			for (i = 0; i < NUM_SMD_CONTROL_CHANNELS; i++) {
				if (driver->smd_cntl[i].ch)
					diag_send_event_mask_update(
						driver->smd_cntl[i].ch,
						&driver->smd_cntl[i],
						diag_event_num_bytes);
			}
			encode_rsp_and_send(6 + EVENT_LAST_ID/8);
@@ -843,7 +870,7 @@ int diag_process_apps_masks(unsigned char *buf, int len)
			for (i = 0; i < NUM_SMD_CONTROL_CHANNELS; i++) {
				if (driver->smd_cntl[i].ch)
					diag_send_event_mask_update(
						driver->smd_cntl[i].ch,
						&driver->smd_cntl[i],
						diag_event_num_bytes);
			}
			encode_rsp_and_send(2);
+4 −4
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, 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
@@ -21,10 +21,10 @@ struct diag_log_mask_t {
	uint8_t ptr[MAX_ITEMS_PER_EQUIP_ID];
} __packed;

void diag_send_event_mask_update(smd_channel_t *, int num_bytes);
void diag_send_msg_mask_update(smd_channel_t *, int ssid_first,
void diag_send_event_mask_update(struct diag_smd_info *smd_info, int num_bytes);
void diag_send_msg_mask_update(struct diag_smd_info *smd_info, int ssid_first,
					 int ssid_last, int proc);
void diag_send_log_mask_update(smd_channel_t *, int);
void diag_send_log_mask_update(struct diag_smd_info *smd_info, int);
void diag_mask_update_fn(struct work_struct *work);
void diag_send_feature_mask_update(struct diag_smd_info *smd_info);
int diag_process_apps_masks(unsigned char *buf, int len);
+4 −0
Original line number Diff line number Diff line
@@ -512,7 +512,9 @@ void diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info,
	mutex_lock(&driver->diag_cntl_mutex);
	if (smd_info->ch) {
		while (retry_count < 3) {
			mutex_lock(&smd_info->smd_ch_mutex);
			wr_size = smd_write(smd_info->ch, buf, msg_size);
			mutex_unlock(&smd_info->smd_ch_mutex);
			if (wr_size == -ENOMEM) {
				/*
				 * The smd channel is full. Delay while
@@ -566,7 +568,9 @@ int diag_send_stm_state(struct diag_smd_info *smd_info,
		stm_msg.version = 1;
		stm_msg.control_data = stm_control_data;
		while (retry_count < 3) {
			mutex_lock(&smd_info->smd_ch_mutex);
			wr_size = smd_write(smd_info->ch, &stm_msg, msg_size);
			mutex_unlock(&smd_info->smd_ch_mutex);
			if (wr_size == -ENOMEM) {
				/*
				 * The smd channel is full. Delay while