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

perf intel-pt: Improve sync_switch by processing PERF_RECORD_SWITCH* in events



sync_switch is a facility to synchronize decoding more closely with the
point in the kernel when the context actually switched.

Improve it by processing "context switch in" events.

Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20190412113830.4126-8-adrian.hunter@intel.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 3cd3216d
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
@@ -1914,6 +1914,44 @@ static int intel_pt_process_switch(struct intel_pt *pt,
	return machine__set_current_tid(pt->machine, cpu, -1, tid);
}

static int intel_pt_context_switch_in(struct intel_pt *pt,
				      struct perf_sample *sample)
{
	pid_t pid = sample->pid;
	pid_t tid = sample->tid;
	int cpu = sample->cpu;

	if (pt->sync_switch) {
		struct intel_pt_queue *ptq;

		ptq = intel_pt_cpu_to_ptq(pt, cpu);
		if (ptq && ptq->sync_switch) {
			ptq->next_tid = -1;
			switch (ptq->switch_state) {
			case INTEL_PT_SS_NOT_TRACING:
			case INTEL_PT_SS_UNKNOWN:
			case INTEL_PT_SS_TRACING:
				break;
			case INTEL_PT_SS_EXPECTING_SWITCH_EVENT:
			case INTEL_PT_SS_EXPECTING_SWITCH_IP:
				ptq->switch_state = INTEL_PT_SS_TRACING;
				break;
			default:
				break;
			}
		}
	}

	/*
	 * If the current tid has not been updated yet, ensure it is now that
	 * a "switch in" event has occurred.
	 */
	if (machine__get_current_tid(pt->machine, cpu) == tid)
		return 0;

	return machine__set_current_tid(pt->machine, cpu, pid, tid);
}

static int intel_pt_context_switch(struct intel_pt *pt, union perf_event *event,
				   struct perf_sample *sample)
{
@@ -1925,7 +1963,7 @@ static int intel_pt_context_switch(struct intel_pt *pt, union perf_event *event,

	if (pt->have_sched_switch == 3) {
		if (!out)
			return 0;
			return intel_pt_context_switch_in(pt, sample);
		if (event->header.type != PERF_RECORD_SWITCH_CPU_WIDE) {
			pr_err("Expecting CPU-wide context switch event\n");
			return -EINVAL;