| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * thread-stack.h: Synthesize a thread's stack using call / return events |
|---|
| 3 | 4 | * Copyright (c) 2014, Intel Corporation. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 7 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 12 | | - * more details. |
|---|
| 13 | | - * |
|---|
| 14 | 5 | */ |
|---|
| 15 | 6 | |
|---|
| 16 | 7 | #ifndef __PERF_THREAD_STACK_H |
|---|
| .. | .. |
|---|
| 35 | 26 | * |
|---|
| 36 | 27 | * CALL_RETURN_NO_CALL: 'return' but no matching 'call' |
|---|
| 37 | 28 | * CALL_RETURN_NO_RETURN: 'call' but no matching 'return' |
|---|
| 29 | + * CALL_RETURN_NON_CALL: a branch but not a 'call' to the start of a different |
|---|
| 30 | + * symbol |
|---|
| 38 | 31 | */ |
|---|
| 39 | 32 | enum { |
|---|
| 40 | 33 | CALL_RETURN_NO_CALL = 1 << 0, |
|---|
| 41 | 34 | CALL_RETURN_NO_RETURN = 1 << 1, |
|---|
| 35 | + CALL_RETURN_NON_CALL = 1 << 2, |
|---|
| 42 | 36 | }; |
|---|
| 43 | 37 | |
|---|
| 44 | 38 | /** |
|---|
| .. | .. |
|---|
| 49 | 43 | * @call_time: timestamp of call (if known) |
|---|
| 50 | 44 | * @return_time: timestamp of return (if known) |
|---|
| 51 | 45 | * @branch_count: number of branches seen between call and return |
|---|
| 46 | + * @insn_count: approx. number of instructions between call and return |
|---|
| 47 | + * @cyc_count: approx. number of cycles between call and return |
|---|
| 52 | 48 | * @call_ref: external reference to 'call' sample (e.g. db_id) |
|---|
| 53 | 49 | * @return_ref: external reference to 'return' sample (e.g. db_id) |
|---|
| 54 | 50 | * @db_id: id used for db-export |
|---|
| 51 | + * @parent_db_id: id of parent call used for db-export |
|---|
| 55 | 52 | * @flags: Call/Return flags |
|---|
| 56 | 53 | */ |
|---|
| 57 | 54 | struct call_return { |
|---|
| .. | .. |
|---|
| 61 | 58 | u64 call_time; |
|---|
| 62 | 59 | u64 return_time; |
|---|
| 63 | 60 | u64 branch_count; |
|---|
| 61 | + u64 insn_count; |
|---|
| 62 | + u64 cyc_count; |
|---|
| 64 | 63 | u64 call_ref; |
|---|
| 65 | 64 | u64 return_ref; |
|---|
| 66 | 65 | u64 db_id; |
|---|
| 66 | + u64 parent_db_id; |
|---|
| 67 | 67 | u32 flags; |
|---|
| 68 | 68 | }; |
|---|
| 69 | 69 | |
|---|
| .. | .. |
|---|
| 76 | 76 | */ |
|---|
| 77 | 77 | struct call_return_processor { |
|---|
| 78 | 78 | struct call_path_root *cpr; |
|---|
| 79 | | - int (*process)(struct call_return *cr, void *data); |
|---|
| 79 | + int (*process)(struct call_return *cr, u64 *parent_db_id, void *data); |
|---|
| 80 | 80 | void *data; |
|---|
| 81 | 81 | }; |
|---|
| 82 | 82 | |
|---|
| 83 | | -int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, |
|---|
| 84 | | - u64 to_ip, u16 insn_len, u64 trace_nr); |
|---|
| 85 | | -void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr); |
|---|
| 86 | | -void thread_stack__sample(struct thread *thread, struct ip_callchain *chain, |
|---|
| 83 | +int thread_stack__event(struct thread *thread, int cpu, u32 flags, u64 from_ip, |
|---|
| 84 | + u64 to_ip, u16 insn_len, u64 trace_nr, bool callstack, |
|---|
| 85 | + unsigned int br_stack_sz, bool mispred_all); |
|---|
| 86 | +void thread_stack__set_trace_nr(struct thread *thread, int cpu, u64 trace_nr); |
|---|
| 87 | +void thread_stack__sample(struct thread *thread, int cpu, struct ip_callchain *chain, |
|---|
| 87 | 88 | size_t sz, u64 ip, u64 kernel_start); |
|---|
| 89 | +void thread_stack__sample_late(struct thread *thread, int cpu, |
|---|
| 90 | + struct ip_callchain *chain, size_t sz, u64 ip, |
|---|
| 91 | + u64 kernel_start); |
|---|
| 92 | +void thread_stack__br_sample(struct thread *thread, int cpu, |
|---|
| 93 | + struct branch_stack *dst, unsigned int sz); |
|---|
| 94 | +void thread_stack__br_sample_late(struct thread *thread, int cpu, |
|---|
| 95 | + struct branch_stack *dst, unsigned int sz, |
|---|
| 96 | + u64 sample_ip, u64 kernel_start); |
|---|
| 88 | 97 | int thread_stack__flush(struct thread *thread); |
|---|
| 89 | 98 | void thread_stack__free(struct thread *thread); |
|---|
| 90 | | -size_t thread_stack__depth(struct thread *thread); |
|---|
| 99 | +size_t thread_stack__depth(struct thread *thread, int cpu); |
|---|
| 91 | 100 | |
|---|
| 92 | 101 | struct call_return_processor * |
|---|
| 93 | | -call_return_processor__new(int (*process)(struct call_return *cr, void *data), |
|---|
| 102 | +call_return_processor__new(int (*process)(struct call_return *cr, u64 *parent_db_id, void *data), |
|---|
| 94 | 103 | void *data); |
|---|
| 95 | 104 | void call_return_processor__free(struct call_return_processor *crp); |
|---|
| 96 | 105 | int thread_stack__process(struct thread *thread, struct comm *comm, |
|---|