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: Adrian 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: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
3cd3216dbb
commit
c7b4f15ff7
|
@ -1914,6 +1914,44 @@ static int intel_pt_process_switch(struct intel_pt *pt,
|
||||||
return machine__set_current_tid(pt->machine, cpu, -1, tid);
|
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,
|
static int intel_pt_context_switch(struct intel_pt *pt, union perf_event *event,
|
||||||
struct perf_sample *sample)
|
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 (pt->have_sched_switch == 3) {
|
||||||
if (!out)
|
if (!out)
|
||||||
return 0;
|
return intel_pt_context_switch_in(pt, sample);
|
||||||
if (event->header.type != PERF_RECORD_SWITCH_CPU_WIDE) {
|
if (event->header.type != PERF_RECORD_SWITCH_CPU_WIDE) {
|
||||||
pr_err("Expecting CPU-wide context switch event\n");
|
pr_err("Expecting CPU-wide context switch event\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
Loading…
Reference in New Issue