diff options
-rw-r--r-- | tools/include/uapi/linux/in.h | 2 | ||||
-rw-r--r-- | tools/perf/Documentation/perf-c2c.txt | 16 | ||||
-rw-r--r-- | tools/perf/Documentation/perf-mem.txt | 2 | ||||
-rw-r--r-- | tools/perf/arch/powerpc/util/Build | 1 | ||||
-rw-r--r-- | tools/perf/arch/powerpc/util/mem-events.c | 11 | ||||
-rw-r--r-- | tools/perf/builtin-trace.c | 25 | ||||
-rw-r--r-- | tools/perf/tests/attr.py | 32 | ||||
-rw-r--r-- | tools/perf/tests/evsel-tp-sched.c | 2 | ||||
-rw-r--r-- | tools/perf/util/c++/clang.cpp | 2 | ||||
-rw-r--r-- | tools/perf/util/mem-events.c | 2 | ||||
-rw-r--r-- | tools/perf/util/symbol-elf.c | 23 |
11 files changed, 88 insertions, 30 deletions
diff --git a/tools/include/uapi/linux/in.h b/tools/include/uapi/linux/in.h index f6052e70bf40..a55cb8b10165 100644 --- a/tools/include/uapi/linux/in.h +++ b/tools/include/uapi/linux/in.h | |||
@@ -268,7 +268,7 @@ struct sockaddr_in { | |||
268 | #define IN_MULTICAST(a) IN_CLASSD(a) | 268 | #define IN_MULTICAST(a) IN_CLASSD(a) |
269 | #define IN_MULTICAST_NET 0xe0000000 | 269 | #define IN_MULTICAST_NET 0xe0000000 |
270 | 270 | ||
271 | #define IN_BADCLASS(a) ((((long int) (a) ) == 0xffffffff) | 271 | #define IN_BADCLASS(a) (((long int) (a) ) == (long int)0xffffffff) |
272 | #define IN_EXPERIMENTAL(a) IN_BADCLASS((a)) | 272 | #define IN_EXPERIMENTAL(a) IN_BADCLASS((a)) |
273 | 273 | ||
274 | #define IN_CLASSE(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000) | 274 | #define IN_CLASSE(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000) |
diff --git a/tools/perf/Documentation/perf-c2c.txt b/tools/perf/Documentation/perf-c2c.txt index 095aebdc5bb7..e6150f21267d 100644 --- a/tools/perf/Documentation/perf-c2c.txt +++ b/tools/perf/Documentation/perf-c2c.txt | |||
@@ -19,8 +19,11 @@ C2C stands for Cache To Cache. | |||
19 | The perf c2c tool provides means for Shared Data C2C/HITM analysis. It allows | 19 | The perf c2c tool provides means for Shared Data C2C/HITM analysis. It allows |
20 | you to track down the cacheline contentions. | 20 | you to track down the cacheline contentions. |
21 | 21 | ||
22 | The tool is based on x86's load latency and precise store facility events | 22 | On x86, the tool is based on load latency and precise store facility events |
23 | provided by Intel CPUs. These events provide: | 23 | provided by Intel CPUs. On PowerPC, the tool uses random instruction sampling |
24 | with thresholding feature. | ||
25 | |||
26 | These events provide: | ||
24 | - memory address of the access | 27 | - memory address of the access |
25 | - type of the access (load and store details) | 28 | - type of the access (load and store details) |
26 | - latency (in cycles) of the load access | 29 | - latency (in cycles) of the load access |
@@ -46,7 +49,7 @@ RECORD OPTIONS | |||
46 | 49 | ||
47 | -l:: | 50 | -l:: |
48 | --ldlat:: | 51 | --ldlat:: |
49 | Configure mem-loads latency. | 52 | Configure mem-loads latency. (x86 only) |
50 | 53 | ||
51 | -k:: | 54 | -k:: |
52 | --all-kernel:: | 55 | --all-kernel:: |
@@ -119,11 +122,16 @@ Following perf record options are configured by default: | |||
119 | -W,-d,--phys-data,--sample-cpu | 122 | -W,-d,--phys-data,--sample-cpu |
120 | 123 | ||
121 | Unless specified otherwise with '-e' option, following events are monitored by | 124 | Unless specified otherwise with '-e' option, following events are monitored by |
122 | default: | 125 | default on x86: |
123 | 126 | ||
124 | cpu/mem-loads,ldlat=30/P | 127 | cpu/mem-loads,ldlat=30/P |
125 | cpu/mem-stores/P | 128 | cpu/mem-stores/P |
126 | 129 | ||
130 | and following on PowerPC: | ||
131 | |||
132 | cpu/mem-loads/ | ||
133 | cpu/mem-stores/ | ||
134 | |||
127 | User can pass any 'perf record' option behind '--' mark, like (to enable | 135 | User can pass any 'perf record' option behind '--' mark, like (to enable |
128 | callchains and system wide monitoring): | 136 | callchains and system wide monitoring): |
129 | 137 | ||
diff --git a/tools/perf/Documentation/perf-mem.txt b/tools/perf/Documentation/perf-mem.txt index f8d2167cf3e7..199ea0f0a6c0 100644 --- a/tools/perf/Documentation/perf-mem.txt +++ b/tools/perf/Documentation/perf-mem.txt | |||
@@ -82,7 +82,7 @@ RECORD OPTIONS | |||
82 | Be more verbose (show counter open errors, etc) | 82 | Be more verbose (show counter open errors, etc) |
83 | 83 | ||
84 | --ldlat <n>:: | 84 | --ldlat <n>:: |
85 | Specify desired latency for loads event. | 85 | Specify desired latency for loads event. (x86 only) |
86 | 86 | ||
87 | In addition, for report all perf report options are valid, and for record | 87 | In addition, for report all perf report options are valid, and for record |
88 | all perf record options. | 88 | all perf record options. |
diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/util/Build index 2e6595310420..ba98bd006488 100644 --- a/tools/perf/arch/powerpc/util/Build +++ b/tools/perf/arch/powerpc/util/Build | |||
@@ -2,6 +2,7 @@ libperf-y += header.o | |||
2 | libperf-y += sym-handling.o | 2 | libperf-y += sym-handling.o |
3 | libperf-y += kvm-stat.o | 3 | libperf-y += kvm-stat.o |
4 | libperf-y += perf_regs.o | 4 | libperf-y += perf_regs.o |
5 | libperf-y += mem-events.o | ||
5 | 6 | ||
6 | libperf-$(CONFIG_DWARF) += dwarf-regs.o | 7 | libperf-$(CONFIG_DWARF) += dwarf-regs.o |
7 | libperf-$(CONFIG_DWARF) += skip-callchain-idx.o | 8 | libperf-$(CONFIG_DWARF) += skip-callchain-idx.o |
diff --git a/tools/perf/arch/powerpc/util/mem-events.c b/tools/perf/arch/powerpc/util/mem-events.c new file mode 100644 index 000000000000..d08311f04e95 --- /dev/null +++ b/tools/perf/arch/powerpc/util/mem-events.c | |||
@@ -0,0 +1,11 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #include "mem-events.h" | ||
3 | |||
4 | /* PowerPC does not support 'ldlat' parameter. */ | ||
5 | char *perf_mem_events__name(int i) | ||
6 | { | ||
7 | if (i == PERF_MEM_EVENTS__LOAD) | ||
8 | return (char *) "cpu/mem-loads/"; | ||
9 | |||
10 | return (char *) "cpu/mem-stores/"; | ||
11 | } | ||
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index ed4583128b9c..b36061cd1ab8 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -2514,19 +2514,30 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp); | |||
2514 | 2514 | ||
2515 | static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist) | 2515 | static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist) |
2516 | { | 2516 | { |
2517 | struct perf_evsel *evsel = perf_evsel__newtp("probe", "vfs_getname"); | 2517 | bool found = false; |
2518 | struct perf_evsel *evsel, *tmp; | ||
2519 | struct parse_events_error err = { .idx = 0, }; | ||
2520 | int ret = parse_events(evlist, "probe:vfs_getname*", &err); | ||
2518 | 2521 | ||
2519 | if (IS_ERR(evsel)) | 2522 | if (ret) |
2520 | return false; | 2523 | return false; |
2521 | 2524 | ||
2522 | if (perf_evsel__field(evsel, "pathname") == NULL) { | 2525 | evlist__for_each_entry_safe(evlist, evsel, tmp) { |
2526 | if (!strstarts(perf_evsel__name(evsel), "probe:vfs_getname")) | ||
2527 | continue; | ||
2528 | |||
2529 | if (perf_evsel__field(evsel, "pathname")) { | ||
2530 | evsel->handler = trace__vfs_getname; | ||
2531 | found = true; | ||
2532 | continue; | ||
2533 | } | ||
2534 | |||
2535 | list_del_init(&evsel->node); | ||
2536 | evsel->evlist = NULL; | ||
2523 | perf_evsel__delete(evsel); | 2537 | perf_evsel__delete(evsel); |
2524 | return false; | ||
2525 | } | 2538 | } |
2526 | 2539 | ||
2527 | evsel->handler = trace__vfs_getname; | 2540 | return found; |
2528 | perf_evlist__add(evlist, evsel); | ||
2529 | return true; | ||
2530 | } | 2541 | } |
2531 | 2542 | ||
2532 | static struct perf_evsel *perf_evsel__new_pgfault(u64 config) | 2543 | static struct perf_evsel *perf_evsel__new_pgfault(u64 config) |
diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py index 44090a9a19f3..e952127e4fb0 100644 --- a/tools/perf/tests/attr.py +++ b/tools/perf/tests/attr.py | |||
@@ -1,6 +1,8 @@ | |||
1 | #! /usr/bin/python | 1 | #! /usr/bin/python |
2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
3 | 3 | ||
4 | from __future__ import print_function | ||
5 | |||
4 | import os | 6 | import os |
5 | import sys | 7 | import sys |
6 | import glob | 8 | import glob |
@@ -8,7 +10,11 @@ import optparse | |||
8 | import tempfile | 10 | import tempfile |
9 | import logging | 11 | import logging |
10 | import shutil | 12 | import shutil |
11 | import ConfigParser | 13 | |
14 | try: | ||
15 | import configparser | ||
16 | except ImportError: | ||
17 | import ConfigParser as configparser | ||
12 | 18 | ||
13 | def data_equal(a, b): | 19 | def data_equal(a, b): |
14 | # Allow multiple values in assignment separated by '|' | 20 | # Allow multiple values in assignment separated by '|' |
@@ -100,20 +106,20 @@ class Event(dict): | |||
100 | def equal(self, other): | 106 | def equal(self, other): |
101 | for t in Event.terms: | 107 | for t in Event.terms: |
102 | log.debug(" [%s] %s %s" % (t, self[t], other[t])); | 108 | log.debug(" [%s] %s %s" % (t, self[t], other[t])); |
103 | if not self.has_key(t) or not other.has_key(t): | 109 | if t not in self or t not in other: |
104 | return False | 110 | return False |
105 | if not data_equal(self[t], other[t]): | 111 | if not data_equal(self[t], other[t]): |
106 | return False | 112 | return False |
107 | return True | 113 | return True |
108 | 114 | ||
109 | def optional(self): | 115 | def optional(self): |
110 | if self.has_key('optional') and self['optional'] == '1': | 116 | if 'optional' in self and self['optional'] == '1': |
111 | return True | 117 | return True |
112 | return False | 118 | return False |
113 | 119 | ||
114 | def diff(self, other): | 120 | def diff(self, other): |
115 | for t in Event.terms: | 121 | for t in Event.terms: |
116 | if not self.has_key(t) or not other.has_key(t): | 122 | if t not in self or t not in other: |
117 | continue | 123 | continue |
118 | if not data_equal(self[t], other[t]): | 124 | if not data_equal(self[t], other[t]): |
119 | log.warning("expected %s=%s, got %s" % (t, self[t], other[t])) | 125 | log.warning("expected %s=%s, got %s" % (t, self[t], other[t])) |
@@ -134,7 +140,7 @@ class Event(dict): | |||
134 | # - expected values assignments | 140 | # - expected values assignments |
135 | class Test(object): | 141 | class Test(object): |
136 | def __init__(self, path, options): | 142 | def __init__(self, path, options): |
137 | parser = ConfigParser.SafeConfigParser() | 143 | parser = configparser.SafeConfigParser() |
138 | parser.read(path) | 144 | parser.read(path) |
139 | 145 | ||
140 | log.warning("running '%s'" % path) | 146 | log.warning("running '%s'" % path) |
@@ -193,7 +199,7 @@ class Test(object): | |||
193 | return True | 199 | return True |
194 | 200 | ||
195 | def load_events(self, path, events): | 201 | def load_events(self, path, events): |
196 | parser_event = ConfigParser.SafeConfigParser() | 202 | parser_event = configparser.SafeConfigParser() |
197 | parser_event.read(path) | 203 | parser_event.read(path) |
198 | 204 | ||
199 | # The event record section header contains 'event' word, | 205 | # The event record section header contains 'event' word, |
@@ -207,7 +213,7 @@ class Test(object): | |||
207 | # Read parent event if there's any | 213 | # Read parent event if there's any |
208 | if (':' in section): | 214 | if (':' in section): |
209 | base = section[section.index(':') + 1:] | 215 | base = section[section.index(':') + 1:] |
210 | parser_base = ConfigParser.SafeConfigParser() | 216 | parser_base = configparser.SafeConfigParser() |
211 | parser_base.read(self.test_dir + '/' + base) | 217 | parser_base.read(self.test_dir + '/' + base) |
212 | base_items = parser_base.items('event') | 218 | base_items = parser_base.items('event') |
213 | 219 | ||
@@ -322,9 +328,9 @@ def run_tests(options): | |||
322 | for f in glob.glob(options.test_dir + '/' + options.test): | 328 | for f in glob.glob(options.test_dir + '/' + options.test): |
323 | try: | 329 | try: |
324 | Test(f, options).run() | 330 | Test(f, options).run() |
325 | except Unsup, obj: | 331 | except Unsup as obj: |
326 | log.warning("unsupp %s" % obj.getMsg()) | 332 | log.warning("unsupp %s" % obj.getMsg()) |
327 | except Notest, obj: | 333 | except Notest as obj: |
328 | log.warning("skipped %s" % obj.getMsg()) | 334 | log.warning("skipped %s" % obj.getMsg()) |
329 | 335 | ||
330 | def setup_log(verbose): | 336 | def setup_log(verbose): |
@@ -363,7 +369,7 @@ def main(): | |||
363 | parser.add_option("-p", "--perf", | 369 | parser.add_option("-p", "--perf", |
364 | action="store", type="string", dest="perf") | 370 | action="store", type="string", dest="perf") |
365 | parser.add_option("-v", "--verbose", | 371 | parser.add_option("-v", "--verbose", |
366 | action="count", dest="verbose") | 372 | default=0, action="count", dest="verbose") |
367 | 373 | ||
368 | options, args = parser.parse_args() | 374 | options, args = parser.parse_args() |
369 | if args: | 375 | if args: |
@@ -373,7 +379,7 @@ def main(): | |||
373 | setup_log(options.verbose) | 379 | setup_log(options.verbose) |
374 | 380 | ||
375 | if not options.test_dir: | 381 | if not options.test_dir: |
376 | print 'FAILED no -d option specified' | 382 | print('FAILED no -d option specified') |
377 | sys.exit(-1) | 383 | sys.exit(-1) |
378 | 384 | ||
379 | if not options.test: | 385 | if not options.test: |
@@ -382,8 +388,8 @@ def main(): | |||
382 | try: | 388 | try: |
383 | run_tests(options) | 389 | run_tests(options) |
384 | 390 | ||
385 | except Fail, obj: | 391 | except Fail as obj: |
386 | print "FAILED %s" % obj.getMsg(); | 392 | print("FAILED %s" % obj.getMsg()) |
387 | sys.exit(-1) | 393 | sys.exit(-1) |
388 | 394 | ||
389 | sys.exit(0) | 395 | sys.exit(0) |
diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c index 5f8501c68da4..5cbba70bcdd0 100644 --- a/tools/perf/tests/evsel-tp-sched.c +++ b/tools/perf/tests/evsel-tp-sched.c | |||
@@ -17,7 +17,7 @@ static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name, | |||
17 | return -1; | 17 | return -1; |
18 | } | 18 | } |
19 | 19 | ||
20 | is_signed = !!(field->flags | TEP_FIELD_IS_SIGNED); | 20 | is_signed = !!(field->flags & TEP_FIELD_IS_SIGNED); |
21 | if (should_be_signed && !is_signed) { | 21 | if (should_be_signed && !is_signed) { |
22 | pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n", | 22 | pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n", |
23 | evsel->name, name, is_signed, should_be_signed); | 23 | evsel->name, name, is_signed, should_be_signed); |
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp index 89512504551b..39c0004f2886 100644 --- a/tools/perf/util/c++/clang.cpp +++ b/tools/perf/util/c++/clang.cpp | |||
@@ -160,7 +160,7 @@ getBPFObjectFromModule(llvm::Module *Module) | |||
160 | } | 160 | } |
161 | PM.run(*Module); | 161 | PM.run(*Module); |
162 | 162 | ||
163 | return std::move(Buffer); | 163 | return Buffer; |
164 | } | 164 | } |
165 | 165 | ||
166 | } | 166 | } |
diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c index 93f74d8d3cdd..42c3e5a229d2 100644 --- a/tools/perf/util/mem-events.c +++ b/tools/perf/util/mem-events.c | |||
@@ -28,7 +28,7 @@ struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX] = { | |||
28 | static char mem_loads_name[100]; | 28 | static char mem_loads_name[100]; |
29 | static bool mem_loads_name__init; | 29 | static bool mem_loads_name__init; |
30 | 30 | ||
31 | char *perf_mem_events__name(int i) | 31 | char * __weak perf_mem_events__name(int i) |
32 | { | 32 | { |
33 | if (i == PERF_MEM_EVENTS__LOAD) { | 33 | if (i == PERF_MEM_EVENTS__LOAD) { |
34 | if (!mem_loads_name__init) { | 34 | if (!mem_loads_name__init) { |
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 66a84d5846c8..dca7dfae69ad 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
@@ -19,6 +19,20 @@ | |||
19 | #define EM_AARCH64 183 /* ARM 64 bit */ | 19 | #define EM_AARCH64 183 /* ARM 64 bit */ |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #ifndef ELF32_ST_VISIBILITY | ||
23 | #define ELF32_ST_VISIBILITY(o) ((o) & 0x03) | ||
24 | #endif | ||
25 | |||
26 | /* For ELF64 the definitions are the same. */ | ||
27 | #ifndef ELF64_ST_VISIBILITY | ||
28 | #define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) | ||
29 | #endif | ||
30 | |||
31 | /* How to extract information held in the st_other field. */ | ||
32 | #ifndef GELF_ST_VISIBILITY | ||
33 | #define GELF_ST_VISIBILITY(val) ELF64_ST_VISIBILITY (val) | ||
34 | #endif | ||
35 | |||
22 | typedef Elf64_Nhdr GElf_Nhdr; | 36 | typedef Elf64_Nhdr GElf_Nhdr; |
23 | 37 | ||
24 | #ifdef HAVE_CPLUS_DEMANGLE_SUPPORT | 38 | #ifdef HAVE_CPLUS_DEMANGLE_SUPPORT |
@@ -87,6 +101,11 @@ static inline uint8_t elf_sym__type(const GElf_Sym *sym) | |||
87 | return GELF_ST_TYPE(sym->st_info); | 101 | return GELF_ST_TYPE(sym->st_info); |
88 | } | 102 | } |
89 | 103 | ||
104 | static inline uint8_t elf_sym__visibility(const GElf_Sym *sym) | ||
105 | { | ||
106 | return GELF_ST_VISIBILITY(sym->st_other); | ||
107 | } | ||
108 | |||
90 | #ifndef STT_GNU_IFUNC | 109 | #ifndef STT_GNU_IFUNC |
91 | #define STT_GNU_IFUNC 10 | 110 | #define STT_GNU_IFUNC 10 |
92 | #endif | 111 | #endif |
@@ -111,7 +130,9 @@ static inline int elf_sym__is_label(const GElf_Sym *sym) | |||
111 | return elf_sym__type(sym) == STT_NOTYPE && | 130 | return elf_sym__type(sym) == STT_NOTYPE && |
112 | sym->st_name != 0 && | 131 | sym->st_name != 0 && |
113 | sym->st_shndx != SHN_UNDEF && | 132 | sym->st_shndx != SHN_UNDEF && |
114 | sym->st_shndx != SHN_ABS; | 133 | sym->st_shndx != SHN_ABS && |
134 | elf_sym__visibility(sym) != STV_HIDDEN && | ||
135 | elf_sym__visibility(sym) != STV_INTERNAL; | ||
115 | } | 136 | } |
116 | 137 | ||
117 | static bool elf_sym__filter(GElf_Sym *sym) | 138 | static bool elf_sym__filter(GElf_Sym *sym) |