diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-25 20:05:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-25 20:05:40 -0400 |
commit | bdc6b758e443c21c39a14c075e5b7e01f095b37b (patch) | |
tree | 40b98b5abd501cc232f41af03eb078282d7a6327 /tools/perf/util/machine.c | |
parent | c4a346002bc06046bc51910a7ade3a0c650c3d34 (diff) | |
parent | 0c9f790fcbdaf8cfb6dd7fb4e88fadf55082e37e (diff) |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar:
"Mostly tooling and PMU driver fixes, but also a number of late updates
such as the reworking of the call-chain size limiting logic to make
call-graph recording more robust, plus tooling side changes for the
new 'backwards ring-buffer' extension to the perf ring-buffer"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (34 commits)
perf record: Read from backward ring buffer
perf record: Rename variable to make code clear
perf record: Prevent reading invalid data in record__mmap_read
perf evlist: Add API to pause/resume
perf trace: Use the ptr->name beautifier as default for "filename" args
perf trace: Use the fd->name beautifier as default for "fd" args
perf report: Add srcline_from/to branch sort keys
perf evsel: Record fd into perf_mmap
perf evsel: Add overwrite attribute and check write_backward
perf tools: Set buildid dir under symfs when --symfs is provided
perf trace: Only auto set call-graph to "dwarf" when syscalls are being traced
perf annotate: Sort list of recognised instructions
perf annotate: Fix identification of ARM blt and bls instructions
perf tools: Fix usage of max_stack sysctl
perf callchain: Stop validating callchains by the max_stack sysctl
perf trace: Fix exit_group() formatting
perf top: Use machine->kptr_restrict_warned
perf trace: Warn when trying to resolve kernel addresses with kptr_restrict=1
perf machine: Do not bail out if not managing to read ref reloc symbol
perf/x86/intel/p4: Trival indentation fix, remove space
...
Diffstat (limited to 'tools/perf/util/machine.c')
-rw-r--r-- | tools/perf/util/machine.c | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index f9644f79686c..b1772180c820 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -43,6 +43,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) | |||
43 | 43 | ||
44 | machine->symbol_filter = NULL; | 44 | machine->symbol_filter = NULL; |
45 | machine->id_hdr_size = 0; | 45 | machine->id_hdr_size = 0; |
46 | machine->kptr_restrict_warned = false; | ||
46 | machine->comm_exec = false; | 47 | machine->comm_exec = false; |
47 | machine->kernel_start = 0; | 48 | machine->kernel_start = 0; |
48 | 49 | ||
@@ -709,7 +710,7 @@ static struct dso *machine__get_kernel(struct machine *machine) | |||
709 | if (machine__is_host(machine)) { | 710 | if (machine__is_host(machine)) { |
710 | vmlinux_name = symbol_conf.vmlinux_name; | 711 | vmlinux_name = symbol_conf.vmlinux_name; |
711 | if (!vmlinux_name) | 712 | if (!vmlinux_name) |
712 | vmlinux_name = "[kernel.kallsyms]"; | 713 | vmlinux_name = DSO__NAME_KALLSYMS; |
713 | 714 | ||
714 | kernel = machine__findnew_kernel(machine, vmlinux_name, | 715 | kernel = machine__findnew_kernel(machine, vmlinux_name, |
715 | "[kernel]", DSO_TYPE_KERNEL); | 716 | "[kernel]", DSO_TYPE_KERNEL); |
@@ -1135,10 +1136,10 @@ int machine__create_kernel_maps(struct machine *machine) | |||
1135 | { | 1136 | { |
1136 | struct dso *kernel = machine__get_kernel(machine); | 1137 | struct dso *kernel = machine__get_kernel(machine); |
1137 | const char *name; | 1138 | const char *name; |
1138 | u64 addr = machine__get_running_kernel_start(machine, &name); | 1139 | u64 addr; |
1139 | int ret; | 1140 | int ret; |
1140 | 1141 | ||
1141 | if (!addr || kernel == NULL) | 1142 | if (kernel == NULL) |
1142 | return -1; | 1143 | return -1; |
1143 | 1144 | ||
1144 | ret = __machine__create_kernel_maps(machine, kernel); | 1145 | ret = __machine__create_kernel_maps(machine, kernel); |
@@ -1160,8 +1161,9 @@ int machine__create_kernel_maps(struct machine *machine) | |||
1160 | */ | 1161 | */ |
1161 | map_groups__fixup_end(&machine->kmaps); | 1162 | map_groups__fixup_end(&machine->kmaps); |
1162 | 1163 | ||
1163 | if (maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, | 1164 | addr = machine__get_running_kernel_start(machine, &name); |
1164 | addr)) { | 1165 | if (!addr) { |
1166 | } else if (maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, addr)) { | ||
1165 | machine__destroy_kernel_maps(machine); | 1167 | machine__destroy_kernel_maps(machine); |
1166 | return -1; | 1168 | return -1; |
1167 | } | 1169 | } |
@@ -1769,11 +1771,6 @@ static int resolve_lbr_callchain_sample(struct thread *thread, | |||
1769 | */ | 1771 | */ |
1770 | int mix_chain_nr = i + 1 + lbr_nr + 1; | 1772 | int mix_chain_nr = i + 1 + lbr_nr + 1; |
1771 | 1773 | ||
1772 | if (mix_chain_nr > (int)sysctl_perf_event_max_stack + PERF_MAX_BRANCH_DEPTH) { | ||
1773 | pr_warning("corrupted callchain. skipping...\n"); | ||
1774 | return 0; | ||
1775 | } | ||
1776 | |||
1777 | for (j = 0; j < mix_chain_nr; j++) { | 1774 | for (j = 0; j < mix_chain_nr; j++) { |
1778 | if (callchain_param.order == ORDER_CALLEE) { | 1775 | if (callchain_param.order == ORDER_CALLEE) { |
1779 | if (j < i + 1) | 1776 | if (j < i + 1) |
@@ -1811,9 +1808,9 @@ static int thread__resolve_callchain_sample(struct thread *thread, | |||
1811 | { | 1808 | { |
1812 | struct branch_stack *branch = sample->branch_stack; | 1809 | struct branch_stack *branch = sample->branch_stack; |
1813 | struct ip_callchain *chain = sample->callchain; | 1810 | struct ip_callchain *chain = sample->callchain; |
1814 | int chain_nr = min(max_stack, (int)chain->nr); | 1811 | int chain_nr = chain->nr; |
1815 | u8 cpumode = PERF_RECORD_MISC_USER; | 1812 | u8 cpumode = PERF_RECORD_MISC_USER; |
1816 | int i, j, err; | 1813 | int i, j, err, nr_entries; |
1817 | int skip_idx = -1; | 1814 | int skip_idx = -1; |
1818 | int first_call = 0; | 1815 | int first_call = 0; |
1819 | 1816 | ||
@@ -1828,8 +1825,7 @@ static int thread__resolve_callchain_sample(struct thread *thread, | |||
1828 | * Based on DWARF debug information, some architectures skip | 1825 | * Based on DWARF debug information, some architectures skip |
1829 | * a callchain entry saved by the kernel. | 1826 | * a callchain entry saved by the kernel. |
1830 | */ | 1827 | */ |
1831 | if (chain->nr < sysctl_perf_event_max_stack) | 1828 | skip_idx = arch_skip_callchain_idx(thread, chain); |
1832 | skip_idx = arch_skip_callchain_idx(thread, chain); | ||
1833 | 1829 | ||
1834 | /* | 1830 | /* |
1835 | * Add branches to call stack for easier browsing. This gives | 1831 | * Add branches to call stack for easier browsing. This gives |
@@ -1889,12 +1885,8 @@ static int thread__resolve_callchain_sample(struct thread *thread, | |||
1889 | } | 1885 | } |
1890 | 1886 | ||
1891 | check_calls: | 1887 | check_calls: |
1892 | if (chain->nr > sysctl_perf_event_max_stack && (int)chain->nr > max_stack) { | 1888 | for (i = first_call, nr_entries = 0; |
1893 | pr_warning("corrupted callchain. skipping...\n"); | 1889 | i < chain_nr && nr_entries < max_stack; i++) { |
1894 | return 0; | ||
1895 | } | ||
1896 | |||
1897 | for (i = first_call; i < chain_nr; i++) { | ||
1898 | u64 ip; | 1890 | u64 ip; |
1899 | 1891 | ||
1900 | if (callchain_param.order == ORDER_CALLEE) | 1892 | if (callchain_param.order == ORDER_CALLEE) |
@@ -1908,6 +1900,9 @@ check_calls: | |||
1908 | #endif | 1900 | #endif |
1909 | ip = chain->ips[j]; | 1901 | ip = chain->ips[j]; |
1910 | 1902 | ||
1903 | if (ip < PERF_CONTEXT_MAX) | ||
1904 | ++nr_entries; | ||
1905 | |||
1911 | err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip); | 1906 | err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip); |
1912 | 1907 | ||
1913 | if (err) | 1908 | if (err) |