diff options
Diffstat (limited to 'tools/perf/util/cs-etm.c')
-rw-r--r-- | tools/perf/util/cs-etm.c | 118 |
1 files changed, 38 insertions, 80 deletions
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 416f2ddc3895..83881c80ea06 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -46,8 +46,6 @@ struct cs_etm_auxtrace { struct auxtrace_heap heap; struct itrace_synth_opts synth_opts; struct perf_session *session; - struct machine *machine; - struct thread *unknown_thread; struct perf_tsc_conversion tc; /* @@ -84,7 +82,6 @@ struct cs_etm_auxtrace { struct cs_etm_traceid_queue { u8 trace_chan_id; - pid_t pid, tid; u64 period_instructions; size_t last_branch_pos; union perf_event *event_buf; @@ -480,9 +477,9 @@ static int cs_etm__init_traceid_queue(struct cs_etm_queue *etmq, cs_etm__clear_packet_queue(&tidq->packet_queue); queue = &etmq->etm->queues.queue_array[etmq->queue_nr]; - tidq->tid = queue->tid; - tidq->pid = -1; tidq->trace_chan_id = trace_chan_id; + tidq->thread = machine__findnew_thread(&etm->session->machines.host, -1, + queue->tid); tidq->packet = zalloc(sizeof(struct cs_etm_packet)); if (!tidq->packet) @@ -863,7 +860,6 @@ static void cs_etm__free(struct perf_session *session) for (i = 0; i < aux->num_cpu; i++) zfree(&aux->metadata[i]); - thread__zput(aux->unknown_thread); zfree(&aux->metadata); zfree(&aux); } @@ -882,7 +878,7 @@ static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address) { struct machine *machine; - machine = etmq->etm->machine; + machine = &etmq->etm->session->machines.host; if (address >= machine__kernel_start(machine)) { if (machine__is_host(machine)) @@ -905,8 +901,6 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id, u8 cpumode; u64 offset; int len; - struct thread *thread; - struct machine *machine; struct addr_location al; struct dso *dso; struct cs_etm_traceid_queue *tidq; @@ -916,20 +910,12 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id, return 0; addr_location__init(&al); - machine = etmq->etm->machine; cpumode = cs_etm__cpu_mode(etmq, address); tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id); if (!tidq) goto out; - thread = tidq->thread; - if (!thread) { - if (cpumode != PERF_RECORD_MISC_KERNEL) - goto out; - thread = etmq->etm->unknown_thread; - } - - if (!thread__find_map(thread, cpumode, address, &al)) + if (!thread__find_map(tidq->thread, cpumode, address, &al)) goto out; dso = map__dso(al.map); @@ -944,7 +930,8 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id, map__load(al.map); - len = dso__data_read_offset(dso, machine, offset, buffer, size); + len = dso__data_read_offset(dso, maps__machine(thread__maps(tidq->thread)), + offset, buffer, size); if (len <= 0) { ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' or debuginfod to export data from the traced system.\n" @@ -1307,39 +1294,31 @@ cs_etm__get_trace(struct cs_etm_queue *etmq) return etmq->buf_len; } -static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm, - struct cs_etm_traceid_queue *tidq) +static void cs_etm__set_thread(struct cs_etm_auxtrace *etm, + struct cs_etm_traceid_queue *tidq, pid_t tid) { - if ((!tidq->thread) && (tidq->tid != -1)) - tidq->thread = machine__find_thread(etm->machine, -1, - tidq->tid); + struct machine *machine = &etm->session->machines.host; + + if (tid != -1) { + thread__zput(tidq->thread); + tidq->thread = machine__find_thread(machine, -1, tid); + } - if (tidq->thread) - tidq->pid = thread__pid(tidq->thread); + /* Couldn't find a known thread */ + if (!tidq->thread) + tidq->thread = machine__idle_thread(machine); } int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq, pid_t tid, u8 trace_chan_id) { - int cpu, err = -EINVAL; - struct cs_etm_auxtrace *etm = etmq->etm; struct cs_etm_traceid_queue *tidq; tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id); if (!tidq) - return err; - - if (cs_etm__get_cpu(trace_chan_id, &cpu) < 0) - return err; - - err = machine__set_current_tid(etm->machine, cpu, tid, tid); - if (err) - return err; - - tidq->tid = tid; - thread__zput(tidq->thread); + return -EINVAL; - cs_etm__set_pid_tid_cpu(etm, tidq); + cs_etm__set_thread(etmq->etm, tidq, tid); return 0; } @@ -1416,8 +1395,8 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq, sample.time = cs_etm__resolve_sample_time(etmq, tidq); sample.ip = addr; - sample.pid = tidq->pid; - sample.tid = tidq->tid; + sample.pid = thread__pid(tidq->thread); + sample.tid = thread__tid(tidq->thread); sample.id = etmq->etm->instructions_id; sample.stream_id = etmq->etm->instructions_id; sample.period = period; @@ -1475,8 +1454,8 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq, sample.time = cs_etm__resolve_sample_time(etmq, tidq); sample.ip = ip; - sample.pid = tidq->pid; - sample.tid = tidq->tid; + sample.pid = thread__pid(tidq->thread); + sample.tid = thread__tid(tidq->thread); sample.addr = cs_etm__first_executed_instr(tidq->packet); sample.id = etmq->etm->branches_id; sample.stream_id = etmq->etm->branches_id; @@ -2470,11 +2449,6 @@ static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm, if (!etmq) continue; - /* - * Per-cpu mode has contextIDs in the trace and the decoder - * calls cs_etm__set_pid_tid_cpu() automatically so no need - * to do this here - */ if (etm->per_thread_decoding) { tidq = cs_etm__etmq_get_traceid_queue( etmq, CS_ETM_PER_THREAD_TRACEID); @@ -2482,10 +2456,8 @@ static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm, if (!tidq) continue; - if ((tid == -1) || (tidq->tid == tid)) { - cs_etm__set_pid_tid_cpu(etm, tidq); + if (tid == -1 || thread__tid(tidq->thread) == tid) cs_etm__run_per_thread_timeless_decoder(etmq); - } } else cs_etm__run_per_cpu_timeless_decoder(etmq); } @@ -2615,10 +2587,12 @@ static int cs_etm__process_itrace_start(struct cs_etm_auxtrace *etm, return 0; /* - * Add the tid/pid to the log so that we can get a match when - * we get a contextID from the decoder. + * Add the tid/pid to the log so that we can get a match when we get a + * contextID from the decoder. Only track for the host: only kernel + * trace is supported for guests which wouldn't need pids so this should + * be fine. */ - th = machine__findnew_thread(etm->machine, + th = machine__findnew_thread(&etm->session->machines.host, event->itrace_start.pid, event->itrace_start.tid); if (!th) @@ -2651,10 +2625,12 @@ static int cs_etm__process_switch_cpu_wide(struct cs_etm_auxtrace *etm, return 0; /* - * Add the tid/pid to the log so that we can get a match when - * we get a contextID from the decoder. + * Add the tid/pid to the log so that we can get a match when we get a + * contextID from the decoder. Only track for the host: only kernel + * trace is supported for guests which wouldn't need pids so this should + * be fine. */ - th = machine__findnew_thread(etm->machine, + th = machine__findnew_thread(&etm->session->machines.host, event->context_switch.next_prev_pid, event->context_switch.next_prev_tid); if (!th) @@ -3263,7 +3239,6 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event, } etm->session = session; - etm->machine = &session->machines.host; etm->num_cpu = num_cpu; etm->pmu_type = (unsigned int) ((ptr[CS_PMU_TYPE_CPUS] >> 32) & 0xffffffff); @@ -3290,21 +3265,6 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event, if (err) return err; - etm->unknown_thread = thread__new(999999999, 999999999); - if (!etm->unknown_thread) { - err = -ENOMEM; - goto err_free_queues; - } - - err = thread__set_comm(etm->unknown_thread, "unknown", 0); - if (err) - goto err_delete_thread; - - if (thread__init_maps(etm->unknown_thread, etm->machine)) { - err = -ENOMEM; - goto err_delete_thread; - } - etm->tc.time_shift = tc->time_shift; etm->tc.time_mult = tc->time_mult; etm->tc.time_zero = tc->time_zero; @@ -3316,7 +3276,7 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event, } err = cs_etm__synth_events(etm, session); if (err) - goto err_delete_thread; + goto err_free_queues; /* * Map Trace ID values to CPU metadata. @@ -3346,7 +3306,7 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event, session->header.data_size, cs_etm__process_aux_hw_id_cb, &aux_hw_id_found); if (err) - goto err_delete_thread; + goto err_free_queues; /* if HW ID found then clear any unused metadata ID values */ if (aux_hw_id_found) @@ -3356,17 +3316,15 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event, err = cs_etm__map_trace_ids_metadata(num_cpu, metadata); if (err) - goto err_delete_thread; + goto err_free_queues; err = cs_etm__queue_aux_records(session); if (err) - goto err_delete_thread; + goto err_free_queues; etm->data_queued = etm->queues.populated; return 0; -err_delete_thread: - thread__zput(etm->unknown_thread); err_free_queues: auxtrace_queues__free(&etm->queues); session->auxtrace = NULL; |