Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf tooling fixes from Thomas Gleixner:

- Synchronization of tools and kernel headers

- A series of fixes for perf report addressing various failures:
* Handle invalid maps proper
* Plug a memory leak
* Handle frames and callchain order correctly

- Fixes for handling inlines and children mode

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
tools/include: Sync kernel ABI headers with tooling headers
perf tools: Put caller above callee in --children mode
perf report: Do not drop last inlined frame
perf report: Always honor callchain order for inlined nodes
perf script: Add --inline option for debugging
perf report: Fix off-by-one for non-activation frames
perf report: Fix memory leak in addr2line when called by addr2inlines
perf report: Don't crash on invalid maps in `-g srcline` mode

+180 -51
+9 -1
tools/arch/arm/include/uapi/asm/kvm.h
··· 27 27 #define __KVM_HAVE_IRQ_LINE 28 28 #define __KVM_HAVE_READONLY_MEM 29 29 30 + #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 31 + 30 32 #define KVM_REG_SIZE(id) \ 31 33 (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT)) 32 34 ··· 116 114 }; 117 115 118 116 struct kvm_sync_regs { 117 + /* Used with KVM_CAP_ARM_USER_IRQ */ 118 + __u64 device_irq_level; 119 119 }; 120 120 121 121 struct kvm_arch_memory_slot { ··· 196 192 #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5 197 193 #define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6 198 194 #define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7 195 + #define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8 199 196 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10 200 197 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \ 201 198 (0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT) 202 199 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff 203 200 #define VGIC_LEVEL_INFO_LINE_LEVEL 0 204 201 205 - #define KVM_DEV_ARM_VGIC_CTRL_INIT 0 202 + #define KVM_DEV_ARM_VGIC_CTRL_INIT 0 203 + #define KVM_DEV_ARM_ITS_SAVE_TABLES 1 204 + #define KVM_DEV_ARM_ITS_RESTORE_TABLES 2 205 + #define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3 206 206 207 207 /* KVM_IRQ_LINE irq field index values */ 208 208 #define KVM_ARM_IRQ_TYPE_SHIFT 24
+9 -1
tools/arch/arm64/include/uapi/asm/kvm.h
··· 39 39 #define __KVM_HAVE_IRQ_LINE 40 40 #define __KVM_HAVE_READONLY_MEM 41 41 42 + #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 43 + 42 44 #define KVM_REG_SIZE(id) \ 43 45 (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT)) 44 46 ··· 145 143 #define KVM_GUESTDBG_USE_HW (1 << 17) 146 144 147 145 struct kvm_sync_regs { 146 + /* Used with KVM_CAP_ARM_USER_IRQ */ 147 + __u64 device_irq_level; 148 148 }; 149 149 150 150 struct kvm_arch_memory_slot { ··· 216 212 #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5 217 213 #define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6 218 214 #define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7 215 + #define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8 219 216 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10 220 217 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \ 221 218 (0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT) 222 219 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff 223 220 #define VGIC_LEVEL_INFO_LINE_LEVEL 0 224 221 225 - #define KVM_DEV_ARM_VGIC_CTRL_INIT 0 222 + #define KVM_DEV_ARM_VGIC_CTRL_INIT 0 223 + #define KVM_DEV_ARM_ITS_SAVE_TABLES 1 224 + #define KVM_DEV_ARM_ITS_RESTORE_TABLES 2 225 + #define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3 226 226 227 227 /* Device Control API on vcpu fd */ 228 228 #define KVM_ARM_VCPU_PMU_V3_CTRL 0
+3
tools/arch/powerpc/include/uapi/asm/kvm.h
··· 29 29 #define __KVM_HAVE_IRQ_LINE 30 30 #define __KVM_HAVE_GUEST_DEBUG 31 31 32 + /* Not always available, but if it is, this is the correct offset. */ 33 + #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 34 + 32 35 struct kvm_regs { 33 36 __u64 pc; 34 37 __u64 cr;
+24 -2
tools/arch/s390/include/uapi/asm/kvm.h
··· 26 26 #define KVM_DEV_FLIC_ADAPTER_REGISTER 6 27 27 #define KVM_DEV_FLIC_ADAPTER_MODIFY 7 28 28 #define KVM_DEV_FLIC_CLEAR_IO_IRQ 8 29 + #define KVM_DEV_FLIC_AISM 9 30 + #define KVM_DEV_FLIC_AIRQ_INJECT 10 29 31 /* 30 32 * We can have up to 4*64k pending subchannels + 8 adapter interrupts, 31 33 * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts. ··· 43 41 __u8 isc; 44 42 __u8 maskable; 45 43 __u8 swap; 46 - __u8 pad; 44 + __u8 flags; 45 + }; 46 + 47 + #define KVM_S390_ADAPTER_SUPPRESSIBLE 0x01 48 + 49 + struct kvm_s390_ais_req { 50 + __u8 isc; 51 + __u16 mode; 47 52 }; 48 53 49 54 #define KVM_S390_IO_ADAPTER_MASK 1 ··· 119 110 #define KVM_S390_VM_CPU_FEAT_CMMA 10 120 111 #define KVM_S390_VM_CPU_FEAT_PFMFI 11 121 112 #define KVM_S390_VM_CPU_FEAT_SIGPIF 12 113 + #define KVM_S390_VM_CPU_FEAT_KSS 13 122 114 struct kvm_s390_vm_cpu_feat { 123 115 __u64 feat[16]; 124 116 }; ··· 208 198 #define KVM_SYNC_VRS (1UL << 6) 209 199 #define KVM_SYNC_RICCB (1UL << 7) 210 200 #define KVM_SYNC_FPRS (1UL << 8) 201 + #define KVM_SYNC_GSCB (1UL << 9) 202 + /* length and alignment of the sdnx as a power of two */ 203 + #define SDNXC 8 204 + #define SDNXL (1UL << SDNXC) 211 205 /* definition of registers in kvm_run */ 212 206 struct kvm_sync_regs { 213 207 __u64 prefix; /* prefix register */ ··· 232 218 }; 233 219 __u8 reserved[512]; /* for future vector expansion */ 234 220 __u32 fpc; /* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */ 235 - __u8 padding[52]; /* riccb needs to be 64byte aligned */ 221 + __u8 padding1[52]; /* riccb needs to be 64byte aligned */ 236 222 __u8 riccb[64]; /* runtime instrumentation controls block */ 223 + __u8 padding2[192]; /* sdnx needs to be 256byte aligned */ 224 + union { 225 + __u8 sdnx[SDNXL]; /* state description annex */ 226 + struct { 227 + __u64 reserved1[2]; 228 + __u64 gscb[4]; 229 + }; 230 + }; 237 231 }; 238 232 239 233 #define KVM_REG_S390_TODPR (KVM_REG_S390 | KVM_REG_SIZE_U32 | 0x1)
+2
tools/arch/x86/include/asm/cpufeatures.h
··· 202 202 #define X86_FEATURE_AVX512_4VNNIW (7*32+16) /* AVX-512 Neural Network Instructions */ 203 203 #define X86_FEATURE_AVX512_4FMAPS (7*32+17) /* AVX-512 Multiply Accumulation Single precision */ 204 204 205 + #define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */ 206 + 205 207 /* Virtualization flags: Linux defined, word 8 */ 206 208 #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ 207 209 #define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */
+7 -1
tools/arch/x86/include/asm/disabled-features.h
··· 36 36 # define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE & 31)) 37 37 #endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */ 38 38 39 + #ifdef CONFIG_X86_5LEVEL 40 + # define DISABLE_LA57 0 41 + #else 42 + # define DISABLE_LA57 (1<<(X86_FEATURE_LA57 & 31)) 43 + #endif 44 + 39 45 /* 40 46 * Make sure to add features to the correct mask 41 47 */ ··· 61 55 #define DISABLED_MASK13 0 62 56 #define DISABLED_MASK14 0 63 57 #define DISABLED_MASK15 0 64 - #define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE) 58 + #define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57) 65 59 #define DISABLED_MASK17 0 66 60 #define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18) 67 61
+7 -1
tools/arch/x86/include/asm/required-features.h
··· 53 53 # define NEED_MOVBE 0 54 54 #endif 55 55 56 + #ifdef CONFIG_X86_5LEVEL 57 + # define NEED_LA57 (1<<(X86_FEATURE_LA57 & 31)) 58 + #else 59 + # define NEED_LA57 0 60 + #endif 61 + 56 62 #ifdef CONFIG_X86_64 57 63 #ifdef CONFIG_PARAVIRT 58 64 /* Paravirtualized systems may not have PSE or PGE available */ ··· 104 98 #define REQUIRED_MASK13 0 105 99 #define REQUIRED_MASK14 0 106 100 #define REQUIRED_MASK15 0 107 - #define REQUIRED_MASK16 0 101 + #define REQUIRED_MASK16 (NEED_LA57) 108 102 #define REQUIRED_MASK17 0 109 103 #define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18) 110 104
+3
tools/arch/x86/include/uapi/asm/kvm.h
··· 9 9 #include <linux/types.h> 10 10 #include <linux/ioctl.h> 11 11 12 + #define KVM_PIO_PAGE_OFFSET 1 13 + #define KVM_COALESCED_MMIO_PAGE_OFFSET 2 14 + 12 15 #define DE_VECTOR 0 13 16 #define DB_VECTOR 1 14 17 #define BP_VECTOR 3
+19 -8
tools/arch/x86/include/uapi/asm/vmx.h
··· 76 76 #define EXIT_REASON_WBINVD 54 77 77 #define EXIT_REASON_XSETBV 55 78 78 #define EXIT_REASON_APIC_WRITE 56 79 + #define EXIT_REASON_RDRAND 57 79 80 #define EXIT_REASON_INVPCID 58 81 + #define EXIT_REASON_VMFUNC 59 82 + #define EXIT_REASON_ENCLS 60 83 + #define EXIT_REASON_RDSEED 61 80 84 #define EXIT_REASON_PML_FULL 62 81 85 #define EXIT_REASON_XSAVES 63 82 86 #define EXIT_REASON_XRSTORS 64 ··· 94 90 { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, \ 95 91 { EXIT_REASON_CPUID, "CPUID" }, \ 96 92 { EXIT_REASON_HLT, "HLT" }, \ 93 + { EXIT_REASON_INVD, "INVD" }, \ 97 94 { EXIT_REASON_INVLPG, "INVLPG" }, \ 98 95 { EXIT_REASON_RDPMC, "RDPMC" }, \ 99 96 { EXIT_REASON_RDTSC, "RDTSC" }, \ ··· 113 108 { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, \ 114 109 { EXIT_REASON_MSR_READ, "MSR_READ" }, \ 115 110 { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, \ 111 + { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \ 112 + { EXIT_REASON_MSR_LOAD_FAIL, "MSR_LOAD_FAIL" }, \ 116 113 { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, \ 117 114 { EXIT_REASON_MONITOR_TRAP_FLAG, "MONITOR_TRAP_FLAG" }, \ 118 115 { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, \ ··· 122 115 { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, \ 123 116 { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, \ 124 117 { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, \ 125 - { EXIT_REASON_GDTR_IDTR, "GDTR_IDTR" }, \ 126 - { EXIT_REASON_LDTR_TR, "LDTR_TR" }, \ 118 + { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, \ 119 + { EXIT_REASON_GDTR_IDTR, "GDTR_IDTR" }, \ 120 + { EXIT_REASON_LDTR_TR, "LDTR_TR" }, \ 127 121 { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, \ 128 122 { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, \ 129 123 { EXIT_REASON_INVEPT, "INVEPT" }, \ 124 + { EXIT_REASON_RDTSCP, "RDTSCP" }, \ 130 125 { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" }, \ 131 - { EXIT_REASON_WBINVD, "WBINVD" }, \ 132 - { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, \ 133 - { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, \ 134 - { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \ 135 - { EXIT_REASON_MSR_LOAD_FAIL, "MSR_LOAD_FAIL" }, \ 136 - { EXIT_REASON_INVD, "INVD" }, \ 137 126 { EXIT_REASON_INVVPID, "INVVPID" }, \ 127 + { EXIT_REASON_WBINVD, "WBINVD" }, \ 128 + { EXIT_REASON_XSETBV, "XSETBV" }, \ 129 + { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, \ 130 + { EXIT_REASON_RDRAND, "RDRAND" }, \ 138 131 { EXIT_REASON_INVPCID, "INVPCID" }, \ 132 + { EXIT_REASON_VMFUNC, "VMFUNC" }, \ 133 + { EXIT_REASON_ENCLS, "ENCLS" }, \ 134 + { EXIT_REASON_RDSEED, "RDSEED" }, \ 135 + { EXIT_REASON_PML_FULL, "PML_FULL" }, \ 139 136 { EXIT_REASON_XSAVES, "XSAVES" }, \ 140 137 { EXIT_REASON_XRSTORS, "XRSTORS" } 141 138
+2 -6
tools/include/uapi/linux/stat.h
··· 48 48 * tv_sec holds the number of seconds before (negative) or after (positive) 49 49 * 00:00:00 1st January 1970 UTC. 50 50 * 51 - * tv_nsec holds a number of nanoseconds before (0..-999,999,999 if tv_sec is 52 - * negative) or after (0..999,999,999 if tv_sec is positive) the tv_sec time. 53 - * 54 - * Note that if both tv_sec and tv_nsec are non-zero, then the two values must 55 - * either be both positive or both negative. 51 + * tv_nsec holds a number of nanoseconds (0..999,999,999) after the tv_sec time. 56 52 * 57 53 * __reserved is held in case we need a yet finer resolution. 58 54 */ 59 55 struct statx_timestamp { 60 56 __s64 tv_sec; 61 - __s32 tv_nsec; 57 + __u32 tv_nsec; 62 58 __s32 __reserved; 63 59 }; 64 60
+4
tools/perf/Documentation/perf-script.txt
··· 311 311 Set the maximum number of program blocks to print with brstackasm for 312 312 each sample. 313 313 314 + --inline:: 315 + If a callgraph address belongs to an inlined function, the inline stack 316 + will be printed. Each entry has function name and file/line. 317 + 314 318 SEE ALSO 315 319 -------- 316 320 linkperf:perf-record[1], linkperf:perf-script-perl[1],
+2
tools/perf/builtin-script.c
··· 2494 2494 "Enable kernel symbol demangling"), 2495 2495 OPT_STRING(0, "time", &script.time_str, "str", 2496 2496 "Time span of interest (start,stop)"), 2497 + OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name, 2498 + "Show inline function"), 2497 2499 OPT_END() 2498 2500 }; 2499 2501 const char * const script_subcommands[] = { "record", "report", NULL };
+2
tools/perf/ui/hist.c
··· 210 210 return 0; 211 211 212 212 ret = b->callchain->max_depth - a->callchain->max_depth; 213 + if (callchain_param.order == ORDER_CALLER) 214 + ret = -ret; 213 215 } 214 216 return ret; 215 217 }
+11 -6
tools/perf/util/callchain.c
··· 621 621 static enum match_result match_chain_srcline(struct callchain_cursor_node *node, 622 622 struct callchain_list *cnode) 623 623 { 624 - char *left = get_srcline(cnode->ms.map->dso, 625 - map__rip_2objdump(cnode->ms.map, cnode->ip), 626 - cnode->ms.sym, true, false); 627 - char *right = get_srcline(node->map->dso, 628 - map__rip_2objdump(node->map, node->ip), 629 - node->sym, true, false); 624 + char *left = NULL; 625 + char *right = NULL; 630 626 enum match_result ret = MATCH_EQ; 631 627 int cmp; 628 + 629 + if (cnode->ms.map) 630 + left = get_srcline(cnode->ms.map->dso, 631 + map__rip_2objdump(cnode->ms.map, cnode->ip), 632 + cnode->ms.sym, true, false); 633 + if (node->map) 634 + right = get_srcline(node->map->dso, 635 + map__rip_2objdump(node->map, node->ip), 636 + node->sym, true, false); 632 637 633 638 if (left && right) 634 639 cmp = strcmp(left, right);
+33
tools/perf/util/evsel_fprintf.c
··· 7 7 #include "map.h" 8 8 #include "strlist.h" 9 9 #include "symbol.h" 10 + #include "srcline.h" 10 11 11 12 static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...) 12 13 { ··· 168 167 169 168 if (!print_oneline) 170 169 printed += fprintf(fp, "\n"); 170 + 171 + if (symbol_conf.inline_name && node->map) { 172 + struct inline_node *inode; 173 + 174 + addr = map__rip_2objdump(node->map, node->ip), 175 + inode = dso__parse_addr_inlines(node->map->dso, addr); 176 + 177 + if (inode) { 178 + struct inline_list *ilist; 179 + 180 + list_for_each_entry(ilist, &inode->val, list) { 181 + if (print_arrow) 182 + printed += fprintf(fp, " <-"); 183 + 184 + /* IP is same, just skip it */ 185 + if (print_ip) 186 + printed += fprintf(fp, "%c%16s", 187 + s, ""); 188 + if (print_sym) 189 + printed += fprintf(fp, " %s", 190 + ilist->funcname); 191 + if (print_srcline) 192 + printed += fprintf(fp, "\n %s:%d", 193 + ilist->filename, 194 + ilist->line_nr); 195 + if (!print_oneline) 196 + printed += fprintf(fp, "\n"); 197 + } 198 + 199 + inline_node__delete(inode); 200 + } 201 + } 171 202 172 203 if (symbol_conf.bt_stop_list && 173 204 node->sym &&
+27 -24
tools/perf/util/srcline.c
··· 56 56 } 57 57 } 58 58 59 - list_add_tail(&ilist->list, &node->val); 59 + if (callchain_param.order == ORDER_CALLEE) 60 + list_add_tail(&ilist->list, &node->val); 61 + else 62 + list_add(&ilist->list, &node->val); 60 63 61 64 return 0; 62 65 } ··· 203 200 204 201 #define MAX_INLINE_NEST 1024 205 202 206 - static void inline_list__reverse(struct inline_node *node) 203 + static int inline_list__append_dso_a2l(struct dso *dso, 204 + struct inline_node *node) 207 205 { 208 - struct inline_list *ilist, *n; 206 + struct a2l_data *a2l = dso->a2l; 207 + char *funcname = a2l->funcname ? strdup(a2l->funcname) : NULL; 208 + char *filename = a2l->filename ? strdup(a2l->filename) : NULL; 209 209 210 - list_for_each_entry_safe_reverse(ilist, n, &node->val, list) 211 - list_move_tail(&ilist->list, &node->val); 210 + return inline_list__append(filename, funcname, a2l->line, node, dso); 212 211 } 213 212 214 213 static int addr2line(const char *dso_name, u64 addr, ··· 235 230 236 231 bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); 237 232 238 - if (a2l->found && unwind_inlines) { 233 + if (!a2l->found) 234 + return 0; 235 + 236 + if (unwind_inlines) { 239 237 int cnt = 0; 238 + 239 + if (node && inline_list__append_dso_a2l(dso, node)) 240 + return 0; 240 241 241 242 while (bfd_find_inliner_info(a2l->abfd, &a2l->filename, 242 243 &a2l->funcname, &a2l->line) && 243 244 cnt++ < MAX_INLINE_NEST) { 244 245 245 246 if (node != NULL) { 246 - if (inline_list__append(strdup(a2l->filename), 247 - strdup(a2l->funcname), 248 - a2l->line, node, 249 - dso) != 0) 247 + if (inline_list__append_dso_a2l(dso, node)) 250 248 return 0; 249 + // found at least one inline frame 250 + ret = 1; 251 251 } 252 252 } 253 - 254 - if ((node != NULL) && 255 - (callchain_param.order != ORDER_CALLEE)) { 256 - inline_list__reverse(node); 257 - } 258 253 } 259 254 260 - if (a2l->found && a2l->filename) { 261 - *file = strdup(a2l->filename); 255 + if (file) { 256 + *file = a2l->filename ? strdup(a2l->filename) : NULL; 257 + ret = *file ? 1 : 0; 258 + } 259 + 260 + if (line) 262 261 *line = a2l->line; 263 - 264 - if (*file) 265 - ret = 1; 266 - } 267 262 268 263 return ret; 269 264 } ··· 283 278 static struct inline_node *addr2inlines(const char *dso_name, u64 addr, 284 279 struct dso *dso) 285 280 { 286 - char *file = NULL; 287 - unsigned int line = 0; 288 281 struct inline_node *node; 289 282 290 283 node = zalloc(sizeof(*node)); ··· 294 291 INIT_LIST_HEAD(&node->val); 295 292 node->addr = addr; 296 293 297 - if (!addr2line(dso_name, addr, &file, &line, dso, TRUE, node)) 294 + if (!addr2line(dso_name, addr, NULL, NULL, dso, TRUE, node)) 298 295 goto out_free_inline_node; 299 296 300 297 if (list_empty(&node->val))
+5 -1
tools/perf/util/unwind-libdw.c
··· 168 168 { 169 169 struct unwind_info *ui = arg; 170 170 Dwarf_Addr pc; 171 + bool isactivation; 171 172 172 - if (!dwfl_frame_pc(state, &pc, NULL)) { 173 + if (!dwfl_frame_pc(state, &pc, &isactivation)) { 173 174 pr_err("%s", dwfl_errmsg(-1)); 174 175 return DWARF_CB_ABORT; 175 176 } 177 + 178 + if (!isactivation) 179 + --pc; 176 180 177 181 return entry(pc, ui) || !(--ui->max_stack) ? 178 182 DWARF_CB_ABORT : DWARF_CB_OK;
+11
tools/perf/util/unwind-libunwind-local.c
··· 692 692 693 693 while (!ret && (unw_step(&c) > 0) && i < max_stack) { 694 694 unw_get_reg(&c, UNW_REG_IP, &ips[i]); 695 + 696 + /* 697 + * Decrement the IP for any non-activation frames. 698 + * this is required to properly find the srcline 699 + * for caller frames. 700 + * See also the documentation for dwfl_frame_pc(), 701 + * which this code tries to replicate. 702 + */ 703 + if (unw_is_signal_frame(&c) <= 0) 704 + --ips[i]; 705 + 695 706 ++i; 696 707 } 697 708