tools/perf/util/cs-etm.c

Source file repositories/reference/linux-study-clean/tools/perf/util/cs-etm.c

File Facts

System
Linux kernel
Corpus path
tools/perf/util/cs-etm.c
Extension
.c
Size
102244 bytes
Lines
3568
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

event->context_switch.next_prev_pid,
				     event->context_switch.next_prev_tid);
	if (!th)
		return -ENOMEM;

	thread__put(th);

	return 0;
}

static int cs_etm__process_event(struct perf_session *session,
				 union perf_event *event,
				 struct perf_sample *sample,
				 const struct perf_tool *tool)
{
	struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
						   struct cs_etm_auxtrace,
						   auxtrace);

	if (dump_trace)
		return 0;

	if (!tool->ordered_events) {
		pr_err("CoreSight ETM Trace requires ordered events\n");
		return -EINVAL;
	}

	switch (event->header.type) {
	case PERF_RECORD_EXIT:
		/*
		 * Don't need to wait for cs_etm__flush_events() in per-thread mode to
		 * start the decode because we know there will be no more trace from
		 * this thread. All this does is emit samples earlier than waiting for
		 * the flush in other modes, but with timestamps it makes sense to wait
		 * for flush so that events from different threads are interleaved
		 * properly.
		 */
		if (etm->per_thread_decoding && etm->timeless_decoding)
			return cs_etm__process_timeless_queues(etm,
							       event->fork.tid);
		break;

	case PERF_RECORD_ITRACE_START:
		return cs_etm__process_itrace_start(etm, event);

	case PERF_RECORD_SWITCH_CPU_WIDE:
		return cs_etm__process_switch_cpu_wide(etm, event);

	case PERF_RECORD_AUX:
		/*
		 * Record the latest kernel timestamp available in the header
		 * for samples so that synthesised samples occur from this point
		 * onwards.
		 */
		if (sample->time && (sample->time != (u64)-1))
			etm->latest_kernel_timestamp = sample->time;
		break;

	default:
		break;
	}

	return 0;
}

static void dump_queued_data(struct cs_etm_auxtrace *etm,
			     struct perf_record_auxtrace *event)
{
	struct auxtrace_buffer *buf;
	unsigned int i;
	/*
	 * Find all buffers with same reference in the queues and dump them.
	 * This is because the queues can contain multiple entries of the same
	 * buffer that were split on aux records.
	 */
	for (i = 0; i < etm->queues.nr_queues; ++i)
		list_for_each_entry(buf, &etm->queues.queue_array[i].head, list)
			if (buf->reference == event->reference)
				cs_etm__dump_event(etm->queues.queue_array[i].priv, buf);
}

static int cs_etm__process_auxtrace_event(struct perf_session *session,
					  union perf_event *event,
					  const struct perf_tool *tool __maybe_unused)
{
	struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
						   struct cs_etm_auxtrace,
						   auxtrace);
	if (!etm->data_queued) {
		struct auxtrace_buffer *buffer;

Annotation

Implementation Notes