Lines Matching full:etm
22 #include "cs-etm.h"
23 #include "cs-etm-decoder/cs-etm-decoder.h"
107 struct cs_etm_auxtrace *etm; member
129 static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm);
130 static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
135 static u64 *get_cpu_data(struct cs_etm_auxtrace *etm, int cpu);
144 * encode the etm queue number as the upper 16 bit and the channel as
204 * The result is cached in etm->pid_fmt so this function only needs to be called
231 return etmq->etm->pid_fmt; in cs_etm__get_pid_fmt()
256 if (etmq->etm->per_thread_decoding) in cs_etm__insert_trace_id_node()
284 static struct cs_etm_queue *cs_etm__get_queue(struct cs_etm_auxtrace *etm, int cpu) in cs_etm__get_queue() argument
286 if (etm->per_thread_decoding) in cs_etm__get_queue()
287 return etm->queues.queue_array[0].priv; in cs_etm__get_queue()
289 return etm->queues.queue_array[cpu].priv; in cs_etm__get_queue()
292 static int cs_etm__map_trace_id_v0(struct cs_etm_auxtrace *etm, u8 trace_chan_id, in cs_etm__map_trace_id_v0() argument
301 etmq = cs_etm__get_queue(etm, cpu_metadata[CS_ETM_CPU]); in cs_etm__map_trace_id_v0()
310 for (unsigned int i = 0; i < etm->queues.nr_queues; ++i) { in cs_etm__map_trace_id_v0()
313 etmq = etm->queues.queue_array[i].priv; in cs_etm__map_trace_id_v0()
323 static int cs_etm__process_trace_id_v0(struct cs_etm_auxtrace *etm, int cpu, in cs_etm__process_trace_id_v0() argument
330 cpu_data = get_cpu_data(etm, cpu); in cs_etm__process_trace_id_v0()
334 err = cs_etm__map_trace_id_v0(etm, trace_chan_id, cpu_data); in cs_etm__process_trace_id_v0()
345 static int cs_etm__process_trace_id_v0_1(struct cs_etm_auxtrace *etm, int cpu, in cs_etm__process_trace_id_v0_1() argument
348 struct cs_etm_queue *etmq = cs_etm__get_queue(etm, cpu); in cs_etm__process_trace_id_v0_1()
359 if (!etmq->etm->per_thread_decoding && etmq->sink_id != SINK_UNSET && in cs_etm__process_trace_id_v0_1()
368 for (unsigned int i = 0; i < etm->queues.nr_queues; ++i) { in cs_etm__process_trace_id_v0_1()
369 struct cs_etm_queue *other_etmq = etm->queues.queue_array[i].priv; in cs_etm__process_trace_id_v0_1()
391 cpu_data = get_cpu_data(etm, cpu); in cs_etm__process_trace_id_v0_1()
449 static int get_cpu_data_idx(struct cs_etm_auxtrace *etm, int cpu) in get_cpu_data_idx() argument
453 for (i = 0; i < etm->num_cpu; i++) { in get_cpu_data_idx()
454 if (etm->metadata[i][CS_ETM_CPU] == (u64)cpu) { in get_cpu_data_idx()
466 static u64 *get_cpu_data(struct cs_etm_auxtrace *etm, int cpu) in get_cpu_data() argument
468 int idx = get_cpu_data_idx(etm, cpu); in get_cpu_data()
470 return (idx != -1) ? etm->metadata[idx] : NULL; in get_cpu_data()
483 struct cs_etm_auxtrace *etm; in cs_etm__process_aux_output_hw_id() local
495 …pr_err("CS ETM Trace: PERF_RECORD_AUX_OUTPUT_HW_ID version %d not supported. Please update Perf.\n… in cs_etm__process_aux_output_hw_id()
500 /* get access to the etm metadata */ in cs_etm__process_aux_output_hw_id()
501 etm = container_of(session->auxtrace, struct cs_etm_auxtrace, auxtrace); in cs_etm__process_aux_output_hw_id()
502 if (!etm || !etm->metadata) in cs_etm__process_aux_output_hw_id()
522 err = cs_etm__process_trace_id_v0(etm, cpu, hw_id); in cs_etm__process_aux_output_hw_id()
526 err = cs_etm__process_trace_id_v0_1(etm, cpu, hw_id); in cs_etm__process_aux_output_hw_id()
612 struct cs_etm_auxtrace *etm = etmq->etm; in cs_etm__init_traceid_queue() local
616 queue = &etmq->etm->queues.queue_array[etmq->queue_nr]; in cs_etm__init_traceid_queue()
619 tidq->thread = machine__findnew_thread(&etm->session->machines.host, -1, in cs_etm__init_traceid_queue()
621 tidq->prev_packet_thread = machine__idle_thread(&etm->session->machines.host); in cs_etm__init_traceid_queue()
631 if (etm->synth_opts.last_branch) { in cs_etm__init_traceid_queue()
634 sz += etm->synth_opts.last_branch_sz * in cs_etm__init_traceid_queue()
666 struct cs_etm_auxtrace *etm = etmq->etm; in cs_etm__etmq_get_traceid_queue() local
668 if (etm->per_thread_decoding) in cs_etm__etmq_get_traceid_queue()
744 static void cs_etm__packet_swap(struct cs_etm_auxtrace *etm, in cs_etm__packet_swap() argument
749 if (etm->synth_opts.branches || etm->synth_opts.last_branch || in cs_etm__packet_swap()
750 etm->synth_opts.instructions) { in cs_etm__packet_swap()
907 struct cs_etm_auxtrace *etm = container_of(session->auxtrace, in cs_etm__flush_events() local
916 if (etm->timeless_decoding) { in cs_etm__flush_events()
921 return cs_etm__process_timeless_queues(etm, -1); in cs_etm__flush_events()
924 return cs_etm__process_timestamped_queues(etm); in cs_etm__flush_events()
1040 return &etmq->etm->session->machines.host; in cs_etm__get_machine()
1052 return machines__find_guest(&etmq->etm->session->machines, in cs_etm__get_machine()
1059 return &etmq->etm->session->machines.host; in cs_etm__get_machine()
1146 …ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' or debuginfod to export data from … in cs_etm__mem_access()
1149 pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n", in cs_etm__mem_access()
1190 static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm, in cs_etm__setup_queue() argument
1205 etmq->etm = etm; in cs_etm__setup_queue()
1214 static int cs_etm__queue_first_cs_timestamp(struct cs_etm_auxtrace *etm, in cs_etm__queue_first_cs_timestamp() argument
1280 ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, cs_timestamp); in cs_etm__queue_first_cs_timestamp()
1310 nr = etmq->etm->synth_opts.last_branch_sz - tidq->last_branch_pos; in cs_etm__copy_last_branch_rb()
1322 if (bs_src->nr >= etmq->etm->synth_opts.last_branch_sz) { in cs_etm__copy_last_branch_rb()
1407 tidq->last_branch_pos = etmq->etm->synth_opts.last_branch_sz; in cs_etm__update_last_branch_rb()
1422 if (bs->nr < etmq->etm->synth_opts.last_branch_sz) in cs_etm__update_last_branch_rb()
1441 queue = &etmq->etm->queues.queue_array[etmq->queue_nr]; in cs_etm__get_trace()
1458 int fd = perf_data__fd(etmq->etm->session->data); in cs_etm__get_trace()
1509 return !!etmq->etm->timeless_decoding; in cs_etm__etmq_is_timeless()
1543 struct cs_etm_auxtrace *etm = etmq->etm; in cs_etm__convert_sample_time() local
1545 if (etm->has_virtual_ts) in cs_etm__convert_sample_time()
1546 return tsc_to_perf_time(cs_timestamp, &etm->tc); in cs_etm__convert_sample_time()
1554 struct cs_etm_auxtrace *etm = etmq->etm; in cs_etm__resolve_sample_time() local
1557 if (!etm->timeless_decoding && etm->has_virtual_ts) in cs_etm__resolve_sample_time()
1560 return etm->latest_kernel_timestamp; in cs_etm__resolve_sample_time()
1568 struct cs_etm_auxtrace *etm = etmq->etm; in cs_etm__synth_instruction_sample() local
1577 /* Set time field based on etm auxtrace config. */ in cs_etm__synth_instruction_sample()
1583 sample.id = etmq->etm->instructions_id; in cs_etm__synth_instruction_sample()
1584 sample.stream_id = etmq->etm->instructions_id; in cs_etm__synth_instruction_sample()
1592 if (etm->synth_opts.last_branch) in cs_etm__synth_instruction_sample()
1595 if (etm->synth_opts.inject) { in cs_etm__synth_instruction_sample()
1597 etm->instructions_sample_type); in cs_etm__synth_instruction_sample()
1602 ret = perf_session__deliver_synth_event(etm->session, event, &sample); in cs_etm__synth_instruction_sample()
1606 "CS ETM Trace: failed to deliver instruction event, error %d\n", in cs_etm__synth_instruction_sample()
1614 * The cs etm packet encodes an instruction range between a branch target
1621 struct cs_etm_auxtrace *etm = etmq->etm; in cs_etm__synth_branch_sample() local
1638 /* Set time field based on etm auxtrace config. */ in cs_etm__synth_branch_sample()
1645 sample.id = etmq->etm->branches_id; in cs_etm__synth_branch_sample()
1646 sample.stream_id = etmq->etm->branches_id; in cs_etm__synth_branch_sample()
1658 if (etm->synth_opts.last_branch) { in cs_etm__synth_branch_sample()
1670 if (etm->synth_opts.inject) { in cs_etm__synth_branch_sample()
1672 etm->branches_sample_type); in cs_etm__synth_branch_sample()
1677 ret = perf_session__deliver_synth_event(etm->session, event, &sample); in cs_etm__synth_branch_sample()
1681 "CS ETM Trace: failed to deliver instruction event, error %d\n", in cs_etm__synth_branch_sample()
1687 static int cs_etm__synth_events(struct cs_etm_auxtrace *etm, in cs_etm__synth_events() argument
1698 if (evsel->core.attr.type == etm->pmu_type) { in cs_etm__synth_events()
1715 if (etm->timeless_decoding) in cs_etm__synth_events()
1734 if (etm->synth_opts.branches) { in cs_etm__synth_events()
1741 etm->branches_sample_type = attr.sample_type; in cs_etm__synth_events()
1742 etm->branches_id = id; in cs_etm__synth_events()
1747 if (etm->synth_opts.last_branch) { in cs_etm__synth_events()
1757 if (etm->synth_opts.instructions) { in cs_etm__synth_events()
1759 attr.sample_period = etm->synth_opts.period; in cs_etm__synth_events()
1760 etm->instructions_sample_period = attr.sample_period; in cs_etm__synth_events()
1764 etm->instructions_sample_type = attr.sample_type; in cs_etm__synth_events()
1765 etm->instructions_id = id; in cs_etm__synth_events()
1775 struct cs_etm_auxtrace *etm = etmq->etm; in cs_etm__sample() local
1789 if (etm->synth_opts.last_branch && in cs_etm__sample()
1794 if (etm->synth_opts.instructions && in cs_etm__sample()
1795 tidq->period_instructions >= etm->instructions_sample_period) { in cs_etm__sample()
1821 * every etm->instructions_sample_period instructions - as in cs_etm__sample()
1823 * last sample before the current etm packet, n+1 to n+3 in cs_etm__sample()
1824 * samples are generated from the current etm packet. in cs_etm__sample()
1827 * instructions in the current etm packet. in cs_etm__sample()
1831 * previous etm packet. This will always be less than in cs_etm__sample()
1832 * etm->instructions_sample_period. in cs_etm__sample()
1846 * etm->instructions_sample_period. in cs_etm__sample()
1848 u64 offset = etm->instructions_sample_period - instrs_prev; in cs_etm__sample()
1852 if (etm->synth_opts.last_branch) in cs_etm__sample()
1856 etm->instructions_sample_period) { in cs_etm__sample()
1867 etm->instructions_sample_period); in cs_etm__sample()
1871 offset += etm->instructions_sample_period; in cs_etm__sample()
1873 etm->instructions_sample_period; in cs_etm__sample()
1877 if (etm->synth_opts.branches) { in cs_etm__sample()
1896 cs_etm__packet_swap(etm, tidq); in cs_etm__sample()
1924 struct cs_etm_auxtrace *etm = etmq->etm; in cs_etm__flush() local
1930 if (etmq->etm->synth_opts.last_branch && in cs_etm__flush()
1931 etmq->etm->synth_opts.instructions && in cs_etm__flush()
1957 if (etm->synth_opts.branches && in cs_etm__flush()
1965 cs_etm__packet_swap(etm, tidq); in cs_etm__flush()
1968 if (etm->synth_opts.last_branch) in cs_etm__flush()
1988 if (etmq->etm->synth_opts.last_branch && in cs_etm__end_block()
1989 etmq->etm->synth_opts.instructions && in cs_etm__end_block()
2479 pr_err("CS ETM Trace: empty packet\n"); in cs_etm__process_traceid_queue()
2588 static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm, in cs_etm__process_timeless_queues() argument
2592 struct auxtrace_queues *queues = &etm->queues; in cs_etm__process_timeless_queues()
2595 struct auxtrace_queue *queue = &etm->queues.queue_array[i]; in cs_etm__process_timeless_queues()
2602 if (etm->per_thread_decoding) { in cs_etm__process_timeless_queues()
2618 static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm) in cs_etm__process_timestamped_queues() argument
2632 for (i = 0; i < etm->queues.nr_queues; i++) { in cs_etm__process_timestamped_queues()
2633 etmq = etm->queues.queue_array[i].priv; in cs_etm__process_timestamped_queues()
2637 ret = cs_etm__queue_first_cs_timestamp(etm, etmq, i); in cs_etm__process_timestamped_queues()
2643 if (!etm->heap.heap_cnt) in cs_etm__process_timestamped_queues()
2647 cs_queue_nr = etm->heap.heap_array[0].queue_nr; in cs_etm__process_timestamped_queues()
2650 queue = &etm->queues.queue_array[queue_nr]; in cs_etm__process_timestamped_queues()
2657 auxtrace_heap__pop(&etm->heap); in cs_etm__process_timestamped_queues()
2724 ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, cs_timestamp); in cs_etm__process_timestamped_queues()
2727 for (i = 0; i < etm->queues.nr_queues; i++) { in cs_etm__process_timestamped_queues()
2730 etmq = etm->queues.queue_array[i].priv; in cs_etm__process_timestamped_queues()
2748 static int cs_etm__process_itrace_start(struct cs_etm_auxtrace *etm, in cs_etm__process_itrace_start() argument
2753 if (etm->timeless_decoding) in cs_etm__process_itrace_start()
2762 th = machine__findnew_thread(&etm->session->machines.host, in cs_etm__process_itrace_start()
2773 static int cs_etm__process_switch_cpu_wide(struct cs_etm_auxtrace *etm, in cs_etm__process_switch_cpu_wide() argument
2783 if (etm->timeless_decoding) in cs_etm__process_switch_cpu_wide()
2800 th = machine__findnew_thread(&etm->session->machines.host, in cs_etm__process_switch_cpu_wide()
2816 struct cs_etm_auxtrace *etm = container_of(session->auxtrace, in cs_etm__process_event() local
2824 pr_err("CoreSight ETM Trace requires ordered events\n"); in cs_etm__process_event()
2838 if (etm->per_thread_decoding && etm->timeless_decoding) in cs_etm__process_event()
2839 return cs_etm__process_timeless_queues(etm, in cs_etm__process_event()
2844 return cs_etm__process_itrace_start(etm, event); in cs_etm__process_event()
2847 return cs_etm__process_switch_cpu_wide(etm, event); in cs_etm__process_event()
2856 etm->latest_kernel_timestamp = sample->time; in cs_etm__process_event()
2866 static void dump_queued_data(struct cs_etm_auxtrace *etm, in dump_queued_data() argument
2876 for (i = 0; i < etm->queues.nr_queues; ++i) in dump_queued_data()
2877 list_for_each_entry(buf, &etm->queues.queue_array[i].head, list) in dump_queued_data()
2879 cs_etm__dump_event(etm->queues.queue_array[i].priv, buf); in dump_queued_data()
2886 struct cs_etm_auxtrace *etm = container_of(session->auxtrace, in cs_etm__process_auxtrace_event() local
2889 if (!etm->data_queued) { in cs_etm__process_auxtrace_event()
2905 err = auxtrace_queues__add_event(&etm->queues, session, in cs_etm__process_auxtrace_event()
2912 cs_etm__dump_event(etm->queues.queue_array[idx].priv, buffer); in cs_etm__process_auxtrace_event()
2916 dump_queued_data(etm, &event->auxtrace); in cs_etm__process_auxtrace_event()
2921 static int cs_etm__setup_timeless_decoding(struct cs_etm_auxtrace *etm) in cs_etm__setup_timeless_decoding() argument
2924 struct evlist *evlist = etm->session->evlist; in cs_etm__setup_timeless_decoding()
2927 if (etm->synth_opts.timeless_decoding) { in cs_etm__setup_timeless_decoding()
2928 etm->timeless_decoding = true; in cs_etm__setup_timeless_decoding()
2936 if (cs_etm__evsel_is_auxtrace(etm->session, evsel)) { in cs_etm__setup_timeless_decoding()
2937 etm->timeless_decoding = in cs_etm__setup_timeless_decoding()
2942 pr_err("CS ETM: Couldn't find ETM evsel\n"); in cs_etm__setup_timeless_decoding()
3028 struct cs_etm_auxtrace *etm = container_of(session->auxtrace, in cs_etm__queue_aux_fragment() local
3057 etm->per_thread_decoding = true; in cs_etm__queue_aux_fragment()
3061 if (etm->per_thread_decoding) { in cs_etm__queue_aux_fragment()
3066 pr_err("CS ETM: Inconsistent per-thread/per-cpu mode.\n"); in cs_etm__queue_aux_fragment()
3092 struct cs_etm_queue *etmq = etm->queues.queue_array[auxtrace_event->idx].priv; in cs_etm__queue_aux_fragment()
3103 pr_debug3("CS ETM: Queue buffer size: %#"PRI_lx64" offset: %#"PRI_lx64 in cs_etm__queue_aux_fragment()
3105 err = auxtrace_queues__add_event(&etm->queues, session, &auxtrace_fragment, in cs_etm__queue_aux_fragment()
3189 pr_err("CS ETM: Couldn't find auxtrace buffer for aux_offset: %#"PRI_lx64 in cs_etm__queue_aux_records_cb()
3209 * queueing them in cs_etm__process_auxtrace_event() if etm->data_queued is still in cs_etm__queue_aux_records()
3247 static int cs_etm__map_trace_ids_metadata(struct cs_etm_auxtrace *etm, int num_cpu, in cs_etm__map_trace_ids_metadata() argument
3270 err = cs_etm__map_trace_id_v0(etm, trace_chan_id, metadata[i]); in cs_etm__map_trace_ids_metadata()
3337 static int cs_etm__create_decoders(struct cs_etm_auxtrace *etm) in cs_etm__create_decoders() argument
3339 struct auxtrace_queues *queues = &etm->queues; in cs_etm__create_decoders()
3365 struct cs_etm_auxtrace *etm = NULL; in cs_etm__process_auxtrace_info_full() local
3407 …ui__error("CS ETM Trace: Unrecognised magic number %#"PRIx64". File could be from a newer version … in cs_etm__process_auxtrace_info_full()
3435 etm = zalloc(sizeof(*etm)); in cs_etm__process_auxtrace_info_full()
3437 if (!etm) { in cs_etm__process_auxtrace_info_full()
3447 etm->pid_fmt = cs_etm__init_pid_fmt(metadata[0]); in cs_etm__process_auxtrace_info_full()
3449 err = auxtrace_queues__init_nr(&etm->queues, max_cpu + 1); in cs_etm__process_auxtrace_info_full()
3453 for (unsigned int j = 0; j < etm->queues.nr_queues; ++j) { in cs_etm__process_auxtrace_info_full()
3454 err = cs_etm__setup_queue(etm, &etm->queues.queue_array[j], j); in cs_etm__process_auxtrace_info_full()
3460 etm->synth_opts = *session->itrace_synth_opts; in cs_etm__process_auxtrace_info_full()
3462 itrace_synth_opts__set_default(&etm->synth_opts, in cs_etm__process_auxtrace_info_full()
3464 etm->synth_opts.callchain = false; in cs_etm__process_auxtrace_info_full()
3467 etm->session = session; in cs_etm__process_auxtrace_info_full()
3469 etm->num_cpu = num_cpu; in cs_etm__process_auxtrace_info_full()
3470 etm->pmu_type = (unsigned int) ((ptr[CS_PMU_TYPE_CPUS] >> 32) & 0xffffffff); in cs_etm__process_auxtrace_info_full()
3471 etm->snapshot_mode = (ptr[CS_ETM_SNAPSHOT] != 0); in cs_etm__process_auxtrace_info_full()
3472 etm->metadata = metadata; in cs_etm__process_auxtrace_info_full()
3473 etm->auxtrace_type = auxtrace_info->type; in cs_etm__process_auxtrace_info_full()
3475 if (etm->synth_opts.use_timestamp) in cs_etm__process_auxtrace_info_full()
3485 etm->has_virtual_ts = true; in cs_etm__process_auxtrace_info_full()
3488 etm->has_virtual_ts = cs_etm__has_virtual_ts(metadata, num_cpu); in cs_etm__process_auxtrace_info_full()
3490 if (!etm->has_virtual_ts) in cs_etm__process_auxtrace_info_full()
3497 etm->auxtrace.process_event = cs_etm__process_event; in cs_etm__process_auxtrace_info_full()
3498 etm->auxtrace.process_auxtrace_event = cs_etm__process_auxtrace_event; in cs_etm__process_auxtrace_info_full()
3499 etm->auxtrace.flush_events = cs_etm__flush_events; in cs_etm__process_auxtrace_info_full()
3500 etm->auxtrace.free_events = cs_etm__free_events; in cs_etm__process_auxtrace_info_full()
3501 etm->auxtrace.free = cs_etm__free; in cs_etm__process_auxtrace_info_full()
3502 etm->auxtrace.evsel_is_auxtrace = cs_etm__evsel_is_auxtrace; in cs_etm__process_auxtrace_info_full()
3503 session->auxtrace = &etm->auxtrace; in cs_etm__process_auxtrace_info_full()
3505 err = cs_etm__setup_timeless_decoding(etm); in cs_etm__process_auxtrace_info_full()
3509 etm->tc.time_shift = tc->time_shift; in cs_etm__process_auxtrace_info_full()
3510 etm->tc.time_mult = tc->time_mult; in cs_etm__process_auxtrace_info_full()
3511 etm->tc.time_zero = tc->time_zero; in cs_etm__process_auxtrace_info_full()
3513 etm->tc.time_cycles = tc->time_cycles; in cs_etm__process_auxtrace_info_full()
3514 etm->tc.time_mask = tc->time_mask; in cs_etm__process_auxtrace_info_full()
3515 etm->tc.cap_user_time_zero = tc->cap_user_time_zero; in cs_etm__process_auxtrace_info_full()
3516 etm->tc.cap_user_time_short = tc->cap_user_time_short; in cs_etm__process_auxtrace_info_full()
3518 err = cs_etm__synth_events(etm, session); in cs_etm__process_auxtrace_info_full()
3557 err = cs_etm__map_trace_ids_metadata(etm, num_cpu, metadata); in cs_etm__process_auxtrace_info_full()
3562 err = cs_etm__create_decoders(etm); in cs_etm__process_auxtrace_info_full()
3566 etm->data_queued = etm->queues.populated; in cs_etm__process_auxtrace_info_full()
3570 auxtrace_queues__free(&etm->queues); in cs_etm__process_auxtrace_info_full()
3573 zfree(&etm); in cs_etm__process_auxtrace_info_full()