Commit bdc5663fa14de657f24080ee959670d49c8dd094
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar: "Assorted standalone fixes" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf/x86/intel: Add model number for Avoton Silvermont perf: Fix capabilities bitfield compatibility in 'struct perf_event_mmap_page' perf/x86/intel/uncore: Don't use smp_processor_id() in validate_group() perf: Update ABI comment tools lib lk: Uninclude linux/magic.h in debugfs.c perf tools: Fix old GCC build error in trace-event-parse.c:parse_proc_kallsyms() perf probe: Fix finder to find lines of given function perf session: Check for SIGINT in more loops perf tools: Fix compile with libelf without get_phdrnum perf tools: Fix buildid cache handling of kallsyms with kcore perf annotate: Fix objdump line parsing offset validation perf tools: Fill in new definitions for madvise()/mmap() flags perf tools: Sharpen the libaudit dependencies test
Showing 23 changed files Side-by-side Diff
- arch/x86/kernel/cpu/perf_event.c
- arch/x86/kernel/cpu/perf_event_intel.c
- arch/x86/kernel/cpu/perf_event_intel_uncore.c
- include/uapi/linux/perf_event.h
- kernel/events/core.c
- tools/lib/lk/debugfs.c
- tools/perf/arch/x86/util/tsc.c
- tools/perf/builtin-inject.c
- tools/perf/builtin-report.c
- tools/perf/builtin-script.c
- tools/perf/builtin-trace.c
- tools/perf/config/Makefile
- tools/perf/config/feature-tests.mak
- tools/perf/util/annotate.c
- tools/perf/util/dwarf-aux.c
- tools/perf/util/dwarf-aux.h
- tools/perf/util/header.c
- tools/perf/util/hist.c
- tools/perf/util/probe-finder.c
- tools/perf/util/session.c
- tools/perf/util/session.h
- tools/perf/util/symbol-elf.c
- tools/perf/util/trace-event-parse.c
arch/x86/kernel/cpu/perf_event.c
... | ... | @@ -1883,9 +1883,9 @@ |
1883 | 1883 | |
1884 | 1884 | void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) |
1885 | 1885 | { |
1886 | - userpg->cap_usr_time = 0; | |
1887 | - userpg->cap_usr_time_zero = 0; | |
1888 | - userpg->cap_usr_rdpmc = x86_pmu.attr_rdpmc; | |
1886 | + userpg->cap_user_time = 0; | |
1887 | + userpg->cap_user_time_zero = 0; | |
1888 | + userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc; | |
1889 | 1889 | userpg->pmc_width = x86_pmu.cntval_bits; |
1890 | 1890 | |
1891 | 1891 | if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) |
1892 | 1892 | |
... | ... | @@ -1894,13 +1894,13 @@ |
1894 | 1894 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) |
1895 | 1895 | return; |
1896 | 1896 | |
1897 | - userpg->cap_usr_time = 1; | |
1897 | + userpg->cap_user_time = 1; | |
1898 | 1898 | userpg->time_mult = this_cpu_read(cyc2ns); |
1899 | 1899 | userpg->time_shift = CYC2NS_SCALE_FACTOR; |
1900 | 1900 | userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; |
1901 | 1901 | |
1902 | 1902 | if (sched_clock_stable && !check_tsc_disabled()) { |
1903 | - userpg->cap_usr_time_zero = 1; | |
1903 | + userpg->cap_user_time_zero = 1; | |
1904 | 1904 | userpg->time_zero = this_cpu_read(cyc2ns_offset); |
1905 | 1905 | } |
1906 | 1906 | } |
arch/x86/kernel/cpu/perf_event_intel.c
... | ... | @@ -2325,6 +2325,7 @@ |
2325 | 2325 | break; |
2326 | 2326 | |
2327 | 2327 | case 55: /* Atom 22nm "Silvermont" */ |
2328 | + case 77: /* Avoton "Silvermont" */ | |
2328 | 2329 | memcpy(hw_cache_event_ids, slm_hw_cache_event_ids, |
2329 | 2330 | sizeof(hw_cache_event_ids)); |
2330 | 2331 | memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs, |
arch/x86/kernel/cpu/perf_event_intel_uncore.c
... | ... | @@ -2706,14 +2706,14 @@ |
2706 | 2706 | box->hrtimer.function = uncore_pmu_hrtimer; |
2707 | 2707 | } |
2708 | 2708 | |
2709 | -struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int cpu) | |
2709 | +static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int node) | |
2710 | 2710 | { |
2711 | 2711 | struct intel_uncore_box *box; |
2712 | 2712 | int i, size; |
2713 | 2713 | |
2714 | 2714 | size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg); |
2715 | 2715 | |
2716 | - box = kzalloc_node(size, GFP_KERNEL, cpu_to_node(cpu)); | |
2716 | + box = kzalloc_node(size, GFP_KERNEL, node); | |
2717 | 2717 | if (!box) |
2718 | 2718 | return NULL; |
2719 | 2719 | |
... | ... | @@ -3031,7 +3031,7 @@ |
3031 | 3031 | struct intel_uncore_box *fake_box; |
3032 | 3032 | int ret = -EINVAL, n; |
3033 | 3033 | |
3034 | - fake_box = uncore_alloc_box(pmu->type, smp_processor_id()); | |
3034 | + fake_box = uncore_alloc_box(pmu->type, NUMA_NO_NODE); | |
3035 | 3035 | if (!fake_box) |
3036 | 3036 | return -ENOMEM; |
3037 | 3037 | |
... | ... | @@ -3294,7 +3294,7 @@ |
3294 | 3294 | } |
3295 | 3295 | |
3296 | 3296 | type = pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)]; |
3297 | - box = uncore_alloc_box(type, 0); | |
3297 | + box = uncore_alloc_box(type, NUMA_NO_NODE); | |
3298 | 3298 | if (!box) |
3299 | 3299 | return -ENOMEM; |
3300 | 3300 | |
... | ... | @@ -3499,7 +3499,7 @@ |
3499 | 3499 | if (pmu->func_id < 0) |
3500 | 3500 | pmu->func_id = j; |
3501 | 3501 | |
3502 | - box = uncore_alloc_box(type, cpu); | |
3502 | + box = uncore_alloc_box(type, cpu_to_node(cpu)); | |
3503 | 3503 | if (!box) |
3504 | 3504 | return -ENOMEM; |
3505 | 3505 |
include/uapi/linux/perf_event.h
... | ... | @@ -380,10 +380,13 @@ |
380 | 380 | union { |
381 | 381 | __u64 capabilities; |
382 | 382 | struct { |
383 | - __u64 cap_usr_time : 1, | |
384 | - cap_usr_rdpmc : 1, | |
385 | - cap_usr_time_zero : 1, | |
386 | - cap_____res : 61; | |
383 | + __u64 cap_bit0 : 1, /* Always 0, deprecated, see commit 860f085b74e9 */ | |
384 | + cap_bit0_is_deprecated : 1, /* Always 1, signals that bit 0 is zero */ | |
385 | + | |
386 | + cap_user_rdpmc : 1, /* The RDPMC instruction can be used to read counts */ | |
387 | + cap_user_time : 1, /* The time_* fields are used */ | |
388 | + cap_user_time_zero : 1, /* The time_zero field is used */ | |
389 | + cap_____res : 59; | |
387 | 390 | }; |
388 | 391 | }; |
389 | 392 | |
390 | 393 | |
... | ... | @@ -442,12 +445,13 @@ |
442 | 445 | * ((rem * time_mult) >> time_shift); |
443 | 446 | */ |
444 | 447 | __u64 time_zero; |
448 | + __u32 size; /* Header size up to __reserved[] fields. */ | |
445 | 449 | |
446 | 450 | /* |
447 | 451 | * Hole for extension of the self monitor capabilities |
448 | 452 | */ |
449 | 453 | |
450 | - __u64 __reserved[119]; /* align to 1k */ | |
454 | + __u8 __reserved[118*8+4]; /* align to 1k. */ | |
451 | 455 | |
452 | 456 | /* |
453 | 457 | * Control data for the mmap() data buffer. |
... | ... | @@ -528,6 +532,7 @@ |
528 | 532 | * u64 len; |
529 | 533 | * u64 pgoff; |
530 | 534 | * char filename[]; |
535 | + * struct sample_id sample_id; | |
531 | 536 | * }; |
532 | 537 | */ |
533 | 538 | PERF_RECORD_MMAP = 1, |
kernel/events/core.c
... | ... | @@ -3660,6 +3660,26 @@ |
3660 | 3660 | *running = ctx_time - event->tstamp_running; |
3661 | 3661 | } |
3662 | 3662 | |
3663 | +static void perf_event_init_userpage(struct perf_event *event) | |
3664 | +{ | |
3665 | + struct perf_event_mmap_page *userpg; | |
3666 | + struct ring_buffer *rb; | |
3667 | + | |
3668 | + rcu_read_lock(); | |
3669 | + rb = rcu_dereference(event->rb); | |
3670 | + if (!rb) | |
3671 | + goto unlock; | |
3672 | + | |
3673 | + userpg = rb->user_page; | |
3674 | + | |
3675 | + /* Allow new userspace to detect that bit 0 is deprecated */ | |
3676 | + userpg->cap_bit0_is_deprecated = 1; | |
3677 | + userpg->size = offsetof(struct perf_event_mmap_page, __reserved); | |
3678 | + | |
3679 | +unlock: | |
3680 | + rcu_read_unlock(); | |
3681 | +} | |
3682 | + | |
3663 | 3683 | void __weak arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) |
3664 | 3684 | { |
3665 | 3685 | } |
... | ... | @@ -4044,6 +4064,7 @@ |
4044 | 4064 | ring_buffer_attach(event, rb); |
4045 | 4065 | rcu_assign_pointer(event->rb, rb); |
4046 | 4066 | |
4067 | + perf_event_init_userpage(event); | |
4047 | 4068 | perf_event_update_userpage(event); |
4048 | 4069 | |
4049 | 4070 | unlock: |
tools/lib/lk/debugfs.c
tools/perf/arch/x86/util/tsc.c
... | ... | @@ -32,7 +32,7 @@ |
32 | 32 | int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc, |
33 | 33 | struct perf_tsc_conversion *tc) |
34 | 34 | { |
35 | - bool cap_usr_time_zero; | |
35 | + bool cap_user_time_zero; | |
36 | 36 | u32 seq; |
37 | 37 | int i = 0; |
38 | 38 | |
... | ... | @@ -42,7 +42,7 @@ |
42 | 42 | tc->time_mult = pc->time_mult; |
43 | 43 | tc->time_shift = pc->time_shift; |
44 | 44 | tc->time_zero = pc->time_zero; |
45 | - cap_usr_time_zero = pc->cap_usr_time_zero; | |
45 | + cap_user_time_zero = pc->cap_user_time_zero; | |
46 | 46 | rmb(); |
47 | 47 | if (pc->lock == seq && !(seq & 1)) |
48 | 48 | break; |
... | ... | @@ -52,7 +52,7 @@ |
52 | 52 | } |
53 | 53 | } |
54 | 54 | |
55 | - if (!cap_usr_time_zero) | |
55 | + if (!cap_user_time_zero) | |
56 | 56 | return -EOPNOTSUPP; |
57 | 57 | |
58 | 58 | return 0; |
tools/perf/builtin-inject.c
tools/perf/builtin-report.c
... | ... | @@ -401,8 +401,6 @@ |
401 | 401 | return 0; |
402 | 402 | } |
403 | 403 | |
404 | -extern volatile int session_done; | |
405 | - | |
406 | 404 | static void sig_handler(int sig __maybe_unused) |
407 | 405 | { |
408 | 406 | session_done = 1; |
... | ... | @@ -567,6 +565,9 @@ |
567 | 565 | hists__link(leader_hists, hists); |
568 | 566 | } |
569 | 567 | } |
568 | + | |
569 | + if (session_done()) | |
570 | + return 0; | |
570 | 571 | |
571 | 572 | if (nr_samples == 0) { |
572 | 573 | ui__error("The %s file has no samples!\n", session->filename); |
tools/perf/builtin-script.c
tools/perf/builtin-trace.c
... | ... | @@ -16,6 +16,23 @@ |
16 | 16 | #include <sys/mman.h> |
17 | 17 | #include <linux/futex.h> |
18 | 18 | |
19 | +/* For older distros: */ | |
20 | +#ifndef MAP_STACK | |
21 | +# define MAP_STACK 0x20000 | |
22 | +#endif | |
23 | + | |
24 | +#ifndef MADV_HWPOISON | |
25 | +# define MADV_HWPOISON 100 | |
26 | +#endif | |
27 | + | |
28 | +#ifndef MADV_MERGEABLE | |
29 | +# define MADV_MERGEABLE 12 | |
30 | +#endif | |
31 | + | |
32 | +#ifndef MADV_UNMERGEABLE | |
33 | +# define MADV_UNMERGEABLE 13 | |
34 | +#endif | |
35 | + | |
19 | 36 | static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, |
20 | 37 | unsigned long arg, |
21 | 38 | u8 arg_idx __maybe_unused, |
tools/perf/config/Makefile
... | ... | @@ -180,6 +180,9 @@ |
180 | 180 | ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y) |
181 | 181 | CFLAGS += -DLIBELF_MMAP |
182 | 182 | endif |
183 | +ifeq ($(call try-cc,$(SOURCE_ELF_GETPHDRNUM),$(FLAGS_LIBELF),-DHAVE_ELF_GETPHDRNUM),y) | |
184 | + CFLAGS += -DHAVE_ELF_GETPHDRNUM | |
185 | +endif | |
183 | 186 | |
184 | 187 | # include ARCH specific config |
185 | 188 | -include $(src-perf)/arch/$(ARCH)/Makefile |
tools/perf/config/feature-tests.mak
... | ... | @@ -61,6 +61,15 @@ |
61 | 61 | } |
62 | 62 | endef |
63 | 63 | |
64 | +define SOURCE_ELF_GETPHDRNUM | |
65 | +#include <libelf.h> | |
66 | +int main(void) | |
67 | +{ | |
68 | + size_t dst; | |
69 | + return elf_getphdrnum(0, &dst); | |
70 | +} | |
71 | +endef | |
72 | + | |
64 | 73 | ifndef NO_SLANG |
65 | 74 | define SOURCE_SLANG |
66 | 75 | #include <slang.h> |
... | ... | @@ -210,6 +219,7 @@ |
210 | 219 | |
211 | 220 | int main(void) |
212 | 221 | { |
222 | + printf(\"error message: %s\n\", audit_errno_to_name(0)); | |
213 | 223 | return audit_open(); |
214 | 224 | } |
215 | 225 | endef |
tools/perf/util/annotate.c
tools/perf/util/dwarf-aux.c
... | ... | @@ -263,6 +263,21 @@ |
263 | 263 | } |
264 | 264 | |
265 | 265 | /** |
266 | + * die_is_func_def - Ensure that this DIE is a subprogram and definition | |
267 | + * @dw_die: a DIE | |
268 | + * | |
269 | + * Ensure that this DIE is a subprogram and NOT a declaration. This | |
270 | + * returns true if @dw_die is a function definition. | |
271 | + **/ | |
272 | +bool die_is_func_def(Dwarf_Die *dw_die) | |
273 | +{ | |
274 | + Dwarf_Attribute attr; | |
275 | + | |
276 | + return (dwarf_tag(dw_die) == DW_TAG_subprogram && | |
277 | + dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL); | |
278 | +} | |
279 | + | |
280 | +/** | |
266 | 281 | * die_get_data_member_location - Get the data-member offset |
267 | 282 | * @mb_die: a DIE of a member of a data structure |
268 | 283 | * @offs: The offset of the member in the data structure |
... | ... | @@ -392,6 +407,10 @@ |
392 | 407 | { |
393 | 408 | struct __addr_die_search_param *ad = data; |
394 | 409 | |
410 | + /* | |
411 | + * Since a declaration entry doesn't has given pc, this always returns | |
412 | + * function definition entry. | |
413 | + */ | |
395 | 414 | if (dwarf_tag(fn_die) == DW_TAG_subprogram && |
396 | 415 | dwarf_haspc(fn_die, ad->addr)) { |
397 | 416 | memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die)); |
tools/perf/util/dwarf-aux.h
... | ... | @@ -38,6 +38,9 @@ |
38 | 38 | extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, |
39 | 39 | int (*callback)(Dwarf_Die *, void *), void *data); |
40 | 40 | |
41 | +/* Ensure that this DIE is a subprogram and definition (not declaration) */ | |
42 | +extern bool die_is_func_def(Dwarf_Die *dw_die); | |
43 | + | |
41 | 44 | /* Compare diename and tname */ |
42 | 45 | extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); |
43 | 46 |
tools/perf/util/header.c
... | ... | @@ -199,9 +199,11 @@ |
199 | 199 | return write_padded(fd, name, name_len + 1, len); |
200 | 200 | } |
201 | 201 | |
202 | -static int __dsos__write_buildid_table(struct list_head *head, pid_t pid, | |
203 | - u16 misc, int fd) | |
202 | +static int __dsos__write_buildid_table(struct list_head *head, | |
203 | + struct machine *machine, | |
204 | + pid_t pid, u16 misc, int fd) | |
204 | 205 | { |
206 | + char nm[PATH_MAX]; | |
205 | 207 | struct dso *pos; |
206 | 208 | |
207 | 209 | dsos__for_each_with_build_id(pos, head) { |
... | ... | @@ -215,6 +217,10 @@ |
215 | 217 | if (is_vdso_map(pos->short_name)) { |
216 | 218 | name = (char *) VDSO__MAP_NAME; |
217 | 219 | name_len = sizeof(VDSO__MAP_NAME) + 1; |
220 | + } else if (dso__is_kcore(pos)) { | |
221 | + machine__mmap_name(machine, nm, sizeof(nm)); | |
222 | + name = nm; | |
223 | + name_len = strlen(nm) + 1; | |
218 | 224 | } else { |
219 | 225 | name = pos->long_name; |
220 | 226 | name_len = pos->long_name_len + 1; |
221 | 227 | |
... | ... | @@ -240,10 +246,10 @@ |
240 | 246 | umisc = PERF_RECORD_MISC_GUEST_USER; |
241 | 247 | } |
242 | 248 | |
243 | - err = __dsos__write_buildid_table(&machine->kernel_dsos, machine->pid, | |
244 | - kmisc, fd); | |
249 | + err = __dsos__write_buildid_table(&machine->kernel_dsos, machine, | |
250 | + machine->pid, kmisc, fd); | |
245 | 251 | if (err == 0) |
246 | - err = __dsos__write_buildid_table(&machine->user_dsos, | |
252 | + err = __dsos__write_buildid_table(&machine->user_dsos, machine, | |
247 | 253 | machine->pid, umisc, fd); |
248 | 254 | return err; |
249 | 255 | } |
250 | 256 | |
251 | 257 | |
252 | 258 | |
253 | 259 | |
... | ... | @@ -375,23 +381,31 @@ |
375 | 381 | return err; |
376 | 382 | } |
377 | 383 | |
378 | -static int dso__cache_build_id(struct dso *dso, const char *debugdir) | |
384 | +static int dso__cache_build_id(struct dso *dso, struct machine *machine, | |
385 | + const char *debugdir) | |
379 | 386 | { |
380 | 387 | bool is_kallsyms = dso->kernel && dso->long_name[0] != '/'; |
381 | 388 | bool is_vdso = is_vdso_map(dso->short_name); |
389 | + char *name = dso->long_name; | |
390 | + char nm[PATH_MAX]; | |
382 | 391 | |
383 | - return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), | |
384 | - dso->long_name, debugdir, | |
385 | - is_kallsyms, is_vdso); | |
392 | + if (dso__is_kcore(dso)) { | |
393 | + is_kallsyms = true; | |
394 | + machine__mmap_name(machine, nm, sizeof(nm)); | |
395 | + name = nm; | |
396 | + } | |
397 | + return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), name, | |
398 | + debugdir, is_kallsyms, is_vdso); | |
386 | 399 | } |
387 | 400 | |
388 | -static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir) | |
401 | +static int __dsos__cache_build_ids(struct list_head *head, | |
402 | + struct machine *machine, const char *debugdir) | |
389 | 403 | { |
390 | 404 | struct dso *pos; |
391 | 405 | int err = 0; |
392 | 406 | |
393 | 407 | dsos__for_each_with_build_id(pos, head) |
394 | - if (dso__cache_build_id(pos, debugdir)) | |
408 | + if (dso__cache_build_id(pos, machine, debugdir)) | |
395 | 409 | err = -1; |
396 | 410 | |
397 | 411 | return err; |
... | ... | @@ -399,8 +413,9 @@ |
399 | 413 | |
400 | 414 | static int machine__cache_build_ids(struct machine *machine, const char *debugdir) |
401 | 415 | { |
402 | - int ret = __dsos__cache_build_ids(&machine->kernel_dsos, debugdir); | |
403 | - ret |= __dsos__cache_build_ids(&machine->user_dsos, debugdir); | |
416 | + int ret = __dsos__cache_build_ids(&machine->kernel_dsos, machine, | |
417 | + debugdir); | |
418 | + ret |= __dsos__cache_build_ids(&machine->user_dsos, machine, debugdir); | |
404 | 419 | return ret; |
405 | 420 | } |
406 | 421 |
tools/perf/util/hist.c
tools/perf/util/probe-finder.c
... | ... | @@ -734,7 +734,7 @@ |
734 | 734 | } |
735 | 735 | |
736 | 736 | /* If not a real subprogram, find a real one */ |
737 | - if (dwarf_tag(sc_die) != DW_TAG_subprogram) { | |
737 | + if (!die_is_func_def(sc_die)) { | |
738 | 738 | if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) { |
739 | 739 | pr_warning("Failed to find probe point in any " |
740 | 740 | "functions.\n"); |
741 | 741 | |
... | ... | @@ -980,12 +980,10 @@ |
980 | 980 | struct dwarf_callback_param *param = data; |
981 | 981 | struct probe_finder *pf = param->data; |
982 | 982 | struct perf_probe_point *pp = &pf->pev->point; |
983 | - Dwarf_Attribute attr; | |
984 | 983 | |
985 | 984 | /* Check tag and diename */ |
986 | - if (dwarf_tag(sp_die) != DW_TAG_subprogram || | |
987 | - !die_compare_name(sp_die, pp->function) || | |
988 | - dwarf_attr(sp_die, DW_AT_declaration, &attr)) | |
985 | + if (!die_is_func_def(sp_die) || | |
986 | + !die_compare_name(sp_die, pp->function)) | |
989 | 987 | return DWARF_CB_OK; |
990 | 988 | |
991 | 989 | /* Check declared file */ |
... | ... | @@ -1474,7 +1472,7 @@ |
1474 | 1472 | return 0; |
1475 | 1473 | } |
1476 | 1474 | |
1477 | -/* Search function from function name */ | |
1475 | +/* Search function definition from function name */ | |
1478 | 1476 | static int line_range_search_cb(Dwarf_Die *sp_die, void *data) |
1479 | 1477 | { |
1480 | 1478 | struct dwarf_callback_param *param = data; |
... | ... | @@ -1485,7 +1483,7 @@ |
1485 | 1483 | if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die))) |
1486 | 1484 | return DWARF_CB_OK; |
1487 | 1485 | |
1488 | - if (dwarf_tag(sp_die) == DW_TAG_subprogram && | |
1486 | + if (die_is_func_def(sp_die) && | |
1489 | 1487 | die_compare_name(sp_die, lr->function)) { |
1490 | 1488 | lf->fname = dwarf_decl_file(sp_die); |
1491 | 1489 | dwarf_decl_line(sp_die, &lr->offset); |
tools/perf/util/session.c
... | ... | @@ -531,6 +531,9 @@ |
531 | 531 | return 0; |
532 | 532 | |
533 | 533 | list_for_each_entry_safe(iter, tmp, head, list) { |
534 | + if (session_done()) | |
535 | + return 0; | |
536 | + | |
534 | 537 | if (iter->timestamp > limit) |
535 | 538 | break; |
536 | 539 | |
... | ... | @@ -1160,7 +1163,6 @@ |
1160 | 1163 | } |
1161 | 1164 | } |
1162 | 1165 | |
1163 | -#define session_done() (*(volatile int *)(&session_done)) | |
1164 | 1166 | volatile int session_done; |
1165 | 1167 | |
1166 | 1168 | static int __perf_session__process_pipe_events(struct perf_session *self, |
1167 | 1169 | |
... | ... | @@ -1372,10 +1374,13 @@ |
1372 | 1374 | "Processing events..."); |
1373 | 1375 | } |
1374 | 1376 | |
1377 | + err = 0; | |
1378 | + if (session_done()) | |
1379 | + goto out_err; | |
1380 | + | |
1375 | 1381 | if (file_pos < file_size) |
1376 | 1382 | goto more; |
1377 | 1383 | |
1378 | - err = 0; | |
1379 | 1384 | /* do the final flush for ordered samples */ |
1380 | 1385 | session->ordered_samples.next_flush = ULLONG_MAX; |
1381 | 1386 | err = flush_sample_queue(session, tool); |
tools/perf/util/session.h
... | ... | @@ -124,5 +124,9 @@ |
124 | 124 | |
125 | 125 | #define perf_session__set_tracepoints_handlers(session, array) \ |
126 | 126 | __perf_session__set_tracepoints_handlers(session, array, ARRAY_SIZE(array)) |
127 | + | |
128 | +extern volatile int session_done; | |
129 | + | |
130 | +#define session_done() (*(volatile int *)(&session_done)) | |
127 | 131 | #endif /* __PERF_SESSION_H */ |
tools/perf/util/symbol-elf.c
... | ... | @@ -8,6 +8,22 @@ |
8 | 8 | #include "symbol.h" |
9 | 9 | #include "debug.h" |
10 | 10 | |
11 | +#ifndef HAVE_ELF_GETPHDRNUM | |
12 | +static int elf_getphdrnum(Elf *elf, size_t *dst) | |
13 | +{ | |
14 | + GElf_Ehdr gehdr; | |
15 | + GElf_Ehdr *ehdr; | |
16 | + | |
17 | + ehdr = gelf_getehdr(elf, &gehdr); | |
18 | + if (!ehdr) | |
19 | + return -1; | |
20 | + | |
21 | + *dst = ehdr->e_phnum; | |
22 | + | |
23 | + return 0; | |
24 | +} | |
25 | +#endif | |
26 | + | |
11 | 27 | #ifndef NT_GNU_BUILD_ID |
12 | 28 | #define NT_GNU_BUILD_ID 3 |
13 | 29 | #endif |