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

Commit e70ea75d authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "diag: dci: Add mutex protection while accessing client details"

parents ccf844af dd93fd94
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -343,6 +343,7 @@ void diag_dci_wakeup_clients()
	struct list_head *start, *temp;
	struct diag_dci_client_tbl *entry = NULL;

	mutex_lock(&driver->dci_mutex);
	list_for_each_safe(start, temp, &driver->dci_client_list) {
		entry = list_entry(start, struct diag_dci_client_tbl, track);

@@ -358,6 +359,7 @@ void diag_dci_wakeup_clients()
						     DCI_DATA_TYPE);
		}
	}
	mutex_unlock(&driver->dci_mutex);
}

void dci_data_drain_work_fn(struct work_struct *work)
@@ -368,6 +370,7 @@ void dci_data_drain_work_fn(struct work_struct *work)
	struct diag_dci_buf_peripheral_t *proc_buf = NULL;
	struct diag_dci_buffer_t *buf_temp = NULL;

	mutex_lock(&driver->dci_mutex);
	list_for_each_safe(start, temp, &driver->dci_client_list) {
		entry = list_entry(start, struct diag_dci_client_tbl, track);
		for (i = 0; i < entry->num_buffers; i++) {
@@ -397,6 +400,7 @@ void dci_data_drain_work_fn(struct work_struct *work)
						     DCI_DATA_TYPE);
		}
	}
	mutex_unlock(&driver->dci_mutex);
	dci_timer_in_progress = 0;
}

@@ -562,6 +566,8 @@ start:
		buf += header_len + dci_pkt_len; /* advance to next DCI pkt */
	}
end:
	if (err)
		return;
	/* wake up all sleeping DCI clients which have some data */
	diag_dci_wakeup_clients();
	dci_check_drain_timer();
@@ -623,6 +629,8 @@ void diag_dci_process_peripheral_data(struct diagfwd_info *p_info, void *buf,
		buf += 5 + dci_pkt_len; /* advance to next DCI pkt */
	}

	if (err)
		return;
	/* wake up all sleeping DCI clients which have some data */
	diag_dci_wakeup_clients();
	dci_check_drain_timer();
@@ -970,9 +978,11 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
		return;
	}

	mutex_lock(&driver->dci_mutex);
	req_entry = diag_dci_get_request_entry(tag);
	if (!req_entry) {
		pr_err("diag: No matching client for DCI data\n");
		pr_err_ratelimited("diag: No matching client for DCI data\n");
		mutex_unlock(&driver->dci_mutex);
		return;
	}

@@ -980,18 +990,17 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
	if (!entry) {
		pr_err("diag: In %s, couldn't find client entry, id:%d\n",
						__func__, req_entry->client_id);
		mutex_unlock(&driver->dci_mutex);
		return;
	}

	save_req_uid = req_entry->uid;
	/* Remove the headers and send only the response to this function */
	mutex_lock(&driver->dci_mutex);
	delete_flag = diag_dci_remove_req_entry(temp, rsp_len, req_entry);
	if (delete_flag < 0) {
		mutex_unlock(&driver->dci_mutex);
		return;
	}
	mutex_unlock(&driver->dci_mutex);

	mutex_lock(&entry->buffers[data_source].buf_mutex);
	rsp_buf = entry->buffers[data_source].buf_cmd;
@@ -1011,6 +1020,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
			pr_err("diag: DCI realloc failed\n");
			mutex_unlock(&rsp_buf->data_mutex);
			mutex_unlock(&entry->buffers[data_source].buf_mutex);
			mutex_unlock(&driver->dci_mutex);
			return;
		} else {
			rsp_buf->data = temp_buf;
@@ -1039,6 +1049,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
	 */
	dci_add_buffer_to_list(entry, rsp_buf);
	mutex_unlock(&entry->buffers[data_source].buf_mutex);
	mutex_unlock(&driver->dci_mutex);
}

static void copy_dci_event(unsigned char *buf, int len,
@@ -1174,6 +1185,7 @@ void extract_dci_events(unsigned char *buf, int len, int data_source, int token)
		   the event data */
		total_event_len = 2 + 10 + payload_len_field + payload_len;
		/* parse through event mask tbl of each client and check mask */
		mutex_lock(&driver->dci_mutex);
		list_for_each_safe(start, temp, &driver->dci_client_list) {
			entry = list_entry(start, struct diag_dci_client_tbl,
									track);
@@ -1185,6 +1197,7 @@ void extract_dci_events(unsigned char *buf, int len, int data_source, int token)
					       entry, data_source);
			}
		}
		mutex_unlock(&driver->dci_mutex);
	}
}

@@ -1276,6 +1289,7 @@ void extract_dci_log(unsigned char *buf, int len, int data_source, int token)
	}

	/* parse through log mask table of each client and check mask */
	mutex_lock(&driver->dci_mutex);
	list_for_each_safe(start, temp, &driver->dci_client_list) {
		entry = list_entry(start, struct diag_dci_client_tbl, track);
		if (entry->client_info.token != token)
@@ -1287,6 +1301,7 @@ void extract_dci_log(unsigned char *buf, int len, int data_source, int token)
			copy_dci_log(buf, len, entry, data_source);
		}
	}
	mutex_unlock(&driver->dci_mutex);
}

void diag_dci_channel_open_work(struct work_struct *work)
+23 −9
Original line number Diff line number Diff line
@@ -2393,7 +2393,10 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
		goto exit;
	}

exit:
	mutex_unlock(&driver->diagchar_mutex);
	if (driver->data_ready[index] & DCI_DATA_TYPE) {
		mutex_lock(&driver->dci_mutex);
		/* Copy the type of data being passed */
		data_type = driver->data_ready[index] & DCI_DATA_TYPE;
		list_for_each_safe(start, temp, &driver->dci_client_list) {
@@ -2403,20 +2406,31 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
				continue;
			if (!entry->in_service)
				continue;
			COPY_USER_SPACE_OR_EXIT(buf + ret, data_type,
								sizeof(int));
			COPY_USER_SPACE_OR_EXIT(buf + ret,
					entry->client_info.token, sizeof(int));
			if (copy_to_user(buf + ret, &data_type, sizeof(int))) {
				mutex_unlock(&driver->dci_mutex);
				goto end;
			}
			ret += sizeof(int);
			if (copy_to_user(buf + ret, &entry->client_info.token,
				sizeof(int))) {
				mutex_unlock(&driver->dci_mutex);
				goto end;
			}
			ret += sizeof(int);
			copy_dci_data = 1;
			exit_stat = diag_copy_dci(buf, count, entry, &ret);
			mutex_lock(&driver->diagchar_mutex);
			driver->data_ready[index] ^= DCI_DATA_TYPE;
			if (exit_stat == 1)
				goto exit;
			mutex_unlock(&driver->diagchar_mutex);
			if (exit_stat == 1) {
				mutex_unlock(&driver->dci_mutex);
				goto end;
			}
		goto exit;
		}
exit:
	mutex_unlock(&driver->diagchar_mutex);
		mutex_unlock(&driver->dci_mutex);
		goto end;
	}
end:
	/*
	 * Flush any read that is currently pending on DCI data and
	 * command channnels. This will ensure that the next read is not