aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile6
-rw-r--r--tools/build/Makefile.build8
-rw-r--r--tools/kvm/kvm_stat/Makefile41
-rwxr-xr-xtools/kvm/kvm_stat/kvm_stat1127
-rw-r--r--tools/kvm/kvm_stat/kvm_stat.txt63
-rw-r--r--tools/objtool/Makefile4
-rw-r--r--tools/objtool/builtin-check.c8
-rw-r--r--tools/objtool/elf.h5
-rw-r--r--tools/perf/Documentation/perf-report.txt5
-rw-r--r--tools/perf/Documentation/perf-script.txt2
-rw-r--r--tools/perf/Documentation/perf-trace.txt3
-rw-r--r--tools/perf/builtin-annotate.c5
-rw-r--r--tools/perf/builtin-buildid-cache.c8
-rw-r--r--tools/perf/builtin-diff.c5
-rw-r--r--tools/perf/builtin-record.c81
-rw-r--r--tools/perf/builtin-report.c7
-rw-r--r--tools/perf/builtin-script.c7
-rw-r--r--tools/perf/builtin-stat.c22
-rw-r--r--tools/perf/builtin-timechart.c5
-rw-r--r--tools/perf/builtin-top.c6
-rw-r--r--tools/perf/builtin-trace.c274
-rw-r--r--tools/perf/perf.c3
-rw-r--r--tools/perf/util/annotate.c32
-rw-r--r--tools/perf/util/build-id.c2
-rw-r--r--tools/perf/util/data-convert-bt.c41
-rw-r--r--tools/perf/util/db-export.c3
-rw-r--r--tools/perf/util/dso.c7
-rw-r--r--tools/perf/util/event.c2
-rw-r--r--tools/perf/util/evlist.c34
-rw-r--r--tools/perf/util/evlist.h4
-rw-r--r--tools/perf/util/evsel.c13
-rw-r--r--tools/perf/util/evsel.h1
-rw-r--r--tools/perf/util/hist.c9
-rw-r--r--tools/perf/util/hist.h2
-rw-r--r--tools/perf/util/machine.c35
-rw-r--r--tools/perf/util/machine.h1
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c3
-rw-r--r--tools/perf/util/sort.c84
-rw-r--r--tools/perf/util/sort.h2
-rw-r--r--tools/perf/util/stat-shadow.c8
-rw-r--r--tools/perf/util/symbol.c49
-rw-r--r--tools/perf/util/symbol.h7
-rw-r--r--tools/perf/util/top.h1
-rw-r--r--tools/perf/util/util.c3
-rw-r--r--tools/perf/util/util.h3
-rw-r--r--tools/testing/radix-tree/tag_check.c2
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc9
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/trigger-hist.tc9
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/trigger-multihist.tc9
-rw-r--r--tools/testing/selftests/net/reuseport_bpf.c10
-rw-r--r--tools/testing/selftests/seccomp/seccomp_bpf.c8
-rw-r--r--tools/testing/selftests/vm/compaction_test.c2
-rw-r--r--tools/testing/selftests/vm/thuge-gen.c2
-rw-r--r--tools/virtio/ringtest/Makefile4
-rw-r--r--tools/virtio/ringtest/README4
-rw-r--r--tools/virtio/ringtest/noring.c69
-rwxr-xr-xtools/virtio/ringtest/run-on-all.sh4
-rw-r--r--tools/vm/slabinfo.c5
58 files changed, 1886 insertions, 292 deletions
diff --git a/tools/Makefile b/tools/Makefile
index 6bf68fe7dd29..f10b64d8c674 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -16,6 +16,7 @@ help:
16 @echo ' gpio - GPIO tools' 16 @echo ' gpio - GPIO tools'
17 @echo ' hv - tools used when in Hyper-V clients' 17 @echo ' hv - tools used when in Hyper-V clients'
18 @echo ' iio - IIO tools' 18 @echo ' iio - IIO tools'
19 @echo ' kvm_stat - top-like utility for displaying kvm statistics'
19 @echo ' lguest - a minimal 32-bit x86 hypervisor' 20 @echo ' lguest - a minimal 32-bit x86 hypervisor'
20 @echo ' net - misc networking tools' 21 @echo ' net - misc networking tools'
21 @echo ' perf - Linux performance measurement and analysis tool' 22 @echo ' perf - Linux performance measurement and analysis tool'
@@ -110,10 +111,13 @@ tmon_install:
110freefall_install: 111freefall_install:
111 $(call descend,laptop/$(@:_install=),install) 112 $(call descend,laptop/$(@:_install=),install)
112 113
114kvm_stat_install:
115 $(call descend,kvm/$(@:_install=),install)
116
113install: acpi_install cgroup_install cpupower_install hv_install firewire_install lguest_install \ 117install: acpi_install cgroup_install cpupower_install hv_install firewire_install lguest_install \
114 perf_install selftests_install turbostat_install usb_install \ 118 perf_install selftests_install turbostat_install usb_install \
115 virtio_install vm_install net_install x86_energy_perf_policy_install \ 119 virtio_install vm_install net_install x86_energy_perf_policy_install \
116 tmon_install freefall_install objtool_install 120 tmon_install freefall_install objtool_install kvm_stat_install
117 121
118acpi_clean: 122acpi_clean:
119 $(call descend,power/acpi,clean) 123 $(call descend,power/acpi,clean)
diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build
index ee566e8bd1cf..27f3583193e6 100644
--- a/tools/build/Makefile.build
+++ b/tools/build/Makefile.build
@@ -58,8 +58,8 @@ quiet_cmd_mkdir = MKDIR $(dir $@)
58quiet_cmd_cc_o_c = CC $@ 58quiet_cmd_cc_o_c = CC $@
59 cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< 59 cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
60 60
61quiet_cmd_cc_i_c = CPP $@ 61quiet_cmd_cpp_i_c = CPP $@
62 cmd_cc_i_c = $(CC) $(c_flags) -E -o $@ $< 62 cmd_cpp_i_c = $(CC) $(c_flags) -E -o $@ $<
63 63
64quiet_cmd_cc_s_c = AS $@ 64quiet_cmd_cc_s_c = AS $@
65 cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $< 65 cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $<
@@ -83,11 +83,11 @@ $(OUTPUT)%.o: %.S FORCE
83 83
84$(OUTPUT)%.i: %.c FORCE 84$(OUTPUT)%.i: %.c FORCE
85 $(call rule_mkdir) 85 $(call rule_mkdir)
86 $(call if_changed_dep,cc_i_c) 86 $(call if_changed_dep,cpp_i_c)
87 87
88$(OUTPUT)%.s: %.S FORCE 88$(OUTPUT)%.s: %.S FORCE
89 $(call rule_mkdir) 89 $(call rule_mkdir)
90 $(call if_changed_dep,cc_i_c) 90 $(call if_changed_dep,cpp_i_c)
91 91
92$(OUTPUT)%.s: %.c FORCE 92$(OUTPUT)%.s: %.c FORCE
93 $(call rule_mkdir) 93 $(call rule_mkdir)
diff --git a/tools/kvm/kvm_stat/Makefile b/tools/kvm/kvm_stat/Makefile
new file mode 100644
index 000000000000..5b1cba57e3b3
--- /dev/null
+++ b/tools/kvm/kvm_stat/Makefile
@@ -0,0 +1,41 @@
1include ../../scripts/Makefile.include
2include ../../scripts/utilities.mak
3BINDIR=usr/bin
4MANDIR=usr/share/man
5MAN1DIR=$(MANDIR)/man1
6
7MAN1=kvm_stat.1
8
9A2X=a2x
10a2x_path := $(call get-executable,$(A2X))
11
12all: man
13
14ifneq ($(findstring $(MAKEFLAGS),s),s)
15 ifneq ($(V),1)
16 QUIET_A2X = @echo ' A2X '$@;
17 endif
18endif
19
20%.1: %.txt
21ifeq ($(a2x_path),)
22 $(error "You need to install asciidoc for man pages")
23else
24 $(QUIET_A2X)$(A2X) --doctype manpage --format manpage $<
25endif
26
27clean:
28 rm -f $(MAN1)
29
30man: $(MAN1)
31
32install-man: man
33 install -d -m 755 $(INSTALL_ROOT)/$(MAN1DIR)
34 install -m 644 kvm_stat.1 $(INSTALL_ROOT)/$(MAN1DIR)
35
36install-tools:
37 install -d -m 755 $(INSTALL_ROOT)/$(BINDIR)
38 install -m 755 -p "kvm_stat" "$(INSTALL_ROOT)/$(BINDIR)/$(TARGET)"
39
40install: install-tools install-man
41.PHONY: all clean man install-tools install-man install
diff --git a/tools/kvm/kvm_stat/kvm_stat b/tools/kvm/kvm_stat/kvm_stat
new file mode 100755
index 000000000000..581278c58488
--- /dev/null
+++ b/tools/kvm/kvm_stat/kvm_stat
@@ -0,0 +1,1127 @@
1#!/usr/bin/python
2#
3# top-like utility for displaying kvm statistics
4#
5# Copyright 2006-2008 Qumranet Technologies
6# Copyright 2008-2011 Red Hat, Inc.
7#
8# Authors:
9# Avi Kivity <avi@redhat.com>
10#
11# This work is licensed under the terms of the GNU GPL, version 2. See
12# the COPYING file in the top-level directory.
13"""The kvm_stat module outputs statistics about running KVM VMs
14
15Three different ways of output formatting are available:
16- as a top-like text ui
17- in a key -> value format
18- in an all keys, all values format
19
20The data is sampled from the KVM's debugfs entries and its perf events.
21"""
22
23import curses
24import sys
25import os
26import time
27import optparse
28import ctypes
29import fcntl
30import resource
31import struct
32import re
33from collections import defaultdict
34from time import sleep
35
36VMX_EXIT_REASONS = {
37 'EXCEPTION_NMI': 0,
38 'EXTERNAL_INTERRUPT': 1,
39 'TRIPLE_FAULT': 2,
40 'PENDING_INTERRUPT': 7,
41 'NMI_WINDOW': 8,
42 'TASK_SWITCH': 9,
43 'CPUID': 10,
44 'HLT': 12,
45 'INVLPG': 14,
46 'RDPMC': 15,
47 'RDTSC': 16,
48 'VMCALL': 18,
49 'VMCLEAR': 19,
50 'VMLAUNCH': 20,
51 'VMPTRLD': 21,
52 'VMPTRST': 22,
53 'VMREAD': 23,
54 'VMRESUME': 24,
55 'VMWRITE': 25,
56 'VMOFF': 26,
57 'VMON': 27,
58 'CR_ACCESS': 28,
59 'DR_ACCESS': 29,
60 'IO_INSTRUCTION': 30,
61 'MSR_READ': 31,
62 'MSR_WRITE': 32,
63 'INVALID_STATE': 33,
64 'MWAIT_INSTRUCTION': 36,
65 'MONITOR_INSTRUCTION': 39,
66 'PAUSE_INSTRUCTION': 40,
67 'MCE_DURING_VMENTRY': 41,
68 'TPR_BELOW_THRESHOLD': 43,
69 'APIC_ACCESS': 44,
70 'EPT_VIOLATION': 48,
71 'EPT_MISCONFIG': 49,
72 'WBINVD': 54,
73 'XSETBV': 55,
74 'APIC_WRITE': 56,
75 'INVPCID': 58,
76}
77
78SVM_EXIT_REASONS = {
79 'READ_CR0': 0x000,
80 'READ_CR3': 0x003,
81 'READ_CR4': 0x004,
82 'READ_CR8': 0x008,
83 'WRITE_CR0': 0x010,
84 'WRITE_CR3': 0x013,
85 'WRITE_CR4': 0x014,
86 'WRITE_CR8': 0x018,
87 'READ_DR0': 0x020,
88 'READ_DR1': 0x021,
89 'READ_DR2': 0x022,
90 'READ_DR3': 0x023,
91 'READ_DR4': 0x024,
92 'READ_DR5': 0x025,
93 'READ_DR6': 0x026,
94 'READ_DR7': 0x027,
95 'WRITE_DR0': 0x030,
96 'WRITE_DR1': 0x031,
97 'WRITE_DR2': 0x032,
98 'WRITE_DR3': 0x033,
99 'WRITE_DR4': 0x034,
100 'WRITE_DR5': 0x035,
101 'WRITE_DR6': 0x036,
102 'WRITE_DR7': 0x037,
103 'EXCP_BASE': 0x040,
104 'INTR': 0x060,
105 'NMI': 0x061,
106 'SMI': 0x062,
107 'INIT': 0x063,
108 'VINTR': 0x064,
109 'CR0_SEL_WRITE': 0x065,
110 'IDTR_READ': 0x066,
111 'GDTR_READ': 0x067,
112 'LDTR_READ': 0x068,
113 'TR_READ': 0x069,
114 'IDTR_WRITE': 0x06a,
115 'GDTR_WRITE': 0x06b,
116 'LDTR_WRITE': 0x06c,
117 'TR_WRITE': 0x06d,
118 'RDTSC': 0x06e,
119 'RDPMC': 0x06f,
120 'PUSHF': 0x070,
121 'POPF': 0x071,
122 'CPUID': 0x072,
123 'RSM': 0x073,
124 'IRET': 0x074,
125 'SWINT': 0x075,
126 'INVD': 0x076,
127 'PAUSE': 0x077,
128 'HLT': 0x078,
129 'INVLPG': 0x079,
130 'INVLPGA': 0x07a,
131 'IOIO': 0x07b,
132 'MSR': 0x07c,
133 'TASK_SWITCH': 0x07d,
134 'FERR_FREEZE': 0x07e,
135 'SHUTDOWN': 0x07f,
136 'VMRUN': 0x080,
137 'VMMCALL': 0x081,
138 'VMLOAD': 0x082,
139 'VMSAVE': 0x083,
140 'STGI': 0x084,
141 'CLGI': 0x085,
142 'SKINIT': 0x086,
143 'RDTSCP': 0x087,
144 'ICEBP': 0x088,
145 'WBINVD': 0x089,
146 'MONITOR': 0x08a,
147 'MWAIT': 0x08b,
148 'MWAIT_COND': 0x08c,
149 'XSETBV': 0x08d,
150 'NPF': 0x400,
151}
152
153# EC definition of HSR (from arch/arm64/include/asm/kvm_arm.h)
154AARCH64_EXIT_REASONS = {
155 'UNKNOWN': 0x00,
156 'WFI': 0x01,
157 'CP15_32': 0x03,
158 'CP15_64': 0x04,
159 'CP14_MR': 0x05,
160 'CP14_LS': 0x06,
161 'FP_ASIMD': 0x07,
162 'CP10_ID': 0x08,
163 'CP14_64': 0x0C,
164 'ILL_ISS': 0x0E,
165 'SVC32': 0x11,
166 'HVC32': 0x12,
167 'SMC32': 0x13,
168 'SVC64': 0x15,
169 'HVC64': 0x16,
170 'SMC64': 0x17,
171 'SYS64': 0x18,
172 'IABT': 0x20,
173 'IABT_HYP': 0x21,
174 'PC_ALIGN': 0x22,
175 'DABT': 0x24,
176 'DABT_HYP': 0x25,
177 'SP_ALIGN': 0x26,
178 'FP_EXC32': 0x28,
179 'FP_EXC64': 0x2C,
180 'SERROR': 0x2F,
181 'BREAKPT': 0x30,
182 'BREAKPT_HYP': 0x31,
183 'SOFTSTP': 0x32,
184 'SOFTSTP_HYP': 0x33,
185 'WATCHPT': 0x34,
186 'WATCHPT_HYP': 0x35,
187 'BKPT32': 0x38,
188 'VECTOR32': 0x3A,
189 'BRK64': 0x3C,
190}
191
192# From include/uapi/linux/kvm.h, KVM_EXIT_xxx
193USERSPACE_EXIT_REASONS = {
194 'UNKNOWN': 0,
195 'EXCEPTION': 1,
196 'IO': 2,
197 'HYPERCALL': 3,
198 'DEBUG': 4,
199 'HLT': 5,
200 'MMIO': 6,
201 'IRQ_WINDOW_OPEN': 7,
202 'SHUTDOWN': 8,
203 'FAIL_ENTRY': 9,
204 'INTR': 10,
205 'SET_TPR': 11,
206 'TPR_ACCESS': 12,
207 'S390_SIEIC': 13,
208 'S390_RESET': 14,
209 'DCR': 15,
210 'NMI': 16,
211 'INTERNAL_ERROR': 17,
212 'OSI': 18,
213 'PAPR_HCALL': 19,
214 'S390_UCONTROL': 20,
215 'WATCHDOG': 21,
216 'S390_TSCH': 22,
217 'EPR': 23,
218 'SYSTEM_EVENT': 24,
219}
220
221IOCTL_NUMBERS = {
222 'SET_FILTER': 0x40082406,
223 'ENABLE': 0x00002400,
224 'DISABLE': 0x00002401,
225 'RESET': 0x00002403,
226}
227
228class Arch(object):
229 """Encapsulates global architecture specific data.
230
231 Contains the performance event open syscall and ioctl numbers, as
232 well as the VM exit reasons for the architecture it runs on.
233
234 """
235 @staticmethod
236 def get_arch():
237 machine = os.uname()[4]
238
239 if machine.startswith('ppc'):
240 return ArchPPC()
241 elif machine.startswith('aarch64'):
242 return ArchA64()
243 elif machine.startswith('s390'):
244 return ArchS390()
245 else:
246 # X86_64
247 for line in open('/proc/cpuinfo'):
248 if not line.startswith('flags'):
249 continue
250
251 flags = line.split()
252 if 'vmx' in flags:
253 return ArchX86(VMX_EXIT_REASONS)
254 if 'svm' in flags:
255 return ArchX86(SVM_EXIT_REASONS)
256 return
257
258class ArchX86(Arch):
259 def __init__(self, exit_reasons):
260 self.sc_perf_evt_open = 298
261 self.ioctl_numbers = IOCTL_NUMBERS
262 self.exit_reasons = exit_reasons
263
264class ArchPPC(Arch):
265 def __init__(self):
266 self.sc_perf_evt_open = 319
267 self.ioctl_numbers = IOCTL_NUMBERS
268 self.ioctl_numbers['ENABLE'] = 0x20002400
269 self.ioctl_numbers['DISABLE'] = 0x20002401
270 self.ioctl_numbers['RESET'] = 0x20002403
271
272 # PPC comes in 32 and 64 bit and some generated ioctl
273 # numbers depend on the wordsize.
274 char_ptr_size = ctypes.sizeof(ctypes.c_char_p)
275 self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16
276 self.exit_reasons = {}
277
278class ArchA64(Arch):
279 def __init__(self):
280 self.sc_perf_evt_open = 241
281 self.ioctl_numbers = IOCTL_NUMBERS
282 self.exit_reasons = AARCH64_EXIT_REASONS
283
284class ArchS390(Arch):
285 def __init__(self):
286 self.sc_perf_evt_open = 331
287 self.ioctl_numbers = IOCTL_NUMBERS
288 self.exit_reasons = None
289
290ARCH = Arch.get_arch()
291
292
293def walkdir(path):
294 """Returns os.walk() data for specified directory.
295
296 As it is only a wrapper it returns the same 3-tuple of (dirpath,
297 dirnames, filenames).
298 """
299 return next(os.walk(path))
300
301
302def parse_int_list(list_string):
303 """Returns an int list from a string of comma separated integers and
304 integer ranges."""
305 integers = []
306 members = list_string.split(',')
307
308 for member in members:
309 if '-' not in member:
310 integers.append(int(member))
311 else:
312 int_range = member.split('-')
313 integers.extend(range(int(int_range[0]),
314 int(int_range[1]) + 1))
315
316 return integers
317
318
319def get_online_cpus():
320 """Returns a list of cpu id integers."""
321 with open('/sys/devices/system/cpu/online') as cpu_list:
322 cpu_string = cpu_list.readline()
323 return parse_int_list(cpu_string)
324
325
326def get_filters():
327 """Returns a dict of trace events, their filter ids and
328 the values that can be filtered.
329
330 Trace events can be filtered for special values by setting a
331 filter string via an ioctl. The string normally has the format
332 identifier==value. For each filter a new event will be created, to
333 be able to distinguish the events.
334
335 """
336 filters = {}
337 filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS)
338 if ARCH.exit_reasons:
339 filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons)
340 return filters
341
342libc = ctypes.CDLL('libc.so.6', use_errno=True)
343syscall = libc.syscall
344
345class perf_event_attr(ctypes.Structure):
346 """Struct that holds the necessary data to set up a trace event.
347
348 For an extensive explanation see perf_event_open(2) and
349 include/uapi/linux/perf_event.h, struct perf_event_attr
350
351 All fields that are not initialized in the constructor are 0.
352
353 """
354 _fields_ = [('type', ctypes.c_uint32),
355 ('size', ctypes.c_uint32),
356 ('config', ctypes.c_uint64),
357 ('sample_freq', ctypes.c_uint64),
358 ('sample_type', ctypes.c_uint64),
359 ('read_format', ctypes.c_uint64),
360 ('flags', ctypes.c_uint64),
361 ('wakeup_events', ctypes.c_uint32),
362 ('bp_type', ctypes.c_uint32),
363 ('bp_addr', ctypes.c_uint64),
364 ('bp_len', ctypes.c_uint64),
365 ]
366
367 def __init__(self):
368 super(self.__class__, self).__init__()
369 self.type = PERF_TYPE_TRACEPOINT
370 self.size = ctypes.sizeof(self)
371 self.read_format = PERF_FORMAT_GROUP
372
373def perf_event_open(attr, pid, cpu, group_fd, flags):
374 """Wrapper for the sys_perf_evt_open() syscall.
375
376 Used to set up performance events, returns a file descriptor or -1
377 on error.
378
379 Attributes are:
380 - syscall number
381 - struct perf_event_attr *
382 - pid or -1 to monitor all pids
383 - cpu number or -1 to monitor all cpus
384 - The file descriptor of the group leader or -1 to create a group.
385 - flags
386
387 """
388 return syscall(ARCH.sc_perf_evt_open, ctypes.pointer(attr),
389 ctypes.c_int(pid), ctypes.c_int(cpu),
390 ctypes.c_int(group_fd), ctypes.c_long(flags))
391
392PERF_TYPE_TRACEPOINT = 2
393PERF_FORMAT_GROUP = 1 << 3
394
395PATH_DEBUGFS_TRACING = '/sys/kernel/debug/tracing'
396PATH_DEBUGFS_KVM = '/sys/kernel/debug/kvm'
397
398class Group(object):
399 """Represents a perf event group."""
400
401 def __init__(self):
402 self.events = []
403
404 def add_event(self, event):
405 self.events.append(event)
406
407 def read(self):
408 """Returns a dict with 'event name: value' for all events in the
409 group.
410
411 Values are read by reading from the file descriptor of the
412 event that is the group leader. See perf_event_open(2) for
413 details.
414
415 Read format for the used event configuration is:
416 struct read_format {
417 u64 nr; /* The number of events */
418 struct {
419 u64 value; /* The value of the event */
420 } values[nr];
421 };
422
423 """
424 length = 8 * (1 + len(self.events))
425 read_format = 'xxxxxxxx' + 'Q' * len(self.events)
426 return dict(zip([event.name for event in self.events],
427 struct.unpack(read_format,
428 os.read(self.events[0].fd, length))))
429
430class Event(object):
431 """Represents a performance event and manages its life cycle."""
432 def __init__(self, name, group, trace_cpu, trace_pid, trace_point,
433 trace_filter, trace_set='kvm'):
434 self.name = name
435 self.fd = None
436 self.setup_event(group, trace_cpu, trace_pid, trace_point,
437 trace_filter, trace_set)
438
439 def __del__(self):
440 """Closes the event's file descriptor.
441
442 As no python file object was created for the file descriptor,
443 python will not reference count the descriptor and will not
444 close it itself automatically, so we do it.
445
446 """
447 if self.fd:
448 os.close(self.fd)
449
450 def setup_event_attribute(self, trace_set, trace_point):
451 """Returns an initialized ctype perf_event_attr struct."""
452
453 id_path = os.path.join(PATH_DEBUGFS_TRACING, 'events', trace_set,
454 trace_point, 'id')
455
456 event_attr = perf_event_attr()
457 event_attr.config = int(open(id_path).read())
458 return event_attr
459
460 def setup_event(self, group, trace_cpu, trace_pid, trace_point,
461 trace_filter, trace_set):
462 """Sets up the perf event in Linux.
463
464 Issues the syscall to register the event in the kernel and
465 then sets the optional filter.
466
467 """
468
469 event_attr = self.setup_event_attribute(trace_set, trace_point)
470
471 # First event will be group leader.
472 group_leader = -1
473
474 # All others have to pass the leader's descriptor instead.
475 if group.events:
476 group_leader = group.events[0].fd
477
478 fd = perf_event_open(event_attr, trace_pid,
479 trace_cpu, group_leader, 0)
480 if fd == -1:
481 err = ctypes.get_errno()
482 raise OSError(err, os.strerror(err),
483 'while calling sys_perf_event_open().')
484
485 if trace_filter:
486 fcntl.ioctl(fd, ARCH.ioctl_numbers['SET_FILTER'],
487 trace_filter)
488
489 self.fd = fd
490
491 def enable(self):
492 """Enables the trace event in the kernel.
493
494 Enabling the group leader makes reading counters from it and the
495 events under it possible.
496
497 """
498 fcntl.ioctl(self.fd, ARCH.ioctl_numbers['ENABLE'], 0)
499
500 def disable(self):
501 """Disables the trace event in the kernel.
502
503 Disabling the group leader makes reading all counters under it
504 impossible.
505
506 """
507 fcntl.ioctl(self.fd, ARCH.ioctl_numbers['DISABLE'], 0)
508
509 def reset(self):
510 """Resets the count of the trace event in the kernel."""
511 fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0)
512
513class TracepointProvider(object):
514 """Data provider for the stats class.
515
516 Manages the events/groups from which it acquires its data.
517
518 """
519 def __init__(self):
520 self.group_leaders = []
521 self.filters = get_filters()
522 self._fields = self.get_available_fields()
523 self._pid = 0
524
525 def get_available_fields(self):
526 """Returns a list of available event's of format 'event name(filter
527 name)'.
528
529 All available events have directories under
530 /sys/kernel/debug/tracing/events/ which export information
531 about the specific event. Therefore, listing the dirs gives us
532 a list of all available events.
533
534 Some events like the vm exit reasons can be filtered for
535 specific values. To take account for that, the routine below
536 creates special fields with the following format:
537 event name(filter name)
538
539 """
540 path = os.path.join(PATH_DEBUGFS_TRACING, 'events', 'kvm')
541 fields = walkdir(path)[1]
542 extra = []
543 for field in fields:
544 if field in self.filters:
545 filter_name_, filter_dicts = self.filters[field]
546 for name in filter_dicts:
547 extra.append(field + '(' + name + ')')
548 fields += extra
549 return fields
550
551 def setup_traces(self):
552 """Creates all event and group objects needed to be able to retrieve
553 data."""
554 if self._pid > 0:
555 # Fetch list of all threads of the monitored pid, as qemu
556 # starts a thread for each vcpu.
557 path = os.path.join('/proc', str(self._pid), 'task')
558 groupids = walkdir(path)[1]
559 else:
560 groupids = get_online_cpus()
561
562 # The constant is needed as a buffer for python libs, std
563 # streams and other files that the script opens.
564 newlim = len(groupids) * len(self._fields) + 50
565 try:
566 softlim_, hardlim = resource.getrlimit(resource.RLIMIT_NOFILE)
567
568 if hardlim < newlim:
569 # Now we need CAP_SYS_RESOURCE, to increase the hard limit.
570 resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, newlim))
571 else:
572 # Raising the soft limit is sufficient.
573 resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, hardlim))
574
575 except ValueError:
576 sys.exit("NOFILE rlimit could not be raised to {0}".format(newlim))
577
578 for groupid in groupids:
579 group = Group()
580 for name in self._fields:
581 tracepoint = name
582 tracefilter = None
583 match = re.match(r'(.*)\((.*)\)', name)
584 if match:
585 tracepoint, sub = match.groups()
586 tracefilter = ('%s==%d\0' %
587 (self.filters[tracepoint][0],
588 self.filters[tracepoint][1][sub]))
589
590 # From perf_event_open(2):
591 # pid > 0 and cpu == -1
592 # This measures the specified process/thread on any CPU.
593 #
594 # pid == -1 and cpu >= 0
595 # This measures all processes/threads on the specified CPU.
596 trace_cpu = groupid if self._pid == 0 else -1
597 trace_pid = int(groupid) if self._pid != 0 else -1
598
599 group.add_event(Event(name=name,
600 group=group,
601 trace_cpu=trace_cpu,
602 trace_pid=trace_pid,
603 trace_point=tracepoint,
604 trace_filter=tracefilter))
605
606 self.group_leaders.append(group)
607
608 def available_fields(self):
609 return self.get_available_fields()
610
611 @property
612 def fields(self):
613 return self._fields
614
615 @fields.setter
616 def fields(self, fields):
617 """Enables/disables the (un)wanted events"""
618 self._fields = fields
619 for group in self.group_leaders:
620 for index, event in enumerate(group.events):
621 if event.name in fields:
622 event.reset()
623 event.enable()
624 else:
625 # Do not disable the group leader.
626 # It would disable all of its events.
627 if index != 0:
628 event.disable()
629
630 @property
631 def pid(self):
632 return self._pid
633
634 @pid.setter
635 def pid(self, pid):
636 """Changes the monitored pid by setting new traces."""
637 self._pid = pid
638 # The garbage collector will get rid of all Event/Group
639 # objects and open files after removing the references.
640 self.group_leaders = []
641 self.setup_traces()
642 self.fields = self._fields
643
644 def read(self):
645 """Returns 'event name: current value' for all enabled events."""
646 ret = defaultdict(int)
647 for group in self.group_leaders:
648 for name, val in group.read().iteritems():
649 if name in self._fields:
650 ret[name] += val
651 return ret
652
653class DebugfsProvider(object):
654 """Provides data from the files that KVM creates in the kvm debugfs
655 folder."""
656 def __init__(self):
657 self._fields = self.get_available_fields()
658 self._pid = 0
659 self.do_read = True
660
661 def get_available_fields(self):
662 """"Returns a list of available fields.
663
664 The fields are all available KVM debugfs files
665
666 """
667 return walkdir(PATH_DEBUGFS_KVM)[2]
668
669 @property
670 def fields(self):
671 return self._fields
672
673 @fields.setter
674 def fields(self, fields):
675 self._fields = fields
676
677 @property
678 def pid(self):
679 return self._pid
680
681 @pid.setter
682 def pid(self, pid):
683 if pid != 0:
684 self._pid = pid
685
686 vms = walkdir(PATH_DEBUGFS_KVM)[1]
687 if len(vms) == 0:
688 self.do_read = False
689
690 self.paths = filter(lambda x: "{}-".format(pid) in x, vms)
691
692 else:
693 self.paths = ['']
694 self.do_read = True
695
696 def read(self):
697 """Returns a dict with format:'file name / field -> current value'."""
698 results = {}
699
700 # If no debugfs filtering support is available, then don't read.
701 if not self.do_read:
702 return results
703
704 for path in self.paths:
705 for field in self._fields:
706 results[field] = results.get(field, 0) \
707 + self.read_field(field, path)
708
709 return results
710
711 def read_field(self, field, path):
712 """Returns the value of a single field from a specific VM."""
713 try:
714 return int(open(os.path.join(PATH_DEBUGFS_KVM,
715 path,
716 field))
717 .read())
718 except IOError:
719 return 0
720
721class Stats(object):
722 """Manages the data providers and the data they provide.
723
724 It is used to set filters on the provider's data and collect all
725 provider data.
726
727 """
728 def __init__(self, providers, pid, fields=None):
729 self.providers = providers
730 self._pid_filter = pid
731 self._fields_filter = fields
732 self.values = {}
733 self.update_provider_pid()
734 self.update_provider_filters()
735
736 def update_provider_filters(self):
737 """Propagates fields filters to providers."""
738 def wanted(key):
739 if not self._fields_filter:
740 return True
741 return re.match(self._fields_filter, key) is not None
742
743 # As we reset the counters when updating the fields we can
744 # also clear the cache of old values.
745 self.values = {}
746 for provider in self.providers:
747 provider_fields = [key for key in provider.get_available_fields()
748 if wanted(key)]
749 provider.fields = provider_fields
750
751 def update_provider_pid(self):
752 """Propagates pid filters to providers."""
753 for provider in self.providers:
754 provider.pid = self._pid_filter
755
756 @property
757 def fields_filter(self):
758 return self._fields_filter
759
760 @fields_filter.setter
761 def fields_filter(self, fields_filter):
762 self._fields_filter = fields_filter
763 self.update_provider_filters()
764
765 @property
766 def pid_filter(self):
767 return self._pid_filter
768
769 @pid_filter.setter
770 def pid_filter(self, pid):
771 self._pid_filter = pid
772 self.values = {}
773 self.update_provider_pid()
774
775 def get(self):
776 """Returns a dict with field -> (value, delta to last value) of all
777 provider data."""
778 for provider in self.providers:
779 new = provider.read()
780 for key in provider.fields:
781 oldval = self.values.get(key, (0, 0))
782 newval = new.get(key, 0)
783 newdelta = None
784 if oldval is not None:
785 newdelta = newval - oldval[0]
786 self.values[key] = (newval, newdelta)
787 return self.values
788
789LABEL_WIDTH = 40
790NUMBER_WIDTH = 10
791
792class Tui(object):
793 """Instruments curses to draw a nice text ui."""
794 def __init__(self, stats):
795 self.stats = stats
796 self.screen = None
797 self.drilldown = False
798 self.update_drilldown()
799
800 def __enter__(self):
801 """Initialises curses for later use. Based on curses.wrapper
802 implementation from the Python standard library."""
803 self.screen = curses.initscr()
804 curses.noecho()
805 curses.cbreak()
806
807 # The try/catch works around a minor bit of
808 # over-conscientiousness in the curses module, the error
809 # return from C start_color() is ignorable.
810 try:
811 curses.start_color()
812 except:
813 pass
814
815 curses.use_default_colors()
816 return self
817
818 def __exit__(self, *exception):
819 """Resets the terminal to its normal state. Based on curses.wrappre
820 implementation from the Python standard library."""
821 if self.screen:
822 self.screen.keypad(0)
823 curses.echo()
824 curses.nocbreak()
825 curses.endwin()
826
827 def update_drilldown(self):
828 """Sets or removes a filter that only allows fields without braces."""
829 if not self.stats.fields_filter:
830 self.stats.fields_filter = r'^[^\(]*$'
831
832 elif self.stats.fields_filter == r'^[^\(]*$':
833 self.stats.fields_filter = None
834
835 def update_pid(self, pid):
836 """Propagates pid selection to stats object."""
837 self.stats.pid_filter = pid
838
839 def refresh(self, sleeptime):
840 """Refreshes on-screen data."""
841 self.screen.erase()
842 if self.stats.pid_filter > 0:
843 self.screen.addstr(0, 0, 'kvm statistics - pid {0}'
844 .format(self.stats.pid_filter),
845 curses.A_BOLD)
846 else:
847 self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
848 self.screen.addstr(2, 1, 'Event')
849 self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH -
850 len('Total'), 'Total')
851 self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 -
852 len('Current'), 'Current')
853 row = 3
854 stats = self.stats.get()
855 def sortkey(x):
856 if stats[x][1]:
857 return (-stats[x][1], -stats[x][0])
858 else:
859 return (0, -stats[x][0])
860 for key in sorted(stats.keys(), key=sortkey):
861
862 if row >= self.screen.getmaxyx()[0]:
863 break
864 values = stats[key]
865 if not values[0] and not values[1]:
866 break
867 col = 1
868 self.screen.addstr(row, col, key)
869 col += LABEL_WIDTH
870 self.screen.addstr(row, col, '%10d' % (values[0],))
871 col += NUMBER_WIDTH
872 if values[1] is not None:
873 self.screen.addstr(row, col, '%8d' % (values[1] / sleeptime,))
874 row += 1
875 self.screen.refresh()
876
877 def show_filter_selection(self):
878 """Draws filter selection mask.
879
880 Asks for a valid regex and sets the fields filter accordingly.
881
882 """
883 while True:
884 self.screen.erase()
885 self.screen.addstr(0, 0,
886 "Show statistics for events matching a regex.",
887 curses.A_BOLD)
888 self.screen.addstr(2, 0,
889 "Current regex: {0}"
890 .format(self.stats.fields_filter))
891 self.screen.addstr(3, 0, "New regex: ")
892 curses.echo()
893 regex = self.screen.getstr()
894 curses.noecho()
895 if len(regex) == 0:
896 return
897 try:
898 re.compile(regex)
899 self.stats.fields_filter = regex
900 return
901 except re.error:
902 continue
903
904 def show_vm_selection(self):
905 """Draws PID selection mask.
906
907 Asks for a pid until a valid pid or 0 has been entered.
908
909 """
910 while True:
911 self.screen.erase()
912 self.screen.addstr(0, 0,
913 'Show statistics for specific pid.',
914 curses.A_BOLD)
915 self.screen.addstr(1, 0,
916 'This might limit the shown data to the trace '
917 'statistics.')
918
919 curses.echo()
920 self.screen.addstr(3, 0, "Pid [0 or pid]: ")
921 pid = self.screen.getstr()
922 curses.noecho()
923
924 try:
925 pid = int(pid)
926
927 if pid == 0:
928 self.update_pid(pid)
929 break
930 else:
931 if not os.path.isdir(os.path.join('/proc/', str(pid))):
932 continue
933 else:
934 self.update_pid(pid)
935 break
936
937 except ValueError:
938 continue
939
940 def show_stats(self):
941 """Refreshes the screen and processes user input."""
942 sleeptime = 0.25
943 while True:
944 self.refresh(sleeptime)
945 curses.halfdelay(int(sleeptime * 10))
946 sleeptime = 3
947 try:
948 char = self.screen.getkey()
949 if char == 'x':
950 self.drilldown = not self.drilldown
951 self.update_drilldown()
952 if char == 'q':
953 break
954 if char == 'f':
955 self.show_filter_selection()
956 if char == 'p':
957 self.show_vm_selection()
958 except KeyboardInterrupt:
959 break
960 except curses.error:
961 continue
962
963def batch(stats):
964 """Prints statistics in a key, value format."""
965 s = stats.get()
966 time.sleep(1)
967 s = stats.get()
968 for key in sorted(s.keys()):
969 values = s[key]
970 print '%-42s%10d%10d' % (key, values[0], values[1])
971
972def log(stats):
973 """Prints statistics as reiterating key block, multiple value blocks."""
974 keys = sorted(stats.get().iterkeys())
975 def banner():
976 for k in keys:
977 print '%s' % k,
978 print
979 def statline():
980 s = stats.get()
981 for k in keys:
982 print ' %9d' % s[k][1],
983 print
984 line = 0
985 banner_repeat = 20
986 while True:
987 time.sleep(1)
988 if line % banner_repeat == 0:
989 banner()
990 statline()
991 line += 1
992
993def get_options():
994 """Returns processed program arguments."""
995 description_text = """
996This script displays various statistics about VMs running under KVM.
997The statistics are gathered from the KVM debugfs entries and / or the
998currently available perf traces.
999
1000The monitoring takes additional cpu cycles and might affect the VM's
1001performance.
1002
1003Requirements:
1004- Access to:
1005 /sys/kernel/debug/kvm
1006 /sys/kernel/debug/trace/events/*
1007 /proc/pid/task
1008- /proc/sys/kernel/perf_event_paranoid < 1 if user has no
1009 CAP_SYS_ADMIN and perf events are used.
1010- CAP_SYS_RESOURCE if the hard limit is not high enough to allow
1011 the large number of files that are possibly opened.
1012"""
1013
1014 class PlainHelpFormatter(optparse.IndentedHelpFormatter):
1015 def format_description(self, description):
1016 if description:
1017 return description + "\n"
1018 else:
1019 return ""
1020
1021 optparser = optparse.OptionParser(description=description_text,
1022 formatter=PlainHelpFormatter())
1023 optparser.add_option('-1', '--once', '--batch',
1024 action='store_true',
1025 default=False,
1026 dest='once',
1027 help='run in batch mode for one second',
1028 )
1029 optparser.add_option('-l', '--log',
1030 action='store_true',
1031 default=False,
1032 dest='log',
1033 help='run in logging mode (like vmstat)',
1034 )
1035 optparser.add_option('-t', '--tracepoints',
1036 action='store_true',
1037 default=False,
1038 dest='tracepoints',
1039 help='retrieve statistics from tracepoints',
1040 )
1041 optparser.add_option('-d', '--debugfs',
1042 action='store_true',
1043 default=False,
1044 dest='debugfs',
1045 help='retrieve statistics from debugfs',
1046 )
1047 optparser.add_option('-f', '--fields',
1048 action='store',
1049 default=None,
1050 dest='fields',
1051 help='fields to display (regex)',
1052 )
1053 optparser.add_option('-p', '--pid',
1054 action='store',
1055 default=0,
1056 type=int,
1057 dest='pid',
1058 help='restrict statistics to pid',
1059 )
1060 (options, _) = optparser.parse_args(sys.argv)
1061 return options
1062
1063def get_providers(options):
1064 """Returns a list of data providers depending on the passed options."""
1065 providers = []
1066
1067 if options.tracepoints:
1068 providers.append(TracepointProvider())
1069 if options.debugfs:
1070 providers.append(DebugfsProvider())
1071 if len(providers) == 0:
1072 providers.append(TracepointProvider())
1073
1074 return providers
1075
1076def check_access(options):
1077 """Exits if the current user can't access all needed directories."""
1078 if not os.path.exists('/sys/kernel/debug'):
1079 sys.stderr.write('Please enable CONFIG_DEBUG_FS in your kernel.')
1080 sys.exit(1)
1081
1082 if not os.path.exists(PATH_DEBUGFS_KVM):
1083 sys.stderr.write("Please make sure, that debugfs is mounted and "
1084 "readable by the current user:\n"
1085 "('mount -t debugfs debugfs /sys/kernel/debug')\n"
1086 "Also ensure, that the kvm modules are loaded.\n")
1087 sys.exit(1)
1088
1089 if not os.path.exists(PATH_DEBUGFS_TRACING) and (options.tracepoints
1090 or not options.debugfs):
1091 sys.stderr.write("Please enable CONFIG_TRACING in your kernel "
1092 "when using the option -t (default).\n"
1093 "If it is enabled, make {0} readable by the "
1094 "current user.\n"
1095 .format(PATH_DEBUGFS_TRACING))
1096 if options.tracepoints:
1097 sys.exit(1)
1098
1099 sys.stderr.write("Falling back to debugfs statistics!\n")
1100 options.debugfs = True
1101 sleep(5)
1102
1103 return options
1104
1105def main():
1106 options = get_options()
1107 options = check_access(options)
1108
1109 if (options.pid > 0 and
1110 not os.path.isdir(os.path.join('/proc/',
1111 str(options.pid)))):
1112 sys.stderr.write('Did you use a (unsupported) tid instead of a pid?\n')
1113 sys.exit('Specified pid does not exist.')
1114
1115 providers = get_providers(options)
1116 stats = Stats(providers, options.pid, fields=options.fields)
1117
1118 if options.log:
1119 log(stats)
1120 elif not options.once:
1121 with Tui(stats) as tui:
1122 tui.show_stats()
1123 else:
1124 batch(stats)
1125
1126if __name__ == "__main__":
1127 main()
diff --git a/tools/kvm/kvm_stat/kvm_stat.txt b/tools/kvm/kvm_stat/kvm_stat.txt
new file mode 100644
index 000000000000..b92a153d7115
--- /dev/null
+++ b/tools/kvm/kvm_stat/kvm_stat.txt
@@ -0,0 +1,63 @@
1kvm_stat(1)
2===========
3
4NAME
5----
6kvm_stat - Report KVM kernel module event counters
7
8SYNOPSIS
9--------
10[verse]
11'kvm_stat' [OPTION]...
12
13DESCRIPTION
14-----------
15kvm_stat prints counts of KVM kernel module trace events. These events signify
16state transitions such as guest mode entry and exit.
17
18This tool is useful for observing guest behavior from the host perspective.
19Often conclusions about performance or buggy behavior can be drawn from the
20output.
21
22The set of KVM kernel module trace events may be specific to the kernel version
23or architecture. It is best to check the KVM kernel module source code for the
24meaning of events.
25
26OPTIONS
27-------
28-1::
29--once::
30--batch::
31 run in batch mode for one second
32
33-l::
34--log::
35 run in logging mode (like vmstat)
36
37-t::
38--tracepoints::
39 retrieve statistics from tracepoints
40
41-d::
42--debugfs::
43 retrieve statistics from debugfs
44
45-p<pid>::
46--pid=<pid>::
47 limit statistics to one virtual machine (pid)
48
49-f<fields>::
50--fields=<fields>::
51 fields to display (regex)
52
53-h::
54--help::
55 show help message
56
57SEE ALSO
58--------
59'perf'(1), 'trace-cmd'(1)
60
61AUTHOR
62------
63Stefan Hajnoczi <stefanha@redhat.com>
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index 6765c7e949f3..f094f3c4ed84 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -30,6 +30,10 @@ INCLUDES := -I$(srctree)/tools/include
30CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES) 30CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
31LDFLAGS += -lelf $(LIBSUBCMD) 31LDFLAGS += -lelf $(LIBSUBCMD)
32 32
33# Allow old libelf to be used:
34elfshdr := $(shell echo '\#include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | grep elf_getshdr)
35CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED)
36
33AWK = awk 37AWK = awk
34export srctree OUTPUT CFLAGS ARCH AWK 38export srctree OUTPUT CFLAGS ARCH AWK
35include $(srctree)/tools/build/Makefile.include 39include $(srctree)/tools/build/Makefile.include
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index e8a1e69eb92c..25d803148f5c 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -122,10 +122,14 @@ static bool ignore_func(struct objtool_file *file, struct symbol *func)
122 122
123 /* check for STACK_FRAME_NON_STANDARD */ 123 /* check for STACK_FRAME_NON_STANDARD */
124 if (file->whitelist && file->whitelist->rela) 124 if (file->whitelist && file->whitelist->rela)
125 list_for_each_entry(rela, &file->whitelist->rela->rela_list, list) 125 list_for_each_entry(rela, &file->whitelist->rela->rela_list, list) {
126 if (rela->sym->sec == func->sec && 126 if (rela->sym->type == STT_SECTION &&
127 rela->sym->sec == func->sec &&
127 rela->addend == func->offset) 128 rela->addend == func->offset)
128 return true; 129 return true;
130 if (rela->sym->type == STT_FUNC && rela->sym == func)
131 return true;
132 }
129 133
130 /* check if it has a context switching instruction */ 134 /* check if it has a context switching instruction */
131 func_for_each_insn(file, func, insn) 135 func_for_each_insn(file, func, insn)
diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
index 7f3e00a2f907..aa1ff6596684 100644
--- a/tools/objtool/elf.h
+++ b/tools/objtool/elf.h
@@ -23,6 +23,11 @@
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/hashtable.h> 24#include <linux/hashtable.h>
25 25
26#ifdef LIBELF_USE_DEPRECATED
27# define elf_getshdrnum elf_getshnum
28# define elf_getshdrstrndx elf_getshstrndx
29#endif
30
26struct section { 31struct section {
27 struct list_head list; 32 struct list_head list;
28 GElf_Shdr sh; 33 GElf_Shdr sh;
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index ebaf849e30ef..9cbddc290aff 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -103,12 +103,13 @@ OPTIONS
103 103
104 If --branch-stack option is used, following sort keys are also 104 If --branch-stack option is used, following sort keys are also
105 available: 105 available:
106 dso_from, dso_to, symbol_from, symbol_to, mispredict.
107 106
108 - dso_from: name of library or module branched from 107 - dso_from: name of library or module branched from
109 - dso_to: name of library or module branched to 108 - dso_to: name of library or module branched to
110 - symbol_from: name of function branched from 109 - symbol_from: name of function branched from
111 - symbol_to: name of function branched to 110 - symbol_to: name of function branched to
111 - srcline_from: source file and line branched from
112 - srcline_to: source file and line branched to
112 - mispredict: "N" for predicted branch, "Y" for mispredicted branch 113 - mispredict: "N" for predicted branch, "Y" for mispredicted branch
113 - in_tx: branch in TSX transaction 114 - in_tx: branch in TSX transaction
114 - abort: TSX transaction abort. 115 - abort: TSX transaction abort.
@@ -248,7 +249,7 @@ OPTIONS
248 Note that when using the --itrace option the synthesized callchain size 249 Note that when using the --itrace option the synthesized callchain size
249 will override this value if the synthesized callchain size is bigger. 250 will override this value if the synthesized callchain size is bigger.
250 251
251 Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise. 252 Default: 127
252 253
253-G:: 254-G::
254--inverted:: 255--inverted::
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index a856a1095893..4fc44c75263f 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -267,7 +267,7 @@ include::itrace.txt[]
267 Note that when using the --itrace option the synthesized callchain size 267 Note that when using the --itrace option the synthesized callchain size
268 will override this value if the synthesized callchain size is bigger. 268 will override this value if the synthesized callchain size is bigger.
269 269
270 Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise. 270 Default: 127
271 271
272--ns:: 272--ns::
273 Use 9 decimal places when displaying time (i.e. show the nanoseconds) 273 Use 9 decimal places when displaying time (i.e. show the nanoseconds)
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 6afe20121bc0..1ab0782369b1 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -143,7 +143,8 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
143 Implies '--call-graph dwarf' when --call-graph not present on the 143 Implies '--call-graph dwarf' when --call-graph not present on the
144 command line, on systems where DWARF unwinding was built in. 144 command line, on systems where DWARF unwinding was built in.
145 145
146 Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise. 146 Default: /proc/sys/kernel/perf_event_max_stack when present for
147 live sessions (without --input/-i), 127 otherwise.
147 148
148--min-stack:: 149--min-stack::
149 Set the stack depth limit when parsing the callchain, anything 150 Set the stack depth limit when parsing the callchain, anything
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 814158393656..25c81734a950 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -324,8 +324,9 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
324 OPT_BOOLEAN(0, "skip-missing", &annotate.skip_missing, 324 OPT_BOOLEAN(0, "skip-missing", &annotate.skip_missing,
325 "Skip symbols that cannot be annotated"), 325 "Skip symbols that cannot be annotated"),
326 OPT_STRING('C', "cpu", &annotate.cpu_list, "cpu", "list of cpus to profile"), 326 OPT_STRING('C', "cpu", &annotate.cpu_list, "cpu", "list of cpus to profile"),
327 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 327 OPT_CALLBACK(0, "symfs", NULL, "directory",
328 "Look for files with symbols relative to this directory"), 328 "Look for files with symbols relative to this directory",
329 symbol__config_symfs),
329 OPT_BOOLEAN(0, "source", &symbol_conf.annotate_src, 330 OPT_BOOLEAN(0, "source", &symbol_conf.annotate_src,
330 "Interleave source code with assembly code (default)"), 331 "Interleave source code with assembly code (default)"),
331 OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw, 332 OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw,
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index 632efc6b79a0..d75bded21fe0 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -119,8 +119,8 @@ static int build_id_cache__add_kcore(const char *filename, bool force)
119 if (build_id_cache__kcore_buildid(from_dir, sbuildid) < 0) 119 if (build_id_cache__kcore_buildid(from_dir, sbuildid) < 0)
120 return -1; 120 return -1;
121 121
122 scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s", 122 scnprintf(to_dir, sizeof(to_dir), "%s/%s/%s",
123 buildid_dir, sbuildid); 123 buildid_dir, DSO__NAME_KCORE, sbuildid);
124 124
125 if (!force && 125 if (!force &&
126 !build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) { 126 !build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) {
@@ -131,8 +131,8 @@ static int build_id_cache__add_kcore(const char *filename, bool force)
131 if (build_id_cache__kcore_dir(dir, sizeof(dir))) 131 if (build_id_cache__kcore_dir(dir, sizeof(dir)))
132 return -1; 132 return -1;
133 133
134 scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s/%s", 134 scnprintf(to_dir, sizeof(to_dir), "%s/%s/%s/%s",
135 buildid_dir, sbuildid, dir); 135 buildid_dir, DSO__NAME_KCORE, sbuildid, dir);
136 136
137 if (mkdir_p(to_dir, 0755)) 137 if (mkdir_p(to_dir, 0755))
138 return -1; 138 return -1;
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 9ce354f469dc..f7645a42708e 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -812,8 +812,9 @@ static const struct option options[] = {
812 OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator", 812 OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
813 "separator for columns, no spaces will be added between " 813 "separator for columns, no spaces will be added between "
814 "columns '.' is reserved."), 814 "columns '.' is reserved."),
815 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 815 OPT_CALLBACK(0, "symfs", NULL, "directory",
816 "Look for files with symbols relative to this directory"), 816 "Look for files with symbols relative to this directory",
817 symbol__config_symfs),
817 OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."), 818 OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."),
818 OPT_CALLBACK(0, "percentage", NULL, "relative|absolute", 819 OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
819 "How to display percentage of filtered entries", parse_filter_percentage), 820 "How to display percentage of filtered entries", parse_filter_percentage),
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f3679c44d3f3..dc3fcb597e4c 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -40,6 +40,7 @@
40#include <unistd.h> 40#include <unistd.h>
41#include <sched.h> 41#include <sched.h>
42#include <sys/mman.h> 42#include <sys/mman.h>
43#include <asm/bug.h>
43 44
44 45
45struct record { 46struct record {
@@ -82,27 +83,87 @@ static int process_synthesized_event(struct perf_tool *tool,
82 return record__write(rec, event, event->header.size); 83 return record__write(rec, event, event->header.size);
83} 84}
84 85
86static int
87backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 *end)
88{
89 struct perf_event_header *pheader;
90 u64 evt_head = head;
91 int size = mask + 1;
92
93 pr_debug2("backward_rb_find_range: buf=%p, head=%"PRIx64"\n", buf, head);
94 pheader = (struct perf_event_header *)(buf + (head & mask));
95 *start = head;
96 while (true) {
97 if (evt_head - head >= (unsigned int)size) {
98 pr_debug("Finshed reading backward ring buffer: rewind\n");
99 if (evt_head - head > (unsigned int)size)
100 evt_head -= pheader->size;
101 *end = evt_head;
102 return 0;
103 }
104
105 pheader = (struct perf_event_header *)(buf + (evt_head & mask));
106
107 if (pheader->size == 0) {
108 pr_debug("Finshed reading backward ring buffer: get start\n");
109 *end = evt_head;
110 return 0;
111 }
112
113 evt_head += pheader->size;
114 pr_debug3("move evt_head: %"PRIx64"\n", evt_head);
115 }
116 WARN_ONCE(1, "Shouldn't get here\n");
117 return -1;
118}
119
120static int
121rb_find_range(struct perf_evlist *evlist,
122 void *data, int mask, u64 head, u64 old,
123 u64 *start, u64 *end)
124{
125 if (!evlist->backward) {
126 *start = old;
127 *end = head;
128 return 0;
129 }
130
131 return backward_rb_find_range(data, mask, head, start, end);
132}
133
85static int record__mmap_read(struct record *rec, int idx) 134static int record__mmap_read(struct record *rec, int idx)
86{ 135{
87 struct perf_mmap *md = &rec->evlist->mmap[idx]; 136 struct perf_mmap *md = &rec->evlist->mmap[idx];
88 u64 head = perf_mmap__read_head(md); 137 u64 head = perf_mmap__read_head(md);
89 u64 old = md->prev; 138 u64 old = md->prev;
139 u64 end = head, start = old;
90 unsigned char *data = md->base + page_size; 140 unsigned char *data = md->base + page_size;
91 unsigned long size; 141 unsigned long size;
92 void *buf; 142 void *buf;
93 int rc = 0; 143 int rc = 0;
94 144
95 if (old == head) 145 if (rb_find_range(rec->evlist, data, md->mask, head,
146 old, &start, &end))
147 return -1;
148
149 if (start == end)
96 return 0; 150 return 0;
97 151
98 rec->samples++; 152 rec->samples++;
99 153
100 size = head - old; 154 size = end - start;
155 if (size > (unsigned long)(md->mask) + 1) {
156 WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
157
158 md->prev = head;
159 perf_evlist__mmap_consume(rec->evlist, idx);
160 return 0;
161 }
101 162
102 if ((old & md->mask) + size != (head & md->mask)) { 163 if ((start & md->mask) + size != (end & md->mask)) {
103 buf = &data[old & md->mask]; 164 buf = &data[start & md->mask];
104 size = md->mask + 1 - (old & md->mask); 165 size = md->mask + 1 - (start & md->mask);
105 old += size; 166 start += size;
106 167
107 if (record__write(rec, buf, size) < 0) { 168 if (record__write(rec, buf, size) < 0) {
108 rc = -1; 169 rc = -1;
@@ -110,16 +171,16 @@ static int record__mmap_read(struct record *rec, int idx)
110 } 171 }
111 } 172 }
112 173
113 buf = &data[old & md->mask]; 174 buf = &data[start & md->mask];
114 size = head - old; 175 size = end - start;
115 old += size; 176 start += size;
116 177
117 if (record__write(rec, buf, size) < 0) { 178 if (record__write(rec, buf, size) < 0) {
118 rc = -1; 179 rc = -1;
119 goto out; 180 goto out;
120 } 181 }
121 182
122 md->prev = old; 183 md->prev = head;
123 perf_evlist__mmap_consume(rec->evlist, idx); 184 perf_evlist__mmap_consume(rec->evlist, idx);
124out: 185out:
125 return rc; 186 return rc;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 87d40e3c4078..a87cb338bdf1 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -691,7 +691,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
691 .ordered_events = true, 691 .ordered_events = true,
692 .ordering_requires_timestamps = true, 692 .ordering_requires_timestamps = true,
693 }, 693 },
694 .max_stack = sysctl_perf_event_max_stack, 694 .max_stack = PERF_MAX_STACK_DEPTH,
695 .pretty_printing_style = "normal", 695 .pretty_printing_style = "normal",
696 .socket_filter = -1, 696 .socket_filter = -1,
697 }; 697 };
@@ -770,8 +770,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
770 "columns '.' is reserved."), 770 "columns '.' is reserved."),
771 OPT_BOOLEAN('U', "hide-unresolved", &symbol_conf.hide_unresolved, 771 OPT_BOOLEAN('U', "hide-unresolved", &symbol_conf.hide_unresolved,
772 "Only display entries resolved to a symbol"), 772 "Only display entries resolved to a symbol"),
773 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 773 OPT_CALLBACK(0, "symfs", NULL, "directory",
774 "Look for files with symbols relative to this directory"), 774 "Look for files with symbols relative to this directory",
775 symbol__config_symfs),
775 OPT_STRING('C', "cpu", &report.cpu_list, "cpu", 776 OPT_STRING('C', "cpu", &report.cpu_list, "cpu",
776 "list of cpus to profile"), 777 "list of cpus to profile"),
777 OPT_BOOLEAN('I', "show-info", &report.show_full_info, 778 OPT_BOOLEAN('I', "show-info", &report.show_full_info,
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index efca81679bb3..e3ce2f34d3ad 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -2010,8 +2010,9 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
2010 "file", "kallsyms pathname"), 2010 "file", "kallsyms pathname"),
2011 OPT_BOOLEAN('G', "hide-call-graph", &no_callchain, 2011 OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
2012 "When printing symbols do not display call chain"), 2012 "When printing symbols do not display call chain"),
2013 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 2013 OPT_CALLBACK(0, "symfs", NULL, "directory",
2014 "Look for files with symbols relative to this directory"), 2014 "Look for files with symbols relative to this directory",
2015 symbol__config_symfs),
2015 OPT_CALLBACK('F', "fields", NULL, "str", 2016 OPT_CALLBACK('F', "fields", NULL, "str",
2016 "comma separated output fields prepend with 'type:'. " 2017 "comma separated output fields prepend with 'type:'. "
2017 "Valid types: hw,sw,trace,raw. " 2018 "Valid types: hw,sw,trace,raw. "
@@ -2067,8 +2068,6 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
2067 NULL 2068 NULL
2068 }; 2069 };
2069 2070
2070 scripting_max_stack = sysctl_perf_event_max_stack;
2071
2072 setup_scripting(); 2071 setup_scripting();
2073 2072
2074 argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage, 2073 argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e459b685a4e9..ee7ada78d86f 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -66,6 +66,7 @@
66#include <stdlib.h> 66#include <stdlib.h>
67#include <sys/prctl.h> 67#include <sys/prctl.h>
68#include <locale.h> 68#include <locale.h>
69#include <math.h>
69 70
70#define DEFAULT_SEPARATOR " " 71#define DEFAULT_SEPARATOR " "
71#define CNTR_NOT_SUPPORTED "<not supported>" 72#define CNTR_NOT_SUPPORTED "<not supported>"
@@ -991,12 +992,12 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
991 const char *fmt; 992 const char *fmt;
992 993
993 if (csv_output) { 994 if (csv_output) {
994 fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s"; 995 fmt = floor(sc) != sc ? "%.2f%s" : "%.0f%s";
995 } else { 996 } else {
996 if (big_num) 997 if (big_num)
997 fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s"; 998 fmt = floor(sc) != sc ? "%'18.2f%s" : "%'18.0f%s";
998 else 999 else
999 fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s"; 1000 fmt = floor(sc) != sc ? "%18.2f%s" : "%18.0f%s";
1000 } 1001 }
1001 1002
1002 aggr_printout(evsel, id, nr); 1003 aggr_printout(evsel, id, nr);
@@ -1909,6 +1910,9 @@ static int add_default_attributes(void)
1909 } 1910 }
1910 1911
1911 if (!evsel_list->nr_entries) { 1912 if (!evsel_list->nr_entries) {
1913 if (target__has_cpu(&target))
1914 default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
1915
1912 if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0) 1916 if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0)
1913 return -1; 1917 return -1;
1914 if (pmu_have_event("cpu", "stalled-cycles-frontend")) { 1918 if (pmu_have_event("cpu", "stalled-cycles-frontend")) {
@@ -2000,7 +2004,7 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
2000 union perf_event *event, 2004 union perf_event *event,
2001 struct perf_session *session) 2005 struct perf_session *session)
2002{ 2006{
2003 struct stat_round_event *round = &event->stat_round; 2007 struct stat_round_event *stat_round = &event->stat_round;
2004 struct perf_evsel *counter; 2008 struct perf_evsel *counter;
2005 struct timespec tsh, *ts = NULL; 2009 struct timespec tsh, *ts = NULL;
2006 const char **argv = session->header.env.cmdline_argv; 2010 const char **argv = session->header.env.cmdline_argv;
@@ -2009,12 +2013,12 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
2009 evlist__for_each(evsel_list, counter) 2013 evlist__for_each(evsel_list, counter)
2010 perf_stat_process_counter(&stat_config, counter); 2014 perf_stat_process_counter(&stat_config, counter);
2011 2015
2012 if (round->type == PERF_STAT_ROUND_TYPE__FINAL) 2016 if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL)
2013 update_stats(&walltime_nsecs_stats, round->time); 2017 update_stats(&walltime_nsecs_stats, stat_round->time);
2014 2018
2015 if (stat_config.interval && round->time) { 2019 if (stat_config.interval && stat_round->time) {
2016 tsh.tv_sec = round->time / NSECS_PER_SEC; 2020 tsh.tv_sec = stat_round->time / NSECS_PER_SEC;
2017 tsh.tv_nsec = round->time % NSECS_PER_SEC; 2021 tsh.tv_nsec = stat_round->time % NSECS_PER_SEC;
2018 ts = &tsh; 2022 ts = &tsh;
2019 } 2023 }
2020 2024
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 40cc9bb3506c..733a55422d03 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1945,8 +1945,9 @@ int cmd_timechart(int argc, const char **argv,
1945 OPT_CALLBACK('p', "process", NULL, "process", 1945 OPT_CALLBACK('p', "process", NULL, "process",
1946 "process selector. Pass a pid or process name.", 1946 "process selector. Pass a pid or process name.",
1947 parse_process), 1947 parse_process),
1948 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 1948 OPT_CALLBACK(0, "symfs", NULL, "directory",
1949 "Look for files with symbols relative to this directory"), 1949 "Look for files with symbols relative to this directory",
1950 symbol__config_symfs),
1950 OPT_INTEGER('n', "proc-num", &tchart.proc_num, 1951 OPT_INTEGER('n', "proc-num", &tchart.proc_num,
1951 "min. number of tasks to print"), 1952 "min. number of tasks to print"),
1952 OPT_BOOLEAN('t', "topology", &tchart.topology, 1953 OPT_BOOLEAN('t', "topology", &tchart.topology,
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 1793da585676..2a6cc254ad0c 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -732,7 +732,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
732 if (machine__resolve(machine, &al, sample) < 0) 732 if (machine__resolve(machine, &al, sample) < 0)
733 return; 733 return;
734 734
735 if (!top->kptr_restrict_warned && 735 if (!machine->kptr_restrict_warned &&
736 symbol_conf.kptr_restrict && 736 symbol_conf.kptr_restrict &&
737 al.cpumode == PERF_RECORD_MISC_KERNEL) { 737 al.cpumode == PERF_RECORD_MISC_KERNEL) {
738 ui__warning( 738 ui__warning(
@@ -743,7 +743,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
743 " modules" : ""); 743 " modules" : "");
744 if (use_browser <= 0) 744 if (use_browser <= 0)
745 sleep(5); 745 sleep(5);
746 top->kptr_restrict_warned = true; 746 machine->kptr_restrict_warned = true;
747 } 747 }
748 748
749 if (al.sym == NULL) { 749 if (al.sym == NULL) {
@@ -759,7 +759,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
759 * --hide-kernel-symbols, even if the user specifies an 759 * --hide-kernel-symbols, even if the user specifies an
760 * invalid --vmlinux ;-) 760 * invalid --vmlinux ;-)
761 */ 761 */
762 if (!top->kptr_restrict_warned && !top->vmlinux_warned && 762 if (!machine->kptr_restrict_warned && !top->vmlinux_warned &&
763 al.map == machine->vmlinux_maps[MAP__FUNCTION] && 763 al.map == machine->vmlinux_maps[MAP__FUNCTION] &&
764 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { 764 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
765 if (symbol_conf.vmlinux_name) { 765 if (symbol_conf.vmlinux_name) {
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 6e5c325148e4..5c50fe70d6b3 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -576,84 +576,54 @@ static struct syscall_fmt {
576 bool hexret; 576 bool hexret;
577} syscall_fmts[] = { 577} syscall_fmts[] = {
578 { .name = "access", .errmsg = true, 578 { .name = "access", .errmsg = true,
579 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ 579 .arg_scnprintf = { [1] = SCA_ACCMODE, /* mode */ }, },
580 [1] = SCA_ACCMODE, /* mode */ }, },
581 { .name = "arch_prctl", .errmsg = true, .alias = "prctl", }, 580 { .name = "arch_prctl", .errmsg = true, .alias = "prctl", },
582 { .name = "bpf", .errmsg = true, STRARRAY(0, cmd, bpf_cmd), }, 581 { .name = "bpf", .errmsg = true, STRARRAY(0, cmd, bpf_cmd), },
583 { .name = "brk", .hexret = true, 582 { .name = "brk", .hexret = true,
584 .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, 583 .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, },
585 { .name = "chdir", .errmsg = true, 584 { .name = "chdir", .errmsg = true, },
586 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, }, 585 { .name = "chmod", .errmsg = true, },
587 { .name = "chmod", .errmsg = true, 586 { .name = "chroot", .errmsg = true, },
588 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
589 { .name = "chroot", .errmsg = true,
590 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
591 { .name = "clock_gettime", .errmsg = true, STRARRAY(0, clk_id, clockid), }, 587 { .name = "clock_gettime", .errmsg = true, STRARRAY(0, clk_id, clockid), },
592 { .name = "clone", .errpid = true, }, 588 { .name = "clone", .errpid = true, },
593 { .name = "close", .errmsg = true, 589 { .name = "close", .errmsg = true,
594 .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, }, 590 .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, },
595 { .name = "connect", .errmsg = true, }, 591 { .name = "connect", .errmsg = true, },
596 { .name = "creat", .errmsg = true, 592 { .name = "creat", .errmsg = true, },
597 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, }, 593 { .name = "dup", .errmsg = true, },
598 { .name = "dup", .errmsg = true, 594 { .name = "dup2", .errmsg = true, },
599 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 595 { .name = "dup3", .errmsg = true, },
600 { .name = "dup2", .errmsg = true,
601 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
602 { .name = "dup3", .errmsg = true,
603 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
604 { .name = "epoll_ctl", .errmsg = true, STRARRAY(1, op, epoll_ctl_ops), }, 596 { .name = "epoll_ctl", .errmsg = true, STRARRAY(1, op, epoll_ctl_ops), },
605 { .name = "eventfd2", .errmsg = true, 597 { .name = "eventfd2", .errmsg = true,
606 .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, }, 598 .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, },
607 { .name = "faccessat", .errmsg = true, 599 { .name = "faccessat", .errmsg = true, },
608 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ 600 { .name = "fadvise64", .errmsg = true, },
609 [1] = SCA_FILENAME, /* filename */ }, }, 601 { .name = "fallocate", .errmsg = true, },
610 { .name = "fadvise64", .errmsg = true, 602 { .name = "fchdir", .errmsg = true, },
611 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 603 { .name = "fchmod", .errmsg = true, },
612 { .name = "fallocate", .errmsg = true,
613 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
614 { .name = "fchdir", .errmsg = true,
615 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
616 { .name = "fchmod", .errmsg = true,
617 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
618 { .name = "fchmodat", .errmsg = true, 604 { .name = "fchmodat", .errmsg = true,
619 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ 605 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, },
620 [1] = SCA_FILENAME, /* filename */ }, }, 606 { .name = "fchown", .errmsg = true, },
621 { .name = "fchown", .errmsg = true,
622 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
623 { .name = "fchownat", .errmsg = true, 607 { .name = "fchownat", .errmsg = true,
624 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ 608 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, },
625 [1] = SCA_FILENAME, /* filename */ }, },
626 { .name = "fcntl", .errmsg = true, 609 { .name = "fcntl", .errmsg = true,
627 .arg_scnprintf = { [0] = SCA_FD, /* fd */ 610 .arg_scnprintf = { [1] = SCA_STRARRAY, /* cmd */ },
628 [1] = SCA_STRARRAY, /* cmd */ },
629 .arg_parm = { [1] = &strarray__fcntl_cmds, /* cmd */ }, }, 611 .arg_parm = { [1] = &strarray__fcntl_cmds, /* cmd */ }, },
630 { .name = "fdatasync", .errmsg = true, 612 { .name = "fdatasync", .errmsg = true, },
631 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
632 { .name = "flock", .errmsg = true, 613 { .name = "flock", .errmsg = true,
633 .arg_scnprintf = { [0] = SCA_FD, /* fd */ 614 .arg_scnprintf = { [1] = SCA_FLOCK, /* cmd */ }, },
634 [1] = SCA_FLOCK, /* cmd */ }, }, 615 { .name = "fsetxattr", .errmsg = true, },
635 { .name = "fsetxattr", .errmsg = true, 616 { .name = "fstat", .errmsg = true, .alias = "newfstat", },
636 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 617 { .name = "fstatat", .errmsg = true, .alias = "newfstatat", },
637 { .name = "fstat", .errmsg = true, .alias = "newfstat", 618 { .name = "fstatfs", .errmsg = true, },
638 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 619 { .name = "fsync", .errmsg = true, },
639 { .name = "fstatat", .errmsg = true, .alias = "newfstatat", 620 { .name = "ftruncate", .errmsg = true, },
640 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
641 [1] = SCA_FILENAME, /* filename */ }, },
642 { .name = "fstatfs", .errmsg = true,
643 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
644 { .name = "fsync", .errmsg = true,
645 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
646 { .name = "ftruncate", .errmsg = true,
647 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
648 { .name = "futex", .errmsg = true, 621 { .name = "futex", .errmsg = true,
649 .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, }, 622 .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, },
650 { .name = "futimesat", .errmsg = true, 623 { .name = "futimesat", .errmsg = true,
651 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ 624 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, },
652 [1] = SCA_FILENAME, /* filename */ }, }, 625 { .name = "getdents", .errmsg = true, },
653 { .name = "getdents", .errmsg = true, 626 { .name = "getdents64", .errmsg = true, },
654 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
655 { .name = "getdents64", .errmsg = true,
656 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
657 { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), }, 627 { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), },
658 { .name = "getpid", .errpid = true, }, 628 { .name = "getpid", .errpid = true, },
659 { .name = "getpgid", .errpid = true, }, 629 { .name = "getpgid", .errpid = true, },
@@ -661,12 +631,10 @@ static struct syscall_fmt {
661 { .name = "getrandom", .errmsg = true, 631 { .name = "getrandom", .errmsg = true,
662 .arg_scnprintf = { [2] = SCA_GETRANDOM_FLAGS, /* flags */ }, }, 632 .arg_scnprintf = { [2] = SCA_GETRANDOM_FLAGS, /* flags */ }, },
663 { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, 633 { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
664 { .name = "getxattr", .errmsg = true, 634 { .name = "getxattr", .errmsg = true, },
665 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, }, 635 { .name = "inotify_add_watch", .errmsg = true, },
666 { .name = "inotify_add_watch", .errmsg = true,
667 .arg_scnprintf = { [1] = SCA_FILENAME, /* pathname */ }, },
668 { .name = "ioctl", .errmsg = true, 636 { .name = "ioctl", .errmsg = true,
669 .arg_scnprintf = { [0] = SCA_FD, /* fd */ 637 .arg_scnprintf = {
670#if defined(__i386__) || defined(__x86_64__) 638#if defined(__i386__) || defined(__x86_64__)
671/* 639/*
672 * FIXME: Make this available to all arches. 640 * FIXME: Make this available to all arches.
@@ -680,41 +648,28 @@ static struct syscall_fmt {
680 { .name = "keyctl", .errmsg = true, STRARRAY(0, option, keyctl_options), }, 648 { .name = "keyctl", .errmsg = true, STRARRAY(0, option, keyctl_options), },
681 { .name = "kill", .errmsg = true, 649 { .name = "kill", .errmsg = true,
682 .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, 650 .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
683 { .name = "lchown", .errmsg = true, 651 { .name = "lchown", .errmsg = true, },
684 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, }, 652 { .name = "lgetxattr", .errmsg = true, },
685 { .name = "lgetxattr", .errmsg = true,
686 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
687 { .name = "linkat", .errmsg = true, 653 { .name = "linkat", .errmsg = true,
688 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 654 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, },
689 { .name = "listxattr", .errmsg = true, 655 { .name = "listxattr", .errmsg = true, },
690 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, }, 656 { .name = "llistxattr", .errmsg = true, },
691 { .name = "llistxattr", .errmsg = true, 657 { .name = "lremovexattr", .errmsg = true, },
692 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
693 { .name = "lremovexattr", .errmsg = true,
694 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
695 { .name = "lseek", .errmsg = true, 658 { .name = "lseek", .errmsg = true,
696 .arg_scnprintf = { [0] = SCA_FD, /* fd */ 659 .arg_scnprintf = { [2] = SCA_STRARRAY, /* whence */ },
697 [2] = SCA_STRARRAY, /* whence */ },
698 .arg_parm = { [2] = &strarray__whences, /* whence */ }, }, 660 .arg_parm = { [2] = &strarray__whences, /* whence */ }, },
699 { .name = "lsetxattr", .errmsg = true, 661 { .name = "lsetxattr", .errmsg = true, },
700 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, }, 662 { .name = "lstat", .errmsg = true, .alias = "newlstat", },
701 { .name = "lstat", .errmsg = true, .alias = "newlstat", 663 { .name = "lsxattr", .errmsg = true, },
702 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
703 { .name = "lsxattr", .errmsg = true,
704 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
705 { .name = "madvise", .errmsg = true, 664 { .name = "madvise", .errmsg = true,
706 .arg_scnprintf = { [0] = SCA_HEX, /* start */ 665 .arg_scnprintf = { [0] = SCA_HEX, /* start */
707 [2] = SCA_MADV_BHV, /* behavior */ }, }, 666 [2] = SCA_MADV_BHV, /* behavior */ }, },
708 { .name = "mkdir", .errmsg = true, 667 { .name = "mkdir", .errmsg = true, },
709 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
710 { .name = "mkdirat", .errmsg = true, 668 { .name = "mkdirat", .errmsg = true,
711 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ 669 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, },
712 [1] = SCA_FILENAME, /* pathname */ }, }, 670 { .name = "mknod", .errmsg = true, },
713 { .name = "mknod", .errmsg = true,
714 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
715 { .name = "mknodat", .errmsg = true, 671 { .name = "mknodat", .errmsg = true,
716 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ 672 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, },
717 [1] = SCA_FILENAME, /* filename */ }, },
718 { .name = "mlock", .errmsg = true, 673 { .name = "mlock", .errmsg = true,
719 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, 674 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
720 { .name = "mlockall", .errmsg = true, 675 { .name = "mlockall", .errmsg = true,
@@ -722,8 +677,7 @@ static struct syscall_fmt {
722 { .name = "mmap", .hexret = true, 677 { .name = "mmap", .hexret = true,
723 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ 678 .arg_scnprintf = { [0] = SCA_HEX, /* addr */
724 [2] = SCA_MMAP_PROT, /* prot */ 679 [2] = SCA_MMAP_PROT, /* prot */
725 [3] = SCA_MMAP_FLAGS, /* flags */ 680 [3] = SCA_MMAP_FLAGS, /* flags */ }, },
726 [4] = SCA_FD, /* fd */ }, },
727 { .name = "mprotect", .errmsg = true, 681 { .name = "mprotect", .errmsg = true,
728 .arg_scnprintf = { [0] = SCA_HEX, /* start */ 682 .arg_scnprintf = { [0] = SCA_HEX, /* start */
729 [2] = SCA_MMAP_PROT, /* prot */ }, }, 683 [2] = SCA_MMAP_PROT, /* prot */ }, },
@@ -740,17 +694,14 @@ static struct syscall_fmt {
740 { .name = "name_to_handle_at", .errmsg = true, 694 { .name = "name_to_handle_at", .errmsg = true,
741 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 695 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
742 { .name = "newfstatat", .errmsg = true, 696 { .name = "newfstatat", .errmsg = true,
743 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ 697 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
744 [1] = SCA_FILENAME, /* filename */ }, },
745 { .name = "open", .errmsg = true, 698 { .name = "open", .errmsg = true,
746 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ 699 .arg_scnprintf = { [1] = SCA_OPEN_FLAGS, /* flags */ }, },
747 [1] = SCA_OPEN_FLAGS, /* flags */ }, },
748 { .name = "open_by_handle_at", .errmsg = true, 700 { .name = "open_by_handle_at", .errmsg = true,
749 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ 701 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
750 [2] = SCA_OPEN_FLAGS, /* flags */ }, }, 702 [2] = SCA_OPEN_FLAGS, /* flags */ }, },
751 { .name = "openat", .errmsg = true, 703 { .name = "openat", .errmsg = true,
752 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ 704 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
753 [1] = SCA_FILENAME, /* filename */
754 [2] = SCA_OPEN_FLAGS, /* flags */ }, }, 705 [2] = SCA_OPEN_FLAGS, /* flags */ }, },
755 { .name = "perf_event_open", .errmsg = true, 706 { .name = "perf_event_open", .errmsg = true,
756 .arg_scnprintf = { [2] = SCA_INT, /* cpu */ 707 .arg_scnprintf = { [2] = SCA_INT, /* cpu */
@@ -760,39 +711,26 @@ static struct syscall_fmt {
760 .arg_scnprintf = { [1] = SCA_PIPE_FLAGS, /* flags */ }, }, 711 .arg_scnprintf = { [1] = SCA_PIPE_FLAGS, /* flags */ }, },
761 { .name = "poll", .errmsg = true, .timeout = true, }, 712 { .name = "poll", .errmsg = true, .timeout = true, },
762 { .name = "ppoll", .errmsg = true, .timeout = true, }, 713 { .name = "ppoll", .errmsg = true, .timeout = true, },
763 { .name = "pread", .errmsg = true, .alias = "pread64", 714 { .name = "pread", .errmsg = true, .alias = "pread64", },
764 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 715 { .name = "preadv", .errmsg = true, .alias = "pread", },
765 { .name = "preadv", .errmsg = true, .alias = "pread",
766 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
767 { .name = "prlimit64", .errmsg = true, STRARRAY(1, resource, rlimit_resources), }, 716 { .name = "prlimit64", .errmsg = true, STRARRAY(1, resource, rlimit_resources), },
768 { .name = "pwrite", .errmsg = true, .alias = "pwrite64", 717 { .name = "pwrite", .errmsg = true, .alias = "pwrite64", },
769 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 718 { .name = "pwritev", .errmsg = true, },
770 { .name = "pwritev", .errmsg = true, 719 { .name = "read", .errmsg = true, },
771 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 720 { .name = "readlink", .errmsg = true, },
772 { .name = "read", .errmsg = true,
773 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
774 { .name = "readlink", .errmsg = true,
775 .arg_scnprintf = { [0] = SCA_FILENAME, /* path */ }, },
776 { .name = "readlinkat", .errmsg = true, 721 { .name = "readlinkat", .errmsg = true,
777 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ 722 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
778 [1] = SCA_FILENAME, /* pathname */ }, }, 723 { .name = "readv", .errmsg = true, },
779 { .name = "readv", .errmsg = true,
780 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
781 { .name = "recvfrom", .errmsg = true, 724 { .name = "recvfrom", .errmsg = true,
782 .arg_scnprintf = { [0] = SCA_FD, /* fd */ 725 .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
783 [3] = SCA_MSG_FLAGS, /* flags */ }, },
784 { .name = "recvmmsg", .errmsg = true, 726 { .name = "recvmmsg", .errmsg = true,
785 .arg_scnprintf = { [0] = SCA_FD, /* fd */ 727 .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
786 [3] = SCA_MSG_FLAGS, /* flags */ }, },
787 { .name = "recvmsg", .errmsg = true, 728 { .name = "recvmsg", .errmsg = true,
788 .arg_scnprintf = { [0] = SCA_FD, /* fd */ 729 .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, },
789 [2] = SCA_MSG_FLAGS, /* flags */ }, }, 730 { .name = "removexattr", .errmsg = true, },
790 { .name = "removexattr", .errmsg = true,
791 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
792 { .name = "renameat", .errmsg = true, 731 { .name = "renameat", .errmsg = true,
793 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 732 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
794 { .name = "rmdir", .errmsg = true, 733 { .name = "rmdir", .errmsg = true, },
795 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
796 { .name = "rt_sigaction", .errmsg = true, 734 { .name = "rt_sigaction", .errmsg = true,
797 .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, }, 735 .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, },
798 { .name = "rt_sigprocmask", .errmsg = true, STRARRAY(0, how, sighow), }, 736 { .name = "rt_sigprocmask", .errmsg = true, STRARRAY(0, how, sighow), },
@@ -807,22 +745,17 @@ static struct syscall_fmt {
807 [1] = SCA_SECCOMP_FLAGS, /* flags */ }, }, 745 [1] = SCA_SECCOMP_FLAGS, /* flags */ }, },
808 { .name = "select", .errmsg = true, .timeout = true, }, 746 { .name = "select", .errmsg = true, .timeout = true, },
809 { .name = "sendmmsg", .errmsg = true, 747 { .name = "sendmmsg", .errmsg = true,
810 .arg_scnprintf = { [0] = SCA_FD, /* fd */ 748 .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
811 [3] = SCA_MSG_FLAGS, /* flags */ }, },
812 { .name = "sendmsg", .errmsg = true, 749 { .name = "sendmsg", .errmsg = true,
813 .arg_scnprintf = { [0] = SCA_FD, /* fd */ 750 .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, },
814 [2] = SCA_MSG_FLAGS, /* flags */ }, },
815 { .name = "sendto", .errmsg = true, 751 { .name = "sendto", .errmsg = true,
816 .arg_scnprintf = { [0] = SCA_FD, /* fd */ 752 .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
817 [3] = SCA_MSG_FLAGS, /* flags */ }, },
818 { .name = "set_tid_address", .errpid = true, }, 753 { .name = "set_tid_address", .errpid = true, },
819 { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), }, 754 { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), },
820 { .name = "setpgid", .errmsg = true, }, 755 { .name = "setpgid", .errmsg = true, },
821 { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, 756 { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
822 { .name = "setxattr", .errmsg = true, 757 { .name = "setxattr", .errmsg = true, },
823 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, }, 758 { .name = "shutdown", .errmsg = true, },
824 { .name = "shutdown", .errmsg = true,
825 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
826 { .name = "socket", .errmsg = true, 759 { .name = "socket", .errmsg = true,
827 .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ 760 .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */
828 [1] = SCA_SK_TYPE, /* type */ }, 761 [1] = SCA_SK_TYPE, /* type */ },
@@ -831,10 +764,8 @@ static struct syscall_fmt {
831 .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ 764 .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */
832 [1] = SCA_SK_TYPE, /* type */ }, 765 [1] = SCA_SK_TYPE, /* type */ },
833 .arg_parm = { [0] = &strarray__socket_families, /* family */ }, }, 766 .arg_parm = { [0] = &strarray__socket_families, /* family */ }, },
834 { .name = "stat", .errmsg = true, .alias = "newstat", 767 { .name = "stat", .errmsg = true, .alias = "newstat", },
835 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, }, 768 { .name = "statfs", .errmsg = true, },
836 { .name = "statfs", .errmsg = true,
837 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
838 { .name = "swapoff", .errmsg = true, 769 { .name = "swapoff", .errmsg = true,
839 .arg_scnprintf = { [0] = SCA_FILENAME, /* specialfile */ }, }, 770 .arg_scnprintf = { [0] = SCA_FILENAME, /* specialfile */ }, },
840 { .name = "swapon", .errmsg = true, 771 { .name = "swapon", .errmsg = true,
@@ -845,29 +776,21 @@ static struct syscall_fmt {
845 .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, 776 .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, },
846 { .name = "tkill", .errmsg = true, 777 { .name = "tkill", .errmsg = true,
847 .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, 778 .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
848 { .name = "truncate", .errmsg = true, 779 { .name = "truncate", .errmsg = true, },
849 .arg_scnprintf = { [0] = SCA_FILENAME, /* path */ }, },
850 { .name = "uname", .errmsg = true, .alias = "newuname", }, 780 { .name = "uname", .errmsg = true, .alias = "newuname", },
851 { .name = "unlinkat", .errmsg = true, 781 { .name = "unlinkat", .errmsg = true,
852 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ 782 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
853 [1] = SCA_FILENAME, /* pathname */ }, }, 783 { .name = "utime", .errmsg = true, },
854 { .name = "utime", .errmsg = true,
855 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
856 { .name = "utimensat", .errmsg = true, 784 { .name = "utimensat", .errmsg = true,
857 .arg_scnprintf = { [0] = SCA_FDAT, /* dirfd */ 785 .arg_scnprintf = { [0] = SCA_FDAT, /* dirfd */ }, },
858 [1] = SCA_FILENAME, /* filename */ }, }, 786 { .name = "utimes", .errmsg = true, },
859 { .name = "utimes", .errmsg = true, 787 { .name = "vmsplice", .errmsg = true, },
860 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
861 { .name = "vmsplice", .errmsg = true,
862 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
863 { .name = "wait4", .errpid = true, 788 { .name = "wait4", .errpid = true,
864 .arg_scnprintf = { [2] = SCA_WAITID_OPTIONS, /* options */ }, }, 789 .arg_scnprintf = { [2] = SCA_WAITID_OPTIONS, /* options */ }, },
865 { .name = "waitid", .errpid = true, 790 { .name = "waitid", .errpid = true,
866 .arg_scnprintf = { [3] = SCA_WAITID_OPTIONS, /* options */ }, }, 791 .arg_scnprintf = { [3] = SCA_WAITID_OPTIONS, /* options */ }, },
867 { .name = "write", .errmsg = true, 792 { .name = "write", .errmsg = true, },
868 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 793 { .name = "writev", .errmsg = true, },
869 { .name = "writev", .errmsg = true,
870 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
871}; 794};
872 795
873static int syscall_fmt__cmp(const void *name, const void *fmtp) 796static int syscall_fmt__cmp(const void *name, const void *fmtp)
@@ -1160,6 +1083,24 @@ static int trace__tool_process(struct perf_tool *tool,
1160 return trace__process_event(trace, machine, event, sample); 1083 return trace__process_event(trace, machine, event, sample);
1161} 1084}
1162 1085
1086static char *trace__machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, char **modp)
1087{
1088 struct machine *machine = vmachine;
1089
1090 if (machine->kptr_restrict_warned)
1091 return NULL;
1092
1093 if (symbol_conf.kptr_restrict) {
1094 pr_warning("Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n"
1095 "Check /proc/sys/kernel/kptr_restrict.\n\n"
1096 "Kernel samples will not be resolved.\n");
1097 machine->kptr_restrict_warned = true;
1098 return NULL;
1099 }
1100
1101 return machine__resolve_kernel_addr(vmachine, addrp, modp);
1102}
1103
1163static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist) 1104static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
1164{ 1105{
1165 int err = symbol__init(NULL); 1106 int err = symbol__init(NULL);
@@ -1171,7 +1112,7 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
1171 if (trace->host == NULL) 1112 if (trace->host == NULL)
1172 return -ENOMEM; 1113 return -ENOMEM;
1173 1114
1174 if (trace_event__register_resolver(trace->host, machine__resolve_kernel_addr) < 0) 1115 if (trace_event__register_resolver(trace->host, trace__machine__resolve_kernel_addr) < 0)
1175 return -errno; 1116 return -errno;
1176 1117
1177 err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target, 1118 err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target,
@@ -1186,7 +1127,7 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
1186static int syscall__set_arg_fmts(struct syscall *sc) 1127static int syscall__set_arg_fmts(struct syscall *sc)
1187{ 1128{
1188 struct format_field *field; 1129 struct format_field *field;
1189 int idx = 0; 1130 int idx = 0, len;
1190 1131
1191 sc->arg_scnprintf = calloc(sc->nr_args, sizeof(void *)); 1132 sc->arg_scnprintf = calloc(sc->nr_args, sizeof(void *));
1192 if (sc->arg_scnprintf == NULL) 1133 if (sc->arg_scnprintf == NULL)
@@ -1198,12 +1139,31 @@ static int syscall__set_arg_fmts(struct syscall *sc)
1198 for (field = sc->args; field; field = field->next) { 1139 for (field = sc->args; field; field = field->next) {
1199 if (sc->fmt && sc->fmt->arg_scnprintf[idx]) 1140 if (sc->fmt && sc->fmt->arg_scnprintf[idx])
1200 sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx]; 1141 sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx];
1142 else if (strcmp(field->type, "const char *") == 0 &&
1143 (strcmp(field->name, "filename") == 0 ||
1144 strcmp(field->name, "path") == 0 ||
1145 strcmp(field->name, "pathname") == 0))
1146 sc->arg_scnprintf[idx] = SCA_FILENAME;
1201 else if (field->flags & FIELD_IS_POINTER) 1147 else if (field->flags & FIELD_IS_POINTER)
1202 sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex; 1148 sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex;
1203 else if (strcmp(field->type, "pid_t") == 0) 1149 else if (strcmp(field->type, "pid_t") == 0)
1204 sc->arg_scnprintf[idx] = SCA_PID; 1150 sc->arg_scnprintf[idx] = SCA_PID;
1205 else if (strcmp(field->type, "umode_t") == 0) 1151 else if (strcmp(field->type, "umode_t") == 0)
1206 sc->arg_scnprintf[idx] = SCA_MODE_T; 1152 sc->arg_scnprintf[idx] = SCA_MODE_T;
1153 else if ((strcmp(field->type, "int") == 0 ||
1154 strcmp(field->type, "unsigned int") == 0 ||
1155 strcmp(field->type, "long") == 0) &&
1156 (len = strlen(field->name)) >= 2 &&
1157 strcmp(field->name + len - 2, "fd") == 0) {
1158 /*
1159 * /sys/kernel/tracing/events/syscalls/sys_enter*
1160 * egrep 'field:.*fd;' .../format|sed -r 's/.*field:([a-z ]+) [a-z_]*fd.+/\1/g'|sort|uniq -c
1161 * 65 int
1162 * 23 unsigned int
1163 * 7 unsigned long
1164 */
1165 sc->arg_scnprintf[idx] = SCA_FD;
1166 }
1207 ++idx; 1167 ++idx;
1208 } 1168 }
1209 1169
@@ -1534,7 +1494,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
1534 if (sc->is_exit) { 1494 if (sc->is_exit) {
1535 if (!(trace->duration_filter || trace->summary_only || trace->min_stack)) { 1495 if (!(trace->duration_filter || trace->summary_only || trace->min_stack)) {
1536 trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output); 1496 trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output);
1537 fprintf(trace->output, "%-70s\n", ttrace->entry_str); 1497 fprintf(trace->output, "%-70s)\n", ttrace->entry_str);
1538 } 1498 }
1539 } else { 1499 } else {
1540 ttrace->entry_pending = true; 1500 ttrace->entry_pending = true;
@@ -2887,12 +2847,12 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2887 mmap_pages_user_set = false; 2847 mmap_pages_user_set = false;
2888 2848
2889 if (trace.max_stack == UINT_MAX) { 2849 if (trace.max_stack == UINT_MAX) {
2890 trace.max_stack = sysctl_perf_event_max_stack; 2850 trace.max_stack = input_name ? PERF_MAX_STACK_DEPTH : sysctl_perf_event_max_stack;
2891 max_stack_user_set = false; 2851 max_stack_user_set = false;
2892 } 2852 }
2893 2853
2894#ifdef HAVE_DWARF_UNWIND_SUPPORT 2854#ifdef HAVE_DWARF_UNWIND_SUPPORT
2895 if ((trace.min_stack || max_stack_user_set) && !callchain_param.enabled) 2855 if ((trace.min_stack || max_stack_user_set) && !callchain_param.enabled && trace.trace_syscalls)
2896 record_opts__parse_callchain(&trace.opts, &callchain_param, "dwarf", false); 2856 record_opts__parse_callchain(&trace.opts, &callchain_param, "dwarf", false);
2897#endif 2857#endif
2898 2858
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 797000842d40..15982cee5ef3 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -549,6 +549,9 @@ int main(int argc, const char **argv)
549 if (sysctl__read_int("kernel/perf_event_max_stack", &value) == 0) 549 if (sysctl__read_int("kernel/perf_event_max_stack", &value) == 0)
550 sysctl_perf_event_max_stack = value; 550 sysctl_perf_event_max_stack = value;
551 551
552 if (sysctl__read_int("kernel/perf_event_max_contexts_per_stack", &value) == 0)
553 sysctl_perf_event_max_contexts_per_stack = value;
554
552 cmd = extract_argv0_path(argv[0]); 555 cmd = extract_argv0_path(argv[0]);
553 if (!cmd) 556 if (!cmd)
554 cmd = "perf-help"; 557 cmd = "perf-help";
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 4db73d5a0dbc..7e5a1e8874ce 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -354,9 +354,6 @@ static struct ins_ops nop_ops = {
354 .scnprintf = nop__scnprintf, 354 .scnprintf = nop__scnprintf,
355}; 355};
356 356
357/*
358 * Must be sorted by name!
359 */
360static struct ins instructions[] = { 357static struct ins instructions[] = {
361 { .name = "add", .ops = &mov_ops, }, 358 { .name = "add", .ops = &mov_ops, },
362 { .name = "addl", .ops = &mov_ops, }, 359 { .name = "addl", .ops = &mov_ops, },
@@ -372,8 +369,8 @@ static struct ins instructions[] = {
372 { .name = "bgt", .ops = &jump_ops, }, 369 { .name = "bgt", .ops = &jump_ops, },
373 { .name = "bhi", .ops = &jump_ops, }, 370 { .name = "bhi", .ops = &jump_ops, },
374 { .name = "bl", .ops = &call_ops, }, 371 { .name = "bl", .ops = &call_ops, },
375 { .name = "blt", .ops = &jump_ops, },
376 { .name = "bls", .ops = &jump_ops, }, 372 { .name = "bls", .ops = &jump_ops, },
373 { .name = "blt", .ops = &jump_ops, },
377 { .name = "blx", .ops = &call_ops, }, 374 { .name = "blx", .ops = &call_ops, },
378 { .name = "bne", .ops = &jump_ops, }, 375 { .name = "bne", .ops = &jump_ops, },
379#endif 376#endif
@@ -449,18 +446,39 @@ static struct ins instructions[] = {
449 { .name = "xbeginq", .ops = &jump_ops, }, 446 { .name = "xbeginq", .ops = &jump_ops, },
450}; 447};
451 448
452static int ins__cmp(const void *name, const void *insp) 449static int ins__key_cmp(const void *name, const void *insp)
453{ 450{
454 const struct ins *ins = insp; 451 const struct ins *ins = insp;
455 452
456 return strcmp(name, ins->name); 453 return strcmp(name, ins->name);
457} 454}
458 455
456static int ins__cmp(const void *a, const void *b)
457{
458 const struct ins *ia = a;
459 const struct ins *ib = b;
460
461 return strcmp(ia->name, ib->name);
462}
463
464static void ins__sort(void)
465{
466 const int nmemb = ARRAY_SIZE(instructions);
467
468 qsort(instructions, nmemb, sizeof(struct ins), ins__cmp);
469}
470
459static struct ins *ins__find(const char *name) 471static struct ins *ins__find(const char *name)
460{ 472{
461 const int nmemb = ARRAY_SIZE(instructions); 473 const int nmemb = ARRAY_SIZE(instructions);
474 static bool sorted;
475
476 if (!sorted) {
477 ins__sort();
478 sorted = true;
479 }
462 480
463 return bsearch(name, instructions, nmemb, sizeof(struct ins), ins__cmp); 481 return bsearch(name, instructions, nmemb, sizeof(struct ins), ins__key_cmp);
464} 482}
465 483
466int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym) 484int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym)
@@ -1122,7 +1140,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
1122 } else if (dso__is_kcore(dso)) { 1140 } else if (dso__is_kcore(dso)) {
1123 goto fallback; 1141 goto fallback;
1124 } else if (readlink(symfs_filename, command, sizeof(command)) < 0 || 1142 } else if (readlink(symfs_filename, command, sizeof(command)) < 0 ||
1125 strstr(command, "[kernel.kallsyms]") || 1143 strstr(command, DSO__NAME_KALLSYMS) ||
1126 access(symfs_filename, R_OK)) { 1144 access(symfs_filename, R_OK)) {
1127 free(filename); 1145 free(filename);
1128fallback: 1146fallback:
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index bff425e1232c..67e5966503b2 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -256,7 +256,7 @@ static int machine__write_buildid_table(struct machine *machine, int fd)
256 size_t name_len; 256 size_t name_len;
257 bool in_kernel = false; 257 bool in_kernel = false;
258 258
259 if (!pos->hit) 259 if (!pos->hit && !dso__is_vdso(pos))
260 continue; 260 continue;
261 261
262 if (dso__is_vdso(pos)) { 262 if (dso__is_vdso(pos)) {
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index bbf69d248ec5..9f53020c3269 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -204,6 +204,44 @@ static unsigned long long adjust_signedness(unsigned long long value_int, int si
204 return (value_int & value_mask) | ~value_mask; 204 return (value_int & value_mask) | ~value_mask;
205} 205}
206 206
207static int string_set_value(struct bt_ctf_field *field, const char *string)
208{
209 char *buffer = NULL;
210 size_t len = strlen(string), i, p;
211 int err;
212
213 for (i = p = 0; i < len; i++, p++) {
214 if (isprint(string[i])) {
215 if (!buffer)
216 continue;
217 buffer[p] = string[i];
218 } else {
219 char numstr[5];
220
221 snprintf(numstr, sizeof(numstr), "\\x%02x",
222 (unsigned int)(string[i]) & 0xff);
223
224 if (!buffer) {
225 buffer = zalloc(i + (len - i) * 4 + 2);
226 if (!buffer) {
227 pr_err("failed to set unprintable string '%s'\n", string);
228 return bt_ctf_field_string_set_value(field, "UNPRINTABLE-STRING");
229 }
230 if (i > 0)
231 strncpy(buffer, string, i);
232 }
233 strncat(buffer + p, numstr, 4);
234 p += 3;
235 }
236 }
237
238 if (!buffer)
239 return bt_ctf_field_string_set_value(field, string);
240 err = bt_ctf_field_string_set_value(field, buffer);
241 free(buffer);
242 return err;
243}
244
207static int add_tracepoint_field_value(struct ctf_writer *cw, 245static int add_tracepoint_field_value(struct ctf_writer *cw,
208 struct bt_ctf_event_class *event_class, 246 struct bt_ctf_event_class *event_class,
209 struct bt_ctf_event *event, 247 struct bt_ctf_event *event,
@@ -270,8 +308,7 @@ static int add_tracepoint_field_value(struct ctf_writer *cw,
270 } 308 }
271 309
272 if (flags & FIELD_IS_STRING) 310 if (flags & FIELD_IS_STRING)
273 ret = bt_ctf_field_string_set_value(field, 311 ret = string_set_value(field, data + offset + i * len);
274 data + offset + i * len);
275 else { 312 else {
276 unsigned long long value_int; 313 unsigned long long value_int;
277 314
diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c
index 8d96c80cc67e..c9a6dc173e74 100644
--- a/tools/perf/util/db-export.c
+++ b/tools/perf/util/db-export.c
@@ -298,8 +298,7 @@ static struct call_path *call_path_from_sample(struct db_export *dbe,
298 */ 298 */
299 callchain_param.order = ORDER_CALLER; 299 callchain_param.order = ORDER_CALLER;
300 err = thread__resolve_callchain(thread, &callchain_cursor, evsel, 300 err = thread__resolve_callchain(thread, &callchain_cursor, evsel,
301 sample, NULL, NULL, 301 sample, NULL, NULL, PERF_MAX_STACK_DEPTH);
302 sysctl_perf_event_max_stack);
303 if (err) { 302 if (err) {
304 callchain_param.order = saved_order; 303 callchain_param.order = saved_order;
305 return NULL; 304 return NULL;
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 3357479082ca..5d286f5d7906 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -7,6 +7,7 @@
7#include "auxtrace.h" 7#include "auxtrace.h"
8#include "util.h" 8#include "util.h"
9#include "debug.h" 9#include "debug.h"
10#include "vdso.h"
10 11
11char dso__symtab_origin(const struct dso *dso) 12char dso__symtab_origin(const struct dso *dso)
12{ 13{
@@ -62,9 +63,7 @@ int dso__read_binary_type_filename(const struct dso *dso,
62 } 63 }
63 break; 64 break;
64 case DSO_BINARY_TYPE__BUILD_ID_CACHE: 65 case DSO_BINARY_TYPE__BUILD_ID_CACHE:
65 /* skip the locally configured cache if a symfs is given */ 66 if (dso__build_id_filename(dso, filename, size) == NULL)
66 if (symbol_conf.symfs[0] ||
67 (dso__build_id_filename(dso, filename, size) == NULL))
68 ret = -1; 67 ret = -1;
69 break; 68 break;
70 69
@@ -1169,7 +1168,7 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1169 struct dso *pos; 1168 struct dso *pos;
1170 1169
1171 list_for_each_entry(pos, head, node) { 1170 list_for_each_entry(pos, head, node) {
1172 if (with_hits && !pos->hit) 1171 if (with_hits && !pos->hit && !dso__is_vdso(pos))
1173 continue; 1172 continue;
1174 if (pos->has_build_id) { 1173 if (pos->has_build_id) {
1175 have_build_id = true; 1174 have_build_id = true;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index f6fcc6832949..9b141f12329e 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -673,6 +673,8 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
673 int err; 673 int err;
674 union perf_event *event; 674 union perf_event *event;
675 675
676 if (symbol_conf.kptr_restrict)
677 return -1;
676 if (map == NULL) 678 if (map == NULL)
677 return -1; 679 return -1;
678 680
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index c4bfe11479a0..e82ba90cc969 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -44,6 +44,7 @@ void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
44 perf_evlist__set_maps(evlist, cpus, threads); 44 perf_evlist__set_maps(evlist, cpus, threads);
45 fdarray__init(&evlist->pollfd, 64); 45 fdarray__init(&evlist->pollfd, 64);
46 evlist->workload.pid = -1; 46 evlist->workload.pid = -1;
47 evlist->backward = false;
47} 48}
48 49
49struct perf_evlist *perf_evlist__new(void) 50struct perf_evlist *perf_evlist__new(void)
@@ -679,6 +680,33 @@ static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
679 return NULL; 680 return NULL;
680} 681}
681 682
683static int perf_evlist__set_paused(struct perf_evlist *evlist, bool value)
684{
685 int i;
686
687 for (i = 0; i < evlist->nr_mmaps; i++) {
688 int fd = evlist->mmap[i].fd;
689 int err;
690
691 if (fd < 0)
692 continue;
693 err = ioctl(fd, PERF_EVENT_IOC_PAUSE_OUTPUT, value ? 1 : 0);
694 if (err)
695 return err;
696 }
697 return 0;
698}
699
700int perf_evlist__pause(struct perf_evlist *evlist)
701{
702 return perf_evlist__set_paused(evlist, true);
703}
704
705int perf_evlist__resume(struct perf_evlist *evlist)
706{
707 return perf_evlist__set_paused(evlist, false);
708}
709
682/* When check_messup is true, 'end' must points to a good entry */ 710/* When check_messup is true, 'end' must points to a good entry */
683static union perf_event * 711static union perf_event *
684perf_mmap__read(struct perf_mmap *md, bool check_messup, u64 start, 712perf_mmap__read(struct perf_mmap *md, bool check_messup, u64 start,
@@ -881,6 +909,7 @@ static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
881 if (evlist->mmap[idx].base != NULL) { 909 if (evlist->mmap[idx].base != NULL) {
882 munmap(evlist->mmap[idx].base, evlist->mmap_len); 910 munmap(evlist->mmap[idx].base, evlist->mmap_len);
883 evlist->mmap[idx].base = NULL; 911 evlist->mmap[idx].base = NULL;
912 evlist->mmap[idx].fd = -1;
884 atomic_set(&evlist->mmap[idx].refcnt, 0); 913 atomic_set(&evlist->mmap[idx].refcnt, 0);
885 } 914 }
886 auxtrace_mmap__munmap(&evlist->mmap[idx].auxtrace_mmap); 915 auxtrace_mmap__munmap(&evlist->mmap[idx].auxtrace_mmap);
@@ -901,10 +930,14 @@ void perf_evlist__munmap(struct perf_evlist *evlist)
901 930
902static int perf_evlist__alloc_mmap(struct perf_evlist *evlist) 931static int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
903{ 932{
933 int i;
934
904 evlist->nr_mmaps = cpu_map__nr(evlist->cpus); 935 evlist->nr_mmaps = cpu_map__nr(evlist->cpus);
905 if (cpu_map__empty(evlist->cpus)) 936 if (cpu_map__empty(evlist->cpus))
906 evlist->nr_mmaps = thread_map__nr(evlist->threads); 937 evlist->nr_mmaps = thread_map__nr(evlist->threads);
907 evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); 938 evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
939 for (i = 0; i < evlist->nr_mmaps; i++)
940 evlist->mmap[i].fd = -1;
908 return evlist->mmap != NULL ? 0 : -ENOMEM; 941 return evlist->mmap != NULL ? 0 : -ENOMEM;
909} 942}
910 943
@@ -941,6 +974,7 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
941 evlist->mmap[idx].base = NULL; 974 evlist->mmap[idx].base = NULL;
942 return -1; 975 return -1;
943 } 976 }
977 evlist->mmap[idx].fd = fd;
944 978
945 if (auxtrace_mmap__mmap(&evlist->mmap[idx].auxtrace_mmap, 979 if (auxtrace_mmap__mmap(&evlist->mmap[idx].auxtrace_mmap,
946 &mp->auxtrace_mp, evlist->mmap[idx].base, fd)) 980 &mp->auxtrace_mp, evlist->mmap[idx].base, fd))
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 85d1b59802e8..d740fb877ab6 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -28,6 +28,7 @@ struct record_opts;
28struct perf_mmap { 28struct perf_mmap {
29 void *base; 29 void *base;
30 int mask; 30 int mask;
31 int fd;
31 atomic_t refcnt; 32 atomic_t refcnt;
32 u64 prev; 33 u64 prev;
33 struct auxtrace_mmap auxtrace_mmap; 34 struct auxtrace_mmap auxtrace_mmap;
@@ -43,6 +44,7 @@ struct perf_evlist {
43 bool overwrite; 44 bool overwrite;
44 bool enabled; 45 bool enabled;
45 bool has_user_cpus; 46 bool has_user_cpus;
47 bool backward;
46 size_t mmap_len; 48 size_t mmap_len;
47 int id_pos; 49 int id_pos;
48 int is_pos; 50 int is_pos;
@@ -135,6 +137,8 @@ void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx);
135 137
136void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx); 138void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
137 139
140int perf_evlist__pause(struct perf_evlist *evlist);
141int perf_evlist__resume(struct perf_evlist *evlist);
138int perf_evlist__open(struct perf_evlist *evlist); 142int perf_evlist__open(struct perf_evlist *evlist);
139void perf_evlist__close(struct perf_evlist *evlist); 143void perf_evlist__close(struct perf_evlist *evlist);
140 144
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 52c7d8884741..5d7037ef7d3b 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -37,6 +37,7 @@ static struct {
37 bool clockid; 37 bool clockid;
38 bool clockid_wrong; 38 bool clockid_wrong;
39 bool lbr_flags; 39 bool lbr_flags;
40 bool write_backward;
40} perf_missing_features; 41} perf_missing_features;
41 42
42static clockid_t clockid; 43static clockid_t clockid;
@@ -1376,6 +1377,8 @@ fallback_missing_features:
1376 if (perf_missing_features.lbr_flags) 1377 if (perf_missing_features.lbr_flags)
1377 evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS | 1378 evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS |
1378 PERF_SAMPLE_BRANCH_NO_CYCLES); 1379 PERF_SAMPLE_BRANCH_NO_CYCLES);
1380 if (perf_missing_features.write_backward)
1381 evsel->attr.write_backward = false;
1379retry_sample_id: 1382retry_sample_id:
1380 if (perf_missing_features.sample_id_all) 1383 if (perf_missing_features.sample_id_all)
1381 evsel->attr.sample_id_all = 0; 1384 evsel->attr.sample_id_all = 0;
@@ -1438,6 +1441,12 @@ retry_open:
1438 err = -EINVAL; 1441 err = -EINVAL;
1439 goto out_close; 1442 goto out_close;
1440 } 1443 }
1444
1445 if (evsel->overwrite &&
1446 perf_missing_features.write_backward) {
1447 err = -EINVAL;
1448 goto out_close;
1449 }
1441 } 1450 }
1442 } 1451 }
1443 1452
@@ -1500,6 +1509,10 @@ try_fallback:
1500 PERF_SAMPLE_BRANCH_NO_FLAGS))) { 1509 PERF_SAMPLE_BRANCH_NO_FLAGS))) {
1501 perf_missing_features.lbr_flags = true; 1510 perf_missing_features.lbr_flags = true;
1502 goto fallback_missing_features; 1511 goto fallback_missing_features;
1512 } else if (!perf_missing_features.write_backward &&
1513 evsel->attr.write_backward) {
1514 perf_missing_features.write_backward = true;
1515 goto fallback_missing_features;
1503 } 1516 }
1504 1517
1505out_close: 1518out_close:
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 8a644fef452c..c1f10159804c 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -112,6 +112,7 @@ struct perf_evsel {
112 bool tracking; 112 bool tracking;
113 bool per_pkg; 113 bool per_pkg;
114 bool precise_max; 114 bool precise_max;
115 bool overwrite;
115 /* parse modifier helper */ 116 /* parse modifier helper */
116 int exclude_GH; 117 int exclude_GH;
117 int nr_members; 118 int nr_members;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index cfab531437c7..d1f19e0012d4 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -117,6 +117,13 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
117 hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); 117 hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
118 hists__set_unres_dso_col_len(hists, HISTC_DSO_TO); 118 hists__set_unres_dso_col_len(hists, HISTC_DSO_TO);
119 } 119 }
120
121 if (h->branch_info->srcline_from)
122 hists__new_col_len(hists, HISTC_SRCLINE_FROM,
123 strlen(h->branch_info->srcline_from));
124 if (h->branch_info->srcline_to)
125 hists__new_col_len(hists, HISTC_SRCLINE_TO,
126 strlen(h->branch_info->srcline_to));
120 } 127 }
121 128
122 if (h->mem_info) { 129 if (h->mem_info) {
@@ -1042,6 +1049,8 @@ void hist_entry__delete(struct hist_entry *he)
1042 if (he->branch_info) { 1049 if (he->branch_info) {
1043 map__zput(he->branch_info->from.map); 1050 map__zput(he->branch_info->from.map);
1044 map__zput(he->branch_info->to.map); 1051 map__zput(he->branch_info->to.map);
1052 free_srcline(he->branch_info->srcline_from);
1053 free_srcline(he->branch_info->srcline_to);
1045 zfree(&he->branch_info); 1054 zfree(&he->branch_info);
1046 } 1055 }
1047 1056
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 0f84bfb42bb1..7b54ccf1b737 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -52,6 +52,8 @@ enum hist_column {
52 HISTC_MEM_IADDR_SYMBOL, 52 HISTC_MEM_IADDR_SYMBOL,
53 HISTC_TRANSACTION, 53 HISTC_TRANSACTION,
54 HISTC_CYCLES, 54 HISTC_CYCLES,
55 HISTC_SRCLINE_FROM,
56 HISTC_SRCLINE_TO,
55 HISTC_TRACE, 57 HISTC_TRACE,
56 HISTC_NR_COLS, /* Last entry */ 58 HISTC_NR_COLS, /* Last entry */
57}; 59};
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
1891check_calls: 1887check_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)
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 83f46790c52f..41ac9cfd416b 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -28,6 +28,7 @@ struct machine {
28 pid_t pid; 28 pid_t pid;
29 u16 id_hdr_size; 29 u16 id_hdr_size;
30 bool comm_exec; 30 bool comm_exec;
31 bool kptr_restrict_warned;
31 char *root_dir; 32 char *root_dir;
32 struct rb_root threads; 33 struct rb_root threads;
33 pthread_rwlock_t threads_lock; 34 pthread_rwlock_t threads_lock;
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 62c7f6988e0e..5d1eb1ccd96c 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -264,8 +264,7 @@ static SV *perl_process_callchain(struct perf_sample *sample,
264 goto exit; 264 goto exit;
265 265
266 if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel, 266 if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
267 sample, NULL, NULL, 267 sample, NULL, NULL, scripting_max_stack) != 0) {
268 sysctl_perf_event_max_stack) != 0) {
269 pr_err("Failed to resolve callchain. Skipping\n"); 268 pr_err("Failed to resolve callchain. Skipping\n");
270 goto exit; 269 goto exit;
271 } 270 }
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 20e69edd5006..c4e9bd70723c 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -353,6 +353,88 @@ struct sort_entry sort_srcline = {
353 .se_width_idx = HISTC_SRCLINE, 353 .se_width_idx = HISTC_SRCLINE,
354}; 354};
355 355
356/* --sort srcline_from */
357
358static int64_t
359sort__srcline_from_cmp(struct hist_entry *left, struct hist_entry *right)
360{
361 if (!left->branch_info->srcline_from) {
362 struct map *map = left->branch_info->from.map;
363 if (!map)
364 left->branch_info->srcline_from = SRCLINE_UNKNOWN;
365 else
366 left->branch_info->srcline_from = get_srcline(map->dso,
367 map__rip_2objdump(map,
368 left->branch_info->from.al_addr),
369 left->branch_info->from.sym, true);
370 }
371 if (!right->branch_info->srcline_from) {
372 struct map *map = right->branch_info->from.map;
373 if (!map)
374 right->branch_info->srcline_from = SRCLINE_UNKNOWN;
375 else
376 right->branch_info->srcline_from = get_srcline(map->dso,
377 map__rip_2objdump(map,
378 right->branch_info->from.al_addr),
379 right->branch_info->from.sym, true);
380 }
381 return strcmp(right->branch_info->srcline_from, left->branch_info->srcline_from);
382}
383
384static int hist_entry__srcline_from_snprintf(struct hist_entry *he, char *bf,
385 size_t size, unsigned int width)
386{
387 return repsep_snprintf(bf, size, "%-*.*s", width, width, he->branch_info->srcline_from);
388}
389
390struct sort_entry sort_srcline_from = {
391 .se_header = "From Source:Line",
392 .se_cmp = sort__srcline_from_cmp,
393 .se_snprintf = hist_entry__srcline_from_snprintf,
394 .se_width_idx = HISTC_SRCLINE_FROM,
395};
396
397/* --sort srcline_to */
398
399static int64_t
400sort__srcline_to_cmp(struct hist_entry *left, struct hist_entry *right)
401{
402 if (!left->branch_info->srcline_to) {
403 struct map *map = left->branch_info->to.map;
404 if (!map)
405 left->branch_info->srcline_to = SRCLINE_UNKNOWN;
406 else
407 left->branch_info->srcline_to = get_srcline(map->dso,
408 map__rip_2objdump(map,
409 left->branch_info->to.al_addr),
410 left->branch_info->from.sym, true);
411 }
412 if (!right->branch_info->srcline_to) {
413 struct map *map = right->branch_info->to.map;
414 if (!map)
415 right->branch_info->srcline_to = SRCLINE_UNKNOWN;
416 else
417 right->branch_info->srcline_to = get_srcline(map->dso,
418 map__rip_2objdump(map,
419 right->branch_info->to.al_addr),
420 right->branch_info->to.sym, true);
421 }
422 return strcmp(right->branch_info->srcline_to, left->branch_info->srcline_to);
423}
424
425static int hist_entry__srcline_to_snprintf(struct hist_entry *he, char *bf,
426 size_t size, unsigned int width)
427{
428 return repsep_snprintf(bf, size, "%-*.*s", width, width, he->branch_info->srcline_to);
429}
430
431struct sort_entry sort_srcline_to = {
432 .se_header = "To Source:Line",
433 .se_cmp = sort__srcline_to_cmp,
434 .se_snprintf = hist_entry__srcline_to_snprintf,
435 .se_width_idx = HISTC_SRCLINE_TO,
436};
437
356/* --sort srcfile */ 438/* --sort srcfile */
357 439
358static char no_srcfile[1]; 440static char no_srcfile[1];
@@ -1347,6 +1429,8 @@ static struct sort_dimension bstack_sort_dimensions[] = {
1347 DIM(SORT_IN_TX, "in_tx", sort_in_tx), 1429 DIM(SORT_IN_TX, "in_tx", sort_in_tx),
1348 DIM(SORT_ABORT, "abort", sort_abort), 1430 DIM(SORT_ABORT, "abort", sort_abort),
1349 DIM(SORT_CYCLES, "cycles", sort_cycles), 1431 DIM(SORT_CYCLES, "cycles", sort_cycles),
1432 DIM(SORT_SRCLINE_FROM, "srcline_from", sort_srcline_from),
1433 DIM(SORT_SRCLINE_TO, "srcline_to", sort_srcline_to),
1350}; 1434};
1351 1435
1352#undef DIM 1436#undef DIM
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 42927f448bcb..ebb59cacd092 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -215,6 +215,8 @@ enum sort_type {
215 SORT_ABORT, 215 SORT_ABORT,
216 SORT_IN_TX, 216 SORT_IN_TX,
217 SORT_CYCLES, 217 SORT_CYCLES,
218 SORT_SRCLINE_FROM,
219 SORT_SRCLINE_TO,
218 220
219 /* memory mode specific sort keys */ 221 /* memory mode specific sort keys */
220 __SORT_MEMORY_MODE, 222 __SORT_MEMORY_MODE,
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index fdb71961143e..aa9efe08762b 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -94,7 +94,8 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
94{ 94{
95 int ctx = evsel_context(counter); 95 int ctx = evsel_context(counter);
96 96
97 if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK)) 97 if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK) ||
98 perf_evsel__match(counter, SOFTWARE, SW_CPU_CLOCK))
98 update_stats(&runtime_nsecs_stats[cpu], count[0]); 99 update_stats(&runtime_nsecs_stats[cpu], count[0]);
99 else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) 100 else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
100 update_stats(&runtime_cycles_stats[ctx][cpu], count[0]); 101 update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
@@ -188,7 +189,7 @@ static void print_stalled_cycles_backend(int cpu,
188 189
189 color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio); 190 color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
190 191
191 out->print_metric(out->ctx, color, "%6.2f%%", "backend cycles idle", ratio); 192 out->print_metric(out->ctx, color, "%7.2f%%", "backend cycles idle", ratio);
192} 193}
193 194
194static void print_branch_misses(int cpu, 195static void print_branch_misses(int cpu,
@@ -444,7 +445,8 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
444 ratio = total / avg; 445 ratio = total / avg;
445 446
446 print_metric(ctxp, NULL, "%8.0f", "cycles / elision", ratio); 447 print_metric(ctxp, NULL, "%8.0f", "cycles / elision", ratio);
447 } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) { 448 } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK) ||
449 perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK)) {
448 if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0) 450 if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0)
449 print_metric(ctxp, NULL, "%8.3f", "CPUs utilized", 451 print_metric(ctxp, NULL, "%8.3f", "CPUs utilized",
450 avg / ratio); 452 avg / ratio);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 7fb33304fb4e..54c4ff2b1cee 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1662,8 +1662,8 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map)
1662 1662
1663 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); 1663 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
1664 1664
1665 scnprintf(path, sizeof(path), "%s/[kernel.kcore]/%s", buildid_dir, 1665 scnprintf(path, sizeof(path), "%s/%s/%s", buildid_dir,
1666 sbuild_id); 1666 DSO__NAME_KCORE, sbuild_id);
1667 1667
1668 /* Use /proc/kallsyms if possible */ 1668 /* Use /proc/kallsyms if possible */
1669 if (is_host) { 1669 if (is_host) {
@@ -1699,8 +1699,8 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map)
1699 if (!find_matching_kcore(map, path, sizeof(path))) 1699 if (!find_matching_kcore(map, path, sizeof(path)))
1700 return strdup(path); 1700 return strdup(path);
1701 1701
1702 scnprintf(path, sizeof(path), "%s/[kernel.kallsyms]/%s", 1702 scnprintf(path, sizeof(path), "%s/%s/%s",
1703 buildid_dir, sbuild_id); 1703 buildid_dir, DSO__NAME_KALLSYMS, sbuild_id);
1704 1704
1705 if (access(path, F_OK)) { 1705 if (access(path, F_OK)) {
1706 pr_err("No kallsyms or vmlinux with build-id %s was found\n", 1706 pr_err("No kallsyms or vmlinux with build-id %s was found\n",
@@ -1769,7 +1769,7 @@ do_kallsyms:
1769 1769
1770 if (err > 0 && !dso__is_kcore(dso)) { 1770 if (err > 0 && !dso__is_kcore(dso)) {
1771 dso->binary_type = DSO_BINARY_TYPE__KALLSYMS; 1771 dso->binary_type = DSO_BINARY_TYPE__KALLSYMS;
1772 dso__set_long_name(dso, "[kernel.kallsyms]", false); 1772 dso__set_long_name(dso, DSO__NAME_KALLSYMS, false);
1773 map__fixup_start(map); 1773 map__fixup_start(map);
1774 map__fixup_end(map); 1774 map__fixup_end(map);
1775 } 1775 }
@@ -1933,17 +1933,17 @@ int setup_intlist(struct intlist **list, const char *list_str,
1933static bool symbol__read_kptr_restrict(void) 1933static bool symbol__read_kptr_restrict(void)
1934{ 1934{
1935 bool value = false; 1935 bool value = false;
1936 FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
1936 1937
1937 if (geteuid() != 0) { 1938 if (fp != NULL) {
1938 FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r"); 1939 char line[8];
1939 if (fp != NULL) {
1940 char line[8];
1941 1940
1942 if (fgets(line, sizeof(line), fp) != NULL) 1941 if (fgets(line, sizeof(line), fp) != NULL)
1943 value = atoi(line) != 0; 1942 value = (geteuid() != 0) ?
1943 (atoi(line) != 0) :
1944 (atoi(line) == 2);
1944 1945
1945 fclose(fp); 1946 fclose(fp);
1946 }
1947 } 1947 }
1948 1948
1949 return value; 1949 return value;
@@ -2033,3 +2033,26 @@ void symbol__exit(void)
2033 symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL; 2033 symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
2034 symbol_conf.initialized = false; 2034 symbol_conf.initialized = false;
2035} 2035}
2036
2037int symbol__config_symfs(const struct option *opt __maybe_unused,
2038 const char *dir, int unset __maybe_unused)
2039{
2040 char *bf = NULL;
2041 int ret;
2042
2043 symbol_conf.symfs = strdup(dir);
2044 if (symbol_conf.symfs == NULL)
2045 return -ENOMEM;
2046
2047 /* skip the locally configured cache if a symfs is given, and
2048 * config buildid dir to symfs/.debug
2049 */
2050 ret = asprintf(&bf, "%s/%s", dir, ".debug");
2051 if (ret < 0)
2052 return -ENOMEM;
2053
2054 set_buildid_dir(bf);
2055
2056 free(bf);
2057 return 0;
2058}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 2b5e4ed76fcb..b10d558a8803 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -44,6 +44,9 @@ Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
44#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ 44#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
45#endif 45#endif
46 46
47#define DSO__NAME_KALLSYMS "[kernel.kallsyms]"
48#define DSO__NAME_KCORE "[kernel.kcore]"
49
47/** struct symbol - symtab entry 50/** struct symbol - symtab entry
48 * 51 *
49 * @ignore - resolvable but tools ignore it (e.g. idle routines) 52 * @ignore - resolvable but tools ignore it (e.g. idle routines)
@@ -183,6 +186,8 @@ struct branch_info {
183 struct addr_map_symbol from; 186 struct addr_map_symbol from;
184 struct addr_map_symbol to; 187 struct addr_map_symbol to;
185 struct branch_flags flags; 188 struct branch_flags flags;
189 char *srcline_from;
190 char *srcline_to;
186}; 191};
187 192
188struct mem_info { 193struct mem_info {
@@ -287,6 +292,8 @@ bool symbol_type__is_a(char symbol_type, enum map_type map_type);
287bool symbol__restricted_filename(const char *filename, 292bool symbol__restricted_filename(const char *filename,
288 const char *restricted_filename); 293 const char *restricted_filename);
289bool symbol__is_idle(struct symbol *sym); 294bool symbol__is_idle(struct symbol *sym);
295int symbol__config_symfs(const struct option *opt __maybe_unused,
296 const char *dir, int unset __maybe_unused);
290 297
291int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, 298int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
292 struct symsrc *runtime_ss, symbol_filter_t filter, 299 struct symsrc *runtime_ss, symbol_filter_t filter,
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index f92c37abb0a8..b2940c88734a 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -27,7 +27,6 @@ struct perf_top {
27 int max_stack; 27 int max_stack;
28 bool hide_kernel_symbols, hide_user_symbols, zero; 28 bool hide_kernel_symbols, hide_user_symbols, zero;
29 bool use_tui, use_stdio; 29 bool use_tui, use_stdio;
30 bool kptr_restrict_warned;
31 bool vmlinux_warned; 30 bool vmlinux_warned;
32 bool dump_symtab; 31 bool dump_symtab;
33 struct hist_entry *sym_filter_entry; 32 struct hist_entry *sym_filter_entry;
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index eab077ad6ca9..23504ad5d6dd 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -33,7 +33,8 @@ struct callchain_param callchain_param = {
33unsigned int page_size; 33unsigned int page_size;
34int cacheline_size; 34int cacheline_size;
35 35
36unsigned int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH; 36int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH;
37int sysctl_perf_event_max_contexts_per_stack = PERF_MAX_CONTEXTS_PER_STACK;
37 38
38bool test_attr__enabled; 39bool test_attr__enabled;
39 40
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 7651633a8dc7..1e8c3167b9fb 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -261,7 +261,8 @@ void sighandler_dump_stack(int sig);
261 261
262extern unsigned int page_size; 262extern unsigned int page_size;
263extern int cacheline_size; 263extern int cacheline_size;
264extern unsigned int sysctl_perf_event_max_stack; 264extern int sysctl_perf_event_max_stack;
265extern int sysctl_perf_event_max_contexts_per_stack;
265 266
266struct parse_tag { 267struct parse_tag {
267 char tag; 268 char tag;
diff --git a/tools/testing/radix-tree/tag_check.c b/tools/testing/radix-tree/tag_check.c
index b7447ceb75e9..b0ac05741750 100644
--- a/tools/testing/radix-tree/tag_check.c
+++ b/tools/testing/radix-tree/tag_check.c
@@ -122,7 +122,7 @@ enum {
122 NODE_TAGGED = 2, 122 NODE_TAGGED = 2,
123}; 123};
124 124
125#define THRASH_SIZE 1000 * 1000 125#define THRASH_SIZE (1000 * 1000)
126#define N 127 126#define N 127
127#define BATCH 33 127#define BATCH 33
128 128
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc
index c2b61c4fda11..0bf5085281f3 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc
@@ -23,15 +23,14 @@ if [ ! -f events/sched/sched_process_fork/trigger ]; then
23 exit_unsupported 23 exit_unsupported
24fi 24fi
25 25
26reset_tracer 26if [ ! -f events/sched/sched_process_fork/hist ]; then
27do_reset
28
29FEATURE=`grep hist events/sched/sched_process_fork/trigger`
30if [ -z "$FEATURE" ]; then
31 echo "hist trigger is not supported" 27 echo "hist trigger is not supported"
32 exit_unsupported 28 exit_unsupported
33fi 29fi
34 30
31reset_tracer
32do_reset
33
35echo "Test histogram with execname modifier" 34echo "Test histogram with execname modifier"
36 35
37echo 'hist:keys=common_pid.execname' > events/sched/sched_process_fork/trigger 36echo 'hist:keys=common_pid.execname' > events/sched/sched_process_fork/trigger
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist.tc
index b2902d42a537..a00184cd9c95 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist.tc
@@ -23,15 +23,14 @@ if [ ! -f events/sched/sched_process_fork/trigger ]; then
23 exit_unsupported 23 exit_unsupported
24fi 24fi
25 25
26reset_tracer 26if [ ! -f events/sched/sched_process_fork/hist ]; then
27do_reset
28
29FEATURE=`grep hist events/sched/sched_process_fork/trigger`
30if [ -z "$FEATURE" ]; then
31 echo "hist trigger is not supported" 27 echo "hist trigger is not supported"
32 exit_unsupported 28 exit_unsupported
33fi 29fi
34 30
31reset_tracer
32do_reset
33
35echo "Test histogram basic tigger" 34echo "Test histogram basic tigger"
36 35
37echo 'hist:keys=parent_pid:vals=child_pid' > events/sched/sched_process_fork/trigger 36echo 'hist:keys=parent_pid:vals=child_pid' > events/sched/sched_process_fork/trigger
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-multihist.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-multihist.tc
index 03c4a46561fc..3478b00ead57 100644
--- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-multihist.tc
+++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-multihist.tc
@@ -23,15 +23,14 @@ if [ ! -f events/sched/sched_process_fork/trigger ]; then
23 exit_unsupported 23 exit_unsupported
24fi 24fi
25 25
26reset_tracer 26if [ ! -f events/sched/sched_process_fork/hist ]; then
27do_reset
28
29FEATURE=`grep hist events/sched/sched_process_fork/trigger`
30if [ -z "$FEATURE" ]; then
31 echo "hist trigger is not supported" 27 echo "hist trigger is not supported"
32 exit_unsupported 28 exit_unsupported
33fi 29fi
34 30
31reset_tracer
32do_reset
33
35reset_trigger 34reset_trigger
36 35
37echo "Test histogram multiple tiggers" 36echo "Test histogram multiple tiggers"
diff --git a/tools/testing/selftests/net/reuseport_bpf.c b/tools/testing/selftests/net/reuseport_bpf.c
index 96ba386b1b7b..4a8217448f20 100644
--- a/tools/testing/selftests/net/reuseport_bpf.c
+++ b/tools/testing/selftests/net/reuseport_bpf.c
@@ -111,9 +111,9 @@ static void attach_ebpf(int fd, uint16_t mod)
111 memset(&attr, 0, sizeof(attr)); 111 memset(&attr, 0, sizeof(attr));
112 attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER; 112 attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
113 attr.insn_cnt = ARRAY_SIZE(prog); 113 attr.insn_cnt = ARRAY_SIZE(prog);
114 attr.insns = (uint64_t)prog; 114 attr.insns = (unsigned long) &prog;
115 attr.license = (uint64_t)bpf_license; 115 attr.license = (unsigned long) &bpf_license;
116 attr.log_buf = (uint64_t)bpf_log_buf; 116 attr.log_buf = (unsigned long) &bpf_log_buf;
117 attr.log_size = sizeof(bpf_log_buf); 117 attr.log_size = sizeof(bpf_log_buf);
118 attr.log_level = 1; 118 attr.log_level = 1;
119 attr.kern_version = 0; 119 attr.kern_version = 0;
@@ -351,8 +351,8 @@ static void test_filter_no_reuseport(const struct test_params p)
351 memset(&eprog, 0, sizeof(eprog)); 351 memset(&eprog, 0, sizeof(eprog));
352 eprog.prog_type = BPF_PROG_TYPE_SOCKET_FILTER; 352 eprog.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
353 eprog.insn_cnt = ARRAY_SIZE(ecode); 353 eprog.insn_cnt = ARRAY_SIZE(ecode);
354 eprog.insns = (uint64_t)ecode; 354 eprog.insns = (unsigned long) &ecode;
355 eprog.license = (uint64_t)bpf_license; 355 eprog.license = (unsigned long) &bpf_license;
356 eprog.kern_version = 0; 356 eprog.kern_version = 0;
357 357
358 memset(&cprog, 0, sizeof(cprog)); 358 memset(&cprog, 0, sizeof(cprog));
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 7947e568e057..2e58549b2f02 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -1234,6 +1234,10 @@ TEST_F(TRACE_poke, getpid_runs_normally)
1234# define ARCH_REGS struct user_pt_regs 1234# define ARCH_REGS struct user_pt_regs
1235# define SYSCALL_NUM regs[8] 1235# define SYSCALL_NUM regs[8]
1236# define SYSCALL_RET regs[0] 1236# define SYSCALL_RET regs[0]
1237#elif defined(__hppa__)
1238# define ARCH_REGS struct user_regs_struct
1239# define SYSCALL_NUM gr[20]
1240# define SYSCALL_RET gr[28]
1237#elif defined(__powerpc__) 1241#elif defined(__powerpc__)
1238# define ARCH_REGS struct pt_regs 1242# define ARCH_REGS struct pt_regs
1239# define SYSCALL_NUM gpr[0] 1243# define SYSCALL_NUM gpr[0]
@@ -1303,7 +1307,7 @@ void change_syscall(struct __test_metadata *_metadata,
1303 EXPECT_EQ(0, ret); 1307 EXPECT_EQ(0, ret);
1304 1308
1305#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \ 1309#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \
1306 defined(__s390__) 1310 defined(__s390__) || defined(__hppa__)
1307 { 1311 {
1308 regs.SYSCALL_NUM = syscall; 1312 regs.SYSCALL_NUM = syscall;
1309 } 1313 }
@@ -1505,6 +1509,8 @@ TEST_F(TRACE_syscall, syscall_dropped)
1505# define __NR_seccomp 383 1509# define __NR_seccomp 383
1506# elif defined(__aarch64__) 1510# elif defined(__aarch64__)
1507# define __NR_seccomp 277 1511# define __NR_seccomp 277
1512# elif defined(__hppa__)
1513# define __NR_seccomp 338
1508# elif defined(__powerpc__) 1514# elif defined(__powerpc__)
1509# define __NR_seccomp 358 1515# define __NR_seccomp 358
1510# elif defined(__s390__) 1516# elif defined(__s390__)
diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c
index 932ff577ffc0..00c4f65d12da 100644
--- a/tools/testing/selftests/vm/compaction_test.c
+++ b/tools/testing/selftests/vm/compaction_test.c
@@ -136,7 +136,7 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size)
136 printf("No of huge pages allocated = %d\n", 136 printf("No of huge pages allocated = %d\n",
137 (atoi(nr_hugepages))); 137 (atoi(nr_hugepages)));
138 138
139 if (write(fd, initial_nr_hugepages, sizeof(initial_nr_hugepages)) 139 if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages))
140 != strlen(initial_nr_hugepages)) { 140 != strlen(initial_nr_hugepages)) {
141 perror("Failed to write to /proc/sys/vm/nr_hugepages\n"); 141 perror("Failed to write to /proc/sys/vm/nr_hugepages\n");
142 goto close_fd; 142 goto close_fd;
diff --git a/tools/testing/selftests/vm/thuge-gen.c b/tools/testing/selftests/vm/thuge-gen.c
index c87957295f74..0bc737a75150 100644
--- a/tools/testing/selftests/vm/thuge-gen.c
+++ b/tools/testing/selftests/vm/thuge-gen.c
@@ -30,7 +30,9 @@
30#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) 30#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)
31#define MAP_HUGE_SHIFT 26 31#define MAP_HUGE_SHIFT 26
32#define MAP_HUGE_MASK 0x3f 32#define MAP_HUGE_MASK 0x3f
33#if !defined(MAP_HUGETLB)
33#define MAP_HUGETLB 0x40000 34#define MAP_HUGETLB 0x40000
35#endif
34 36
35#define SHM_HUGETLB 04000 /* segment will use huge TLB pages */ 37#define SHM_HUGETLB 04000 /* segment will use huge TLB pages */
36#define SHM_HUGE_SHIFT 26 38#define SHM_HUGE_SHIFT 26
diff --git a/tools/virtio/ringtest/Makefile b/tools/virtio/ringtest/Makefile
index 6ba745529833..6173adae9f08 100644
--- a/tools/virtio/ringtest/Makefile
+++ b/tools/virtio/ringtest/Makefile
@@ -1,6 +1,6 @@
1all: 1all:
2 2
3all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder 3all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder noring
4 4
5CFLAGS += -Wall 5CFLAGS += -Wall
6CFLAGS += -pthread -O2 -ggdb 6CFLAGS += -pthread -O2 -ggdb
@@ -15,11 +15,13 @@ ring: ring.o main.o
15virtio_ring_0_9: virtio_ring_0_9.o main.o 15virtio_ring_0_9: virtio_ring_0_9.o main.o
16virtio_ring_poll: virtio_ring_poll.o main.o 16virtio_ring_poll: virtio_ring_poll.o main.o
17virtio_ring_inorder: virtio_ring_inorder.o main.o 17virtio_ring_inorder: virtio_ring_inorder.o main.o
18noring: noring.o main.o
18clean: 19clean:
19 -rm main.o 20 -rm main.o
20 -rm ring.o ring 21 -rm ring.o ring
21 -rm virtio_ring_0_9.o virtio_ring_0_9 22 -rm virtio_ring_0_9.o virtio_ring_0_9
22 -rm virtio_ring_poll.o virtio_ring_poll 23 -rm virtio_ring_poll.o virtio_ring_poll
23 -rm virtio_ring_inorder.o virtio_ring_inorder 24 -rm virtio_ring_inorder.o virtio_ring_inorder
25 -rm noring.o noring
24 26
25.PHONY: all clean 27.PHONY: all clean
diff --git a/tools/virtio/ringtest/README b/tools/virtio/ringtest/README
index 34e94c46104f..d83707a336c9 100644
--- a/tools/virtio/ringtest/README
+++ b/tools/virtio/ringtest/README
@@ -1,2 +1,6 @@
1Partial implementation of various ring layouts, useful to tune virtio design. 1Partial implementation of various ring layouts, useful to tune virtio design.
2Uses shared memory heavily. 2Uses shared memory heavily.
3
4Typical use:
5
6# sh run-on-all.sh perf stat -r 10 --log-fd 1 -- ./ring
diff --git a/tools/virtio/ringtest/noring.c b/tools/virtio/ringtest/noring.c
new file mode 100644
index 000000000000..eda2f4824130
--- /dev/null
+++ b/tools/virtio/ringtest/noring.c
@@ -0,0 +1,69 @@
1#define _GNU_SOURCE
2#include "main.h"
3#include <assert.h>
4
5/* stub implementation: useful for measuring overhead */
6void alloc_ring(void)
7{
8}
9
10/* guest side */
11int add_inbuf(unsigned len, void *buf, void *datap)
12{
13 return 0;
14}
15
16/*
17 * skb_array API provides no way for producer to find out whether a given
18 * buffer was consumed. Our tests merely require that a successful get_buf
19 * implies that add_inbuf succeed in the past, and that add_inbuf will succeed,
20 * fake it accordingly.
21 */
22void *get_buf(unsigned *lenp, void **bufp)
23{
24 return "Buffer";
25}
26
27void poll_used(void)
28{
29}
30
31void disable_call()
32{
33 assert(0);
34}
35
36bool enable_call()
37{
38 assert(0);
39}
40
41void kick_available(void)
42{
43 assert(0);
44}
45
46/* host side */
47void disable_kick()
48{
49 assert(0);
50}
51
52bool enable_kick()
53{
54 assert(0);
55}
56
57void poll_avail(void)
58{
59}
60
61bool use_buf(unsigned *lenp, void **bufp)
62{
63 return true;
64}
65
66void call_used(void)
67{
68 assert(0);
69}
diff --git a/tools/virtio/ringtest/run-on-all.sh b/tools/virtio/ringtest/run-on-all.sh
index 52b0f71ffa8d..2e69ca812b4c 100755
--- a/tools/virtio/ringtest/run-on-all.sh
+++ b/tools/virtio/ringtest/run-on-all.sh
@@ -3,10 +3,10 @@
3#use last CPU for host. Why not the first? 3#use last CPU for host. Why not the first?
4#many devices tend to use cpu0 by default so 4#many devices tend to use cpu0 by default so
5#it tends to be busier 5#it tends to be busier
6HOST_AFFINITY=$(cd /dev/cpu; ls|grep -v '[a-z]'|sort -n|tail -1) 6HOST_AFFINITY=$(lscpu -p=cpu | tail -1)
7 7
8#run command on all cpus 8#run command on all cpus
9for cpu in $(cd /dev/cpu; ls|grep -v '[a-z]'|sort -n); 9for cpu in $(seq 0 $HOST_AFFINITY)
10do 10do
11 #Don't run guest and host on same CPU 11 #Don't run guest and host on same CPU
12 #It actually works ok if using signalling 12 #It actually works ok if using signalling
diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
index 1889163f2f05..b9d34b37c017 100644
--- a/tools/vm/slabinfo.c
+++ b/tools/vm/slabinfo.c
@@ -492,7 +492,7 @@ static void slab_stats(struct slabinfo *s)
492 s->deactivate_to_head + s->deactivate_to_tail + s->deactivate_bypass; 492 s->deactivate_to_head + s->deactivate_to_tail + s->deactivate_bypass;
493 493
494 if (total) { 494 if (total) {
495 printf("\nSlab Deactivation Ocurrences %%\n"); 495 printf("\nSlab Deactivation Occurrences %%\n");
496 printf("-------------------------------------------------\n"); 496 printf("-------------------------------------------------\n");
497 printf("Slab full %7lu %3lu%%\n", 497 printf("Slab full %7lu %3lu%%\n",
498 s->deactivate_full, (s->deactivate_full * 100) / total); 498 s->deactivate_full, (s->deactivate_full * 100) / total);
@@ -510,10 +510,11 @@ static void slab_stats(struct slabinfo *s)
510 s->alloc_node_mismatch, (s->alloc_node_mismatch * 100) / total); 510 s->alloc_node_mismatch, (s->alloc_node_mismatch * 100) / total);
511 } 511 }
512 512
513 if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail) 513 if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail) {
514 printf("\nCmpxchg_double Looping\n------------------------\n"); 514 printf("\nCmpxchg_double Looping\n------------------------\n");
515 printf("Locked Cmpxchg Double redos %lu\nUnlocked Cmpxchg Double redos %lu\n", 515 printf("Locked Cmpxchg Double redos %lu\nUnlocked Cmpxchg Double redos %lu\n",
516 s->cmpxchg_double_fail, s->cmpxchg_double_cpu_fail); 516 s->cmpxchg_double_fail, s->cmpxchg_double_cpu_fail);
517 }
517} 518}
518 519
519static void report(struct slabinfo *s) 520static void report(struct slabinfo *s)