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

Commit da9000ae authored by Adrian Hunter's avatar Adrian Hunter Committed by Arnaldo Carvalho de Melo
Browse files

perf intel-pt: Add support for lookahead



Implement the lookahead callback to let the decoder access subsequent
buffers. intel_pt_lookahead() manages the buffer lifetime and calls the
decoder for each buffer until the decoder returns a non-zero value.

Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Cc: Jin Yao <yao.jin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20190604130017.31207-11-adrian.hunter@intel.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent e96f7df8
Loading
Loading
Loading
Loading
+58 −1
Original line number Diff line number Diff line
@@ -278,7 +278,63 @@ static int intel_pt_get_buffer(struct intel_pt_queue *ptq,
	return 0;
}

/* This function assumes data is processed sequentially only */
/* Do not drop buffers with references - refer intel_pt_get_trace() */
static void intel_pt_lookahead_drop_buffer(struct intel_pt_queue *ptq,
					   struct auxtrace_buffer *buffer)
{
	if (!buffer || buffer == ptq->buffer || buffer == ptq->old_buffer)
		return;

	auxtrace_buffer__drop_data(buffer);
}

/* Must be serialized with respect to intel_pt_get_trace() */
static int intel_pt_lookahead(void *data, intel_pt_lookahead_cb_t cb,
			      void *cb_data)
{
	struct intel_pt_queue *ptq = data;
	struct auxtrace_buffer *buffer = ptq->buffer;
	struct auxtrace_buffer *old_buffer = ptq->old_buffer;
	struct auxtrace_queue *queue;
	int err = 0;

	queue = &ptq->pt->queues.queue_array[ptq->queue_nr];

	while (1) {
		struct intel_pt_buffer b = { .len = 0 };

		buffer = auxtrace_buffer__next(queue, buffer);
		if (!buffer)
			break;

		err = intel_pt_get_buffer(ptq, buffer, old_buffer, &b);
		if (err)
			break;

		if (b.len) {
			intel_pt_lookahead_drop_buffer(ptq, old_buffer);
			old_buffer = buffer;
		} else {
			intel_pt_lookahead_drop_buffer(ptq, buffer);
			continue;
		}

		err = cb(&b, cb_data);
		if (err)
			break;
	}

	if (buffer != old_buffer)
		intel_pt_lookahead_drop_buffer(ptq, buffer);
	intel_pt_lookahead_drop_buffer(ptq, old_buffer);

	return err;
}

/*
 * This function assumes data is processed sequentially only.
 * Must be serialized with respect to intel_pt_lookahead()
 */
static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data)
{
	struct intel_pt_queue *ptq = data;
@@ -827,6 +883,7 @@ static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt,

	params.get_trace = intel_pt_get_trace;
	params.walk_insn = intel_pt_walk_next_insn;
	params.lookahead = intel_pt_lookahead;
	params.data = ptq;
	params.return_compression = intel_pt_return_compression(pt);
	params.branch_enable = intel_pt_branch_enable(pt);