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

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

Merge "diag: Expand log mask buffer dynamically"

parents 1e044318 7dce0ec6
Loading
Loading
Loading
Loading
+63 −20
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include "diagfwd_cntl.h"
#include "diag_masks.h"
#include "diagfwd_peripheral.h"
#include "diag_ipc_logging.h"

#define ALL_EQUIP_ID		100
#define ALL_SSID		-1
@@ -132,9 +133,9 @@ static void diag_send_log_mask_update(uint8_t peripheral, int equip_id)
		ctrl_pkt.stream_id = 1;
		ctrl_pkt.status = log_mask.status;
		if (log_mask.status == DIAG_CTRL_MASK_VALID) {
			mask_size = LOG_ITEMS_TO_SIZE(mask->num_items);
			mask_size = LOG_ITEMS_TO_SIZE(mask->num_items_tools);
			ctrl_pkt.equip_id = i;
			ctrl_pkt.num_items = mask->num_items;
			ctrl_pkt.num_items = mask->num_items_tools;
			ctrl_pkt.log_mask_size = mask_size;
		}
		ctrl_pkt.data_len = LOG_MASK_CTRL_HEADER_LEN + mask_size;
@@ -156,6 +157,12 @@ static void diag_send_log_mask_update(uint8_t peripheral, int equip_id)
		if (mask_size > 0)
			memcpy(buf + header_len, mask->ptr, mask_size);
		mutex_unlock(&mask->lock);

		DIAG_LOG(DIAG_DEBUG_MASKS,
			 "sending ctrl pkt to %d, e %d num_items %d size %d\n",
			 peripheral, i, ctrl_pkt.num_items,
			 ctrl_pkt.log_mask_size);

		err = diagfwd_write(peripheral, TYPE_CNTL,
				    buf, header_len + mask_size);
		if (err && err != -ENODEV) {
@@ -868,7 +875,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
		if (log_item->equip_id != req->equip_id)
			continue;
		mutex_lock(&log_item->lock);
		mask_size = LOG_ITEMS_TO_SIZE(log_item->num_items);
		mask_size = LOG_ITEMS_TO_SIZE(log_item->num_items_tools);
		/*
		 * Make sure we have space to fill the response in the buffer.
		 * Destination buffer should atleast be able to hold equip_id
@@ -885,12 +892,16 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
		}
		*(uint32_t *)(dest_buf + write_len) = log_item->equip_id;
		write_len += sizeof(uint32_t);
		*(uint32_t *)(dest_buf + write_len) = log_item->num_items;
		*(uint32_t *)(dest_buf + write_len) = log_item->num_items_tools;
		write_len += sizeof(uint32_t);
		if (mask_size > 0) {
			memcpy(dest_buf + write_len, log_item->ptr, mask_size);
			write_len += mask_size;
		}
		DIAG_LOG(DIAG_DEBUG_MASKS,
			 "sending log e %d num_items %d size %d\n",
			 log_item->equip_id, log_item->num_items_tools,
			 log_item->range_tools);
		mutex_unlock(&log_item->lock);
		status = LOG_STATUS_SUCCESS;
		break;
@@ -929,7 +940,7 @@ static int diag_cmd_get_log_range(unsigned char *src_buf, int src_len,
	write_len += sizeof(rsp);

	for (i = 0; i < MAX_EQUIP_ID && write_len < dest_len; i++, mask++) {
		*(uint32_t *)(dest_buf + write_len) = mask->num_items;
		*(uint32_t *)(dest_buf + write_len) = mask->num_items_tools;
		write_len += sizeof(uint32_t);
	}

@@ -950,6 +961,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
	struct diag_log_mask_t *mask = (struct diag_log_mask_t *)log_mask.ptr;
	struct diag_log_config_req_t *req;
	struct diag_log_config_set_rsp_t rsp;
	unsigned char *temp_buf = NULL;

	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) {
		pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d",
@@ -965,27 +977,56 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
		       __func__, req->equip_id);
		status = LOG_STATUS_INVALID;
	}

	if (req->num_items == 0) {
		pr_err("diag: In %s, Invalid number of items in log mask request, equip_id: %d\n",
		       __func__, req->equip_id);
		status = LOG_STATUS_INVALID;
	}

	mutex_lock(&log_mask.lock);
	for (i = 0; i < MAX_EQUIP_ID && !status; i++, mask++) {
		if (mask->equip_id != req->equip_id)
			continue;
		mutex_lock(&mask->lock);
		if (req->num_items < mask->num_items)
			mask->num_items = req->num_items;
		mask_size = LOG_ITEMS_TO_SIZE(req->num_items);
		if (mask_size > mask->range) {

		DIAG_LOG(DIAG_DEBUG_MASKS, "e: %d current: %d %d new: %d %d",
			 mask->equip_id, mask->num_items_tools,
			 mask->range_tools, req->num_items,
			 LOG_ITEMS_TO_SIZE(req->num_items));
		/*
		 * If the size of the log mask cannot fit into our
		 * buffer, trim till we have space left in the buffer.
		 * num_items should then reflect the items that we have
		 * in our buffer.
		 */
			mask_size = mask->range;
			mask->num_items = LOG_SIZE_TO_ITEMS(mask_size);
			req->num_items = mask->num_items;
		mask->num_items_tools = (req->num_items > MAX_ITEMS_ALLOWED) ?
					MAX_ITEMS_ALLOWED : req->num_items;
		mask_size = LOG_ITEMS_TO_SIZE(mask->num_items_tools);
		memset(mask->ptr, 0, mask->range_tools);
		if (mask_size > mask->range_tools) {
			DIAG_LOG(DIAG_DEBUG_MASKS,
				 "log range mismatch, e: %d old: %d new: %d\n",
				 req->equip_id, mask->range_tools,
				 LOG_ITEMS_TO_SIZE(mask->num_items_tools));
			/* Change in the mask reported by tools */
			temp_buf = krealloc(mask->ptr, mask_size, GFP_KERNEL);
			if (!temp_buf) {
				log_mask.status = DIAG_CTRL_MASK_INVALID;
				mutex_unlock(&mask->lock);
				break;
			}
			mask->ptr = temp_buf;
			memset(mask->ptr, 0, mask_size);
			mask->range_tools = mask_size;
		}
		req->num_items = mask->num_items_tools;
		if (mask_size > 0)
			memcpy(mask->ptr, src_buf + read_len, mask_size);
		DIAG_LOG(DIAG_DEBUG_MASKS,
			 "copying log mask, e %d num %d range %d size %d\n",
			 req->equip_id, mask->num_items_tools,
			 mask->range_tools, mask_size);
		mutex_unlock(&mask->lock);
		log_mask.status = DIAG_CTRL_MASK_VALID;
		break;
@@ -998,7 +1039,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
	 * response.
	 */
	payload_len = LOG_ITEMS_TO_SIZE(req->num_items);
	if (payload_len + rsp_header_len > dest_len) {
	if ((payload_len + rsp_header_len > dest_len) || (payload_len == 0)) {
		pr_err("diag: In %s, invalid length, payload_len: %d, header_len: %d, dest_len: %d\n",
		       __func__, payload_len, rsp_header_len , dest_len);
		status = LOG_STATUS_FAIL;
@@ -1244,11 +1285,13 @@ static int diag_create_log_mask_table(void)
	for (i = 0; i < MAX_EQUIP_ID; i++, mask++) {
		mask->equip_id = i;
		mask->num_items = LOG_GET_ITEM_NUM(log_code_last_tbl[i]);
		mask->num_items_tools = mask->num_items;
		mutex_init(&mask->lock);
		if (LOG_ITEMS_TO_SIZE(mask->num_items) > MAX_ITEMS_PER_EQUIP_ID)
			mask->range = LOG_ITEMS_TO_SIZE(mask->num_items);
		else
			mask->range = MAX_ITEMS_PER_EQUIP_ID;
		mask->range_tools = mask->range;
		mask->ptr = kzalloc(mask->range, GFP_KERNEL);
		if (!mask->ptr) {
			err = -ENOMEM;
@@ -1488,7 +1531,7 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count)
		len = 0;
		mutex_lock(&mask->lock);
		header.equip_id = mask->equip_id;
		header.num_items = mask->num_items;
		header.num_items = mask->num_items_tools;
		memcpy(ptr, &header, sizeof(header));
		len += sizeof(header);
		copy_len = LOG_ITEMS_TO_SIZE(header.num_items);
+3 −0
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@
struct diag_log_mask_t {
	uint8_t equip_id;
	uint32_t num_items;
	uint32_t num_items_tools;
	uint32_t range;
	uint32_t range_tools;
	struct mutex lock;
	uint8_t *ptr;
};
@@ -126,6 +128,7 @@ struct diag_log_mask_userspace_t {
#define LOG_MASK_SIZE	(MAX_EQUIP_ID * sizeof(struct diag_log_mask_t))
#define EVENT_MASK_SIZE 513
#define MAX_ITEMS_PER_EQUIP_ID	512
#define MAX_ITEMS_ALLOWED	0xFFF

#define LOG_MASK_CTRL_HEADER_LEN	11
#define MSG_MASK_CTRL_HEADER_LEN	11
+4 −18
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "diag_dci.h"
#include "diagmem.h"
#include "diag_masks.h"
#include "diag_ipc_logging.h"

#define FEATURE_SUPPORTED(x)	((feature_mask << (i * 8)) & (1 << x))

@@ -409,8 +410,6 @@ static void process_log_range_report(uint8_t *buf, uint32_t len,
	int read_len = 0;
	int header_len = sizeof(struct diag_ctrl_log_range_report);
	uint8_t *ptr = buf;
	uint8_t *temp = NULL;
	uint32_t mask_size;
	struct diag_ctrl_log_range_report *header = NULL;
	struct diag_ctrl_log_range *log_range = NULL;
	struct diag_log_mask_t *mask_ptr = NULL;
@@ -436,23 +435,10 @@ static void process_log_range_report(uint8_t *buf, uint32_t len,
		}
		mask_ptr = (struct diag_log_mask_t *)log_mask.ptr;
		mask_ptr = &mask_ptr[log_range->equip_id];
		mutex_lock(&(mask_ptr->lock));
		mask_size = LOG_ITEMS_TO_SIZE(log_range->num_items);
		if (mask_size < mask_ptr->range)
			goto proceed;

		temp = krealloc(mask_ptr->ptr, mask_size, GFP_KERNEL);
		if (!temp) {
			pr_err("diag: In %s, Unable to reallocate log mask ptr to size: %d, equip_id: %d\n",
			       __func__, mask_size, log_range->equip_id);
			mutex_unlock(&(mask_ptr->lock));
			continue;
		}
		mask_ptr->ptr = temp;
		mask_ptr->range = mask_size;
proceed:
		if (log_range->num_items > mask_ptr->num_items)
		mutex_lock(&(mask_ptr->lock));
		mask_ptr->num_items = log_range->num_items;
		mask_ptr->range = LOG_ITEMS_TO_SIZE(log_range->num_items);
		mutex_unlock(&(mask_ptr->lock));
	}
}