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

Commit 7ec17b77 authored by Carter Cooper's avatar Carter Cooper
Browse files

msm: kgsl: Update profile print results on error cases



There are some fun error cases that can occur that are not
being handled correctly. For example if the log data gets
corrupted or has invalid data in it, the log parser will fail
and incorrectly update where it is in the log data. Instead
of failing and leaving the log data in an incomplete state,
put the log data in a known state before failing.

Change-Id: I46d361ec998b157086240bf54364dcf9a26bc650
Signed-off-by: default avatarCarter Cooper <ccooper@codeaurora.org>
parent 339d08e5
Loading
Loading
Loading
Loading
+46 −16
Original line number Diff line number Diff line
@@ -219,15 +219,21 @@ static inline void log_buf_wrapcnt(unsigned int cnt, uintptr_t *off)
	*off = (*off + cnt) % ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS;
}

static inline void log_buf_wrapinc(unsigned int *profile_log_buffer,
		unsigned int **ptr)
static inline void log_buf_wrapinc_len(unsigned int *profile_log_buffer,
		unsigned int **ptr, unsigned int len)
{
	*ptr += 1;
	*ptr += len;
	if (*ptr >= (profile_log_buffer +
				ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS))
		*ptr -= ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS;
}

static inline void log_buf_wrapinc(unsigned int *profile_log_buffer,
		unsigned int **ptr)
{
	log_buf_wrapinc_len(profile_log_buffer, ptr, 1);
}

static inline unsigned int log_buf_available(struct adreno_profile *profile,
		unsigned int *head_ptr)
{
@@ -755,7 +761,7 @@ static int _pipe_print_results(struct adreno_device *adreno_dev,
	struct adreno_profile *profile = &adreno_dev->profile;
	const char *grp_name;
	char *usr_buf = ubuf;
	unsigned int *log_ptr = NULL;
	unsigned int *log_ptr = NULL, *tmp_log_ptr = NULL;
	int len, i;
	int status = 0;
	ssize_t size, total_size = 0;
@@ -772,14 +778,26 @@ static int _pipe_print_results(struct adreno_device *adreno_dev,

	do {
		cnt = *log_ptr & 0xffff;

		/* store the tmp var for error cases so we can skip */
		tmp_log_ptr = log_ptr;

		/* Too many to output to pipe, so skip this data */
		if (SIZE_PIPE_ENTRY(cnt) > max) {
			status = 0;
			goto err;
			log_buf_wrapinc_len(profile->log_buffer,
				&tmp_log_ptr, SIZE_PIPE_ENTRY(cnt));
			log_ptr = tmp_log_ptr;
			goto done;
		}

		/*
		 * Not enough space left in pipe, return without doing
		 * anything
		 */
		if ((max - (usr_buf - ubuf)) < SIZE_PIPE_ENTRY(cnt))
			break;
			goto done;

		api_type = *log_ptr >> 16;
		api_type = (*log_ptr >> 16) & 0xffff;
		api_str = get_api_type_str(api_type);
		log_buf_wrapinc(profile->log_buffer, &log_ptr);
		pid = *log_ptr;
@@ -796,9 +814,13 @@ static int _pipe_print_results(struct adreno_device *adreno_dev,
		size = simple_read_from_buffer(usr_buf,
				max - (usr_buf - ubuf),
				&unused, pipe_hdr_buf, len);

		/* non-fatal error, so skip rest of entry and return */
		if (size < 0) {
			status = -EINVAL;
			goto err;
			log_buf_wrapinc_len(profile->log_buffer,
				&tmp_log_ptr, SIZE_PIPE_ENTRY(cnt));
			log_ptr = tmp_log_ptr;
			goto done;
		}

		unused = 0;
@@ -807,10 +829,14 @@ static int _pipe_print_results(struct adreno_device *adreno_dev,

		for (i = 0; i < cnt; i++) {
			grp_name = adreno_perfcounter_get_name(
					adreno_dev, *log_ptr >> 16);
					adreno_dev, (*log_ptr >> 16) & 0xffff);

			/* non-fatal error, so skip rest of entry and return */
			if (grp_name == NULL) {
				status = -EFAULT;
				goto err;
				log_buf_wrapinc_len(profile->log_buffer,
					&tmp_log_ptr, SIZE_PIPE_ENTRY(cnt));
				log_ptr = tmp_log_ptr;
				goto done;
			}

			if (i == cnt - 1)
@@ -836,9 +862,13 @@ static int _pipe_print_results(struct adreno_device *adreno_dev,
			size = simple_read_from_buffer(usr_buf,
					max - (usr_buf - ubuf),
					&unused, pipe_cntr_buf, len);

			/* non-fatal error, so skip rest of entry and return */
			if (size < 0) {
				status = size;
				goto err;
				log_buf_wrapinc_len(profile->log_buffer,
					&tmp_log_ptr, SIZE_PIPE_ENTRY(cnt));
				log_ptr = tmp_log_ptr;
				goto done;
			}
			unused = 0;
			usr_buf += size;
@@ -846,8 +876,8 @@ static int _pipe_print_results(struct adreno_device *adreno_dev,
		}
	} while (log_ptr != profile->log_head);

done:
	status = total_size;
err:
	profile->log_tail = log_ptr;

	return status;