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

Commit f4c0b0aa authored by Will Deacon's avatar Will Deacon Committed by Ingo Molnar
Browse files

perf/core: Keep AUX flags in the output handle



In preparation for adding more flags to perf AUX records, introduce a
separate API for setting the flags for a session, rather than appending
more bool arguments to perf_aux_output_end. This allows to set each
flag at the time a corresponding condition is detected, instead of
tracking it in each driver's private state.

Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarAlexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: vince@deater.net
Link: http://lkml.kernel.org/r/20170220133352.17995-3-alexander.shishkin@linux.intel.com


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent ed827adb
Loading
Loading
Loading
Loading
+7 −9
Original line number Original line Diff line number Diff line
@@ -63,7 +63,6 @@ struct bts_buffer {
	unsigned int	cur_buf;
	unsigned int	cur_buf;
	bool		snapshot;
	bool		snapshot;
	local_t		data_size;
	local_t		data_size;
	local_t		lost;
	local_t		head;
	local_t		head;
	unsigned long	end;
	unsigned long	end;
	void		**data_pages;
	void		**data_pages;
@@ -199,7 +198,8 @@ static void bts_update(struct bts_ctx *bts)
			return;
			return;


		if (ds->bts_index >= ds->bts_absolute_maximum)
		if (ds->bts_index >= ds->bts_absolute_maximum)
			local_inc(&buf->lost);
			perf_aux_output_flag(&bts->handle,
			                     PERF_AUX_FLAG_TRUNCATED);


		/*
		/*
		 * old and head are always in the same physical buffer, so we
		 * old and head are always in the same physical buffer, so we
@@ -276,7 +276,7 @@ static void bts_event_start(struct perf_event *event, int flags)
	return;
	return;


fail_end_stop:
fail_end_stop:
	perf_aux_output_end(&bts->handle, 0, false);
	perf_aux_output_end(&bts->handle, 0);


fail_stop:
fail_stop:
	event->hw.state = PERF_HES_STOPPED;
	event->hw.state = PERF_HES_STOPPED;
@@ -319,9 +319,8 @@ static void bts_event_stop(struct perf_event *event, int flags)
				bts->handle.head =
				bts->handle.head =
					local_xchg(&buf->data_size,
					local_xchg(&buf->data_size,
						   buf->nr_pages << PAGE_SHIFT);
						   buf->nr_pages << PAGE_SHIFT);

			perf_aux_output_end(&bts->handle,
			perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
			                    local_xchg(&buf->data_size, 0));
					    !!local_xchg(&buf->lost, 0));
		}
		}


		cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
		cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
@@ -484,8 +483,7 @@ int intel_bts_interrupt(void)
	if (old_head == local_read(&buf->head))
	if (old_head == local_read(&buf->head))
		return handled;
		return handled;


	perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
	perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0));
			    !!local_xchg(&buf->lost, 0));


	buf = perf_aux_output_begin(&bts->handle, event);
	buf = perf_aux_output_begin(&bts->handle, event);
	if (buf)
	if (buf)
@@ -500,7 +498,7 @@ int intel_bts_interrupt(void)
			 * cleared handle::event
			 * cleared handle::event
			 */
			 */
			barrier();
			barrier();
			perf_aux_output_end(&bts->handle, 0, false);
			perf_aux_output_end(&bts->handle, 0);
		}
		}
	}
	}


+9 −8
Original line number Original line Diff line number Diff line
@@ -753,7 +753,8 @@ static void pt_handle_status(struct pt *pt)
		 */
		 */
		if (!pt_cap_get(PT_CAP_topa_multiple_entries) ||
		if (!pt_cap_get(PT_CAP_topa_multiple_entries) ||
		    buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
		    buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
			local_inc(&buf->lost);
			perf_aux_output_flag(&pt->handle,
			                     PERF_AUX_FLAG_TRUNCATED);
			advance++;
			advance++;
		}
		}
	}
	}
@@ -846,8 +847,10 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,


	/* can't stop in the middle of an output region */
	/* can't stop in the middle of an output region */
	if (buf->output_off + handle->size + 1 <
	if (buf->output_off + handle->size + 1 <
	    sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size))
	    sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
		return -EINVAL;
		return -EINVAL;
	}




	/* single entry ToPA is handled by marking all regions STOP=1 INT=1 */
	/* single entry ToPA is handled by marking all regions STOP=1 INT=1 */
@@ -1192,8 +1195,7 @@ void intel_pt_interrupt(void)


	pt_update_head(pt);
	pt_update_head(pt);


	perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
	perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0));
			    local_xchg(&buf->lost, 0));


	if (!event->hw.state) {
	if (!event->hw.state) {
		int ret;
		int ret;
@@ -1208,7 +1210,7 @@ void intel_pt_interrupt(void)
		/* snapshot counters don't use PMI, so it's safe */
		/* snapshot counters don't use PMI, so it's safe */
		ret = pt_buffer_reset_markers(buf, &pt->handle);
		ret = pt_buffer_reset_markers(buf, &pt->handle);
		if (ret) {
		if (ret) {
			perf_aux_output_end(&pt->handle, 0, true);
			perf_aux_output_end(&pt->handle, 0);
			return;
			return;
		}
		}


@@ -1280,7 +1282,7 @@ static void pt_event_start(struct perf_event *event, int mode)
	return;
	return;


fail_end_stop:
fail_end_stop:
	perf_aux_output_end(&pt->handle, 0, true);
	perf_aux_output_end(&pt->handle, 0);
fail_stop:
fail_stop:
	hwc->state = PERF_HES_STOPPED;
	hwc->state = PERF_HES_STOPPED;
}
}
@@ -1321,8 +1323,7 @@ static void pt_event_stop(struct perf_event *event, int mode)
			pt->handle.head =
			pt->handle.head =
				local_xchg(&buf->data_size,
				local_xchg(&buf->data_size,
					   buf->nr_pages << PAGE_SHIFT);
					   buf->nr_pages << PAGE_SHIFT);
		perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
		perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0));
				    local_xchg(&buf->lost, 0));
	}
	}
}
}


