mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-27 22:53:55 +08:00
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user