+0 −1
Original line number Original line Diff line number Diff line
@@ -143,7 +143,6 @@ struct pt_buffer {
	size_t			output_off;
	size_t			output_off;
	unsigned long		nr_pages;
	unsigned long		nr_pages;
	local_t			data_size;
	local_t			data_size;
	local_t			lost;
	local64_t		head;
	local64_t		head;
	bool			snapshot;
	bool			snapshot;
	unsigned long		stop_pos, intr_pos;
	unsigned long		stop_pos, intr_pos;
+4 −5
Original line number Original line Diff line number Diff line
@@ -321,7 +321,7 @@ static int etb_set_buffer(struct coresight_device *csdev,


static unsigned long etb_reset_buffer(struct coresight_device *csdev,
static unsigned long etb_reset_buffer(struct coresight_device *csdev,
				      struct perf_output_handle *handle,
				      struct perf_output_handle *handle,
				      void *sink_config, bool *lost)
				      void *sink_config)
{
{
	unsigned long size = 0;
	unsigned long size = 0;
	struct cs_buffers *buf = sink_config;
	struct cs_buffers *buf = sink_config;
@@ -343,7 +343,6 @@ static unsigned long etb_reset_buffer(struct coresight_device *csdev,
		 * resetting parameters here and squaring off with the ring
		 * resetting parameters here and squaring off with the ring
		 * buffer API in the tracer PMU is fine.
		 * buffer API in the tracer PMU is fine.
		 */
		 */
		*lost = !!local_xchg(&buf->lost, 0);
		size = local_xchg(&buf->data_size, 0);
		size = local_xchg(&buf->data_size, 0);
	}
	}


@@ -385,7 +384,7 @@ static void etb_update_buffer(struct coresight_device *csdev,
			(unsigned long)write_ptr);
			(unsigned long)write_ptr);


		write_ptr &= ~(ETB_FRAME_SIZE_WORDS - 1);
		write_ptr &= ~(ETB_FRAME_SIZE_WORDS - 1);
		local_inc(&buf->lost);
		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
	}
	}


	/*
	/*
@@ -396,7 +395,7 @@ static void etb_update_buffer(struct coresight_device *csdev,
	 */
	 */
	status = readl_relaxed(drvdata->base + ETB_STATUS_REG);
	status = readl_relaxed(drvdata->base + ETB_STATUS_REG);
	if (status & ETB_STATUS_RAM_FULL) {
	if (status & ETB_STATUS_RAM_FULL) {
		local_inc(&buf->lost);
		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
		to_read = capacity;
		to_read = capacity;
		read_ptr = write_ptr;
		read_ptr = write_ptr;
	} else {
	} else {
@@ -429,7 +428,7 @@ static void etb_update_buffer(struct coresight_device *csdev,
		if (read_ptr > (drvdata->buffer_depth - 1))
		if (read_ptr > (drvdata->buffer_depth - 1))
			read_ptr -= drvdata->buffer_depth;
			read_ptr -= drvdata->buffer_depth;
		/* let the decoder know we've skipped ahead */
		/* let the decoder know we've skipped ahead */
		local_inc(&buf->lost);
		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
	}
	}


	/* finally tell HW where we want to start reading from */
	/* finally tell HW where we want to start reading from */
+4 −5
Original line number Original line Diff line number Diff line
@@ -302,7 +302,8 @@ static void etm_event_start(struct perf_event *event, int flags)
	return;
	return;


fail_end_stop:
fail_end_stop:
	perf_aux_output_end(handle, 0, true);
	perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
	perf_aux_output_end(handle, 0);
fail:
fail:
	event->hw.state = PERF_HES_STOPPED;
	event->hw.state = PERF_HES_STOPPED;
	goto out;
	goto out;
@@ -310,7 +311,6 @@ static void etm_event_start(struct perf_event *event, int flags)


static void etm_event_stop(struct perf_event *event, int mode)
static void etm_event_stop(struct perf_event *event, int mode)
{
{
	bool lost;
	int cpu = smp_processor_id();
	int cpu = smp_processor_id();
	unsigned long size;
	unsigned long size;
	struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
	struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
@@ -348,10 +348,9 @@ static void etm_event_stop(struct perf_event *event, int mode)
			return;
			return;


		size = sink_ops(sink)->reset_buffer(sink, handle,
		size = sink_ops(sink)->reset_buffer(sink, handle,
						    event_data->snk_config,
						    event_data->snk_config);
						    &lost);


		perf_aux_output_end(handle, size, lost);
		perf_aux_output_end(handle, size);
	}
	}


	/* Disabling the path make its elements available to other sessions */
	/* Disabling the path make its elements available to other sessions */
Loading