aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-10-28 13:37:34 -0400
committerIngo Molnar <mingo@kernel.org>2016-10-28 13:37:34 -0400
commit91a79e5fa696fa626bfbd47f827eaf3eb7d76dc5 (patch)
tree4a9c4582fa25b2d59d0b8a67516d28b0f8da1776
parent76e2d2617d767c445498c4c4b1162eb2201cdd77 (diff)
parent46cb25b1a0ee74bf4a79cfb3081ae3567b2f7135 (diff)
Merge tag 'perf-core-for-mingo-20161028' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
perf/core improvements and fixes from Arnaldo Carvalho de Melo: New features: - Support matching by topic in 'perf list' (Andi Kleen) User visible: - Apply cpu color only when there was activity in 'perf sched map' (Namhyung Kim) - Always show the task's COMM in 'perf sched map -v' (Namhyung Kim) - Fix hierarchy column counts in the perf hist browser (top, report), avoiding showing nothing after pressing the RIGHT key a number of times (Namhyung Kim) Infrastructure: - Support cascading options in libsubcmd and use it to share common options in 'perf sched' subcommands (Namhyung Kim) - Avoid worker cacheline bouncing in 'perf bench futex' (Davidlohr Bueso) - Sanitize numeric parameters in 'perf bench futex' (Davidlohr Bueso) - Update copies of kernel files (Arnaldo Carvalho de Melo) - Fix scripting (perl, python) setup to avoid leaks (Arnaldo Carvalho de Melo) - Add missing object file to the python binding linkage list (Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/include/uapi/asm-generic/mman-common.h5
-rw-r--r--tools/lib/subcmd/parse-options.c14
-rw-r--r--tools/lib/subcmd/parse-options.h2
-rw-r--r--tools/perf/Makefile.perf4
-rw-r--r--tools/perf/arch/x86/entry/syscalls/syscall_64.tbl3
-rw-r--r--tools/perf/bench/futex-hash.c15
-rw-r--r--tools/perf/bench/futex-lock-pi.c7
-rw-r--r--tools/perf/bench/futex-requeue.c2
-rw-r--r--tools/perf/bench/futex-wake-parallel.c4
-rw-r--r--tools/perf/bench/futex-wake.c3
-rw-r--r--tools/perf/bench/futex.h4
-rw-r--r--tools/perf/builtin-sched.c38
-rw-r--r--tools/perf/builtin-script.c10
-rw-r--r--tools/perf/ui/browsers/hists.c15
-rw-r--r--tools/perf/util/parse-branch-options.c2
-rw-r--r--tools/perf/util/pmu.c4
-rw-r--r--tools/perf/util/python-ext-sources1
-rw-r--r--tools/perf/util/trace-event-scripting.c39
-rw-r--r--tools/perf/util/util.c8
-rw-r--r--tools/perf/util/util.h3
20 files changed, 130 insertions, 53 deletions
diff --git a/tools/include/uapi/asm-generic/mman-common.h b/tools/include/uapi/asm-generic/mman-common.h
index 58274382a616..8c27db0c5c08 100644
--- a/tools/include/uapi/asm-generic/mman-common.h
+++ b/tools/include/uapi/asm-generic/mman-common.h
@@ -72,4 +72,9 @@
72#define MAP_HUGE_SHIFT 26 72#define MAP_HUGE_SHIFT 26
73#define MAP_HUGE_MASK 0x3f 73#define MAP_HUGE_MASK 0x3f
74 74
75#define PKEY_DISABLE_ACCESS 0x1
76#define PKEY_DISABLE_WRITE 0x2
77#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\
78 PKEY_DISABLE_WRITE)
79
75#endif /* __ASM_GENERIC_MMAN_COMMON_H */ 80#endif /* __ASM_GENERIC_MMAN_COMMON_H */
diff --git a/tools/lib/subcmd/parse-options.c b/tools/lib/subcmd/parse-options.c
index 981bb4481fd5..3284bb14ae78 100644
--- a/tools/lib/subcmd/parse-options.c
+++ b/tools/lib/subcmd/parse-options.c
@@ -314,12 +314,19 @@ static int get_value(struct parse_opt_ctx_t *p,
314 314
315static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options) 315static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
316{ 316{
317retry:
317 for (; options->type != OPTION_END; options++) { 318 for (; options->type != OPTION_END; options++) {
318 if (options->short_name == *p->opt) { 319 if (options->short_name == *p->opt) {
319 p->opt = p->opt[1] ? p->opt + 1 : NULL; 320 p->opt = p->opt[1] ? p->opt + 1 : NULL;
320 return get_value(p, options, OPT_SHORT); 321 return get_value(p, options, OPT_SHORT);
321 } 322 }
322 } 323 }
324
325 if (options->parent) {
326 options = options->parent;
327 goto retry;
328 }
329
323 return -2; 330 return -2;
324} 331}
325 332
@@ -333,6 +340,7 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
333 if (!arg_end) 340 if (!arg_end)
334 arg_end = arg + strlen(arg); 341 arg_end = arg + strlen(arg);
335 342
343retry:
336 for (; options->type != OPTION_END; options++) { 344 for (; options->type != OPTION_END; options++) {
337 const char *rest; 345 const char *rest;
338 int flags = 0; 346 int flags = 0;
@@ -426,6 +434,12 @@ match:
426 } 434 }
427 if (abbrev_option) 435 if (abbrev_option)
428 return get_value(p, abbrev_option, abbrev_flags); 436 return get_value(p, abbrev_option, abbrev_flags);
437
438 if (options->parent) {
439 options = options->parent;
440 goto retry;
441 }
442
429 return -2; 443 return -2;
430} 444}
431 445
diff --git a/tools/lib/subcmd/parse-options.h b/tools/lib/subcmd/parse-options.h
index d60cab2726da..8866ac438b34 100644
--- a/tools/lib/subcmd/parse-options.h
+++ b/tools/lib/subcmd/parse-options.h
@@ -109,11 +109,13 @@ struct option {
109 intptr_t defval; 109 intptr_t defval;
110 bool *set; 110 bool *set;
111 void *data; 111 void *data;
112 const struct option *parent;
112}; 113};
113 114
114#define check_vtype(v, type) ( BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v ) 115#define check_vtype(v, type) ( BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v )
115 116
116#define OPT_END() { .type = OPTION_END } 117#define OPT_END() { .type = OPTION_END }
118#define OPT_PARENT(p) { .type = OPTION_END, .parent = (p) }
117#define OPT_ARGUMENT(l, h) { .type = OPTION_ARGUMENT, .long_name = (l), .help = (h) } 119#define OPT_ARGUMENT(l, h) { .type = OPTION_ARGUMENT, .long_name = (l), .help = (h) }
118#define OPT_GROUP(h) { .type = OPTION_GROUP, .help = (h) } 120#define OPT_GROUP(h) { .type = OPTION_GROUP, .help = (h) }
119#define OPT_BIT(s, l, v, h, b) { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h), .defval = (b) } 121#define OPT_BIT(s, l, v, h, b) { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h), .defval = (b) }
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 982d6439bb07..7de14f470f3c 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -381,10 +381,10 @@ $(PERF_IN): prepare FORCE
381 (diff -B ../arch/x86/include/asm/cpufeatures.h ../../arch/x86/include/asm/cpufeatures.h >/dev/null) \ 381 (diff -B ../arch/x86/include/asm/cpufeatures.h ../../arch/x86/include/asm/cpufeatures.h >/dev/null) \
382 || echo "Warning: tools/arch/x86/include/asm/cpufeatures.h differs from kernel" >&2 )) || true 382 || echo "Warning: tools/arch/x86/include/asm/cpufeatures.h differs from kernel" >&2 )) || true
383 @(test -f ../../arch/x86/lib/memcpy_64.S && ( \ 383 @(test -f ../../arch/x86/lib/memcpy_64.S && ( \
384 (diff -B ../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memcpy_64.S >/dev/null) \ 384 (diff -B -I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" ../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memcpy_64.S >/dev/null) \
385 || echo "Warning: tools/arch/x86/lib/memcpy_64.S differs from kernel" >&2 )) || true 385 || echo "Warning: tools/arch/x86/lib/memcpy_64.S differs from kernel" >&2 )) || true
386 @(test -f ../../arch/x86/lib/memset_64.S && ( \ 386 @(test -f ../../arch/x86/lib/memset_64.S && ( \
387 (diff -B ../arch/x86/lib/memset_64.S ../../arch/x86/lib/memset_64.S >/dev/null) \ 387 (diff -B -I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" ../arch/x86/lib/memset_64.S ../../arch/x86/lib/memset_64.S >/dev/null) \
388 || echo "Warning: tools/arch/x86/lib/memset_64.S differs from kernel" >&2 )) || true 388 || echo "Warning: tools/arch/x86/lib/memset_64.S differs from kernel" >&2 )) || true
389 @(test -f ../../arch/arm/include/uapi/asm/perf_regs.h && ( \ 389 @(test -f ../../arch/arm/include/uapi/asm/perf_regs.h && ( \
390 (diff -B ../arch/arm/include/uapi/asm/perf_regs.h ../../arch/arm/include/uapi/asm/perf_regs.h >/dev/null) \ 390 (diff -B ../arch/arm/include/uapi/asm/perf_regs.h ../../arch/arm/include/uapi/asm/perf_regs.h >/dev/null) \
diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
index e9ce9c7c39b4..e93ef0b38db8 100644
--- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
@@ -335,6 +335,9 @@
335326 common copy_file_range sys_copy_file_range 335326 common copy_file_range sys_copy_file_range
336327 64 preadv2 sys_preadv2 336327 64 preadv2 sys_preadv2
337328 64 pwritev2 sys_pwritev2 337328 64 pwritev2 sys_pwritev2
338329 common pkey_mprotect sys_pkey_mprotect
339330 common pkey_alloc sys_pkey_alloc
340331 common pkey_free sys_pkey_free
338 341
339# 342#
340# x32-specific system call numbers start at 512 to avoid cache impact 343# x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c
index d9e5e80bb4d0..bfbb6b5f609c 100644
--- a/tools/perf/bench/futex-hash.c
+++ b/tools/perf/bench/futex-hash.c
@@ -39,15 +39,12 @@ static unsigned int threads_starting;
39static struct stats throughput_stats; 39static struct stats throughput_stats;
40static pthread_cond_t thread_parent, thread_worker; 40static pthread_cond_t thread_parent, thread_worker;
41 41
42#define SMP_CACHE_BYTES 256
43#define __cacheline_aligned __attribute__ ((aligned (SMP_CACHE_BYTES)))
44
45struct worker { 42struct worker {
46 int tid; 43 int tid;
47 u_int32_t *futex; 44 u_int32_t *futex;
48 pthread_t thread; 45 pthread_t thread;
49 unsigned long ops; 46 unsigned long ops;
50} __cacheline_aligned; 47};
51 48
52static const struct option options[] = { 49static const struct option options[] = {
53 OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), 50 OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"),
@@ -66,8 +63,9 @@ static const char * const bench_futex_hash_usage[] = {
66static void *workerfn(void *arg) 63static void *workerfn(void *arg)
67{ 64{
68 int ret; 65 int ret;
69 unsigned int i;
70 struct worker *w = (struct worker *) arg; 66 struct worker *w = (struct worker *) arg;
67 unsigned int i;
68 unsigned long ops = w->ops; /* avoid cacheline bouncing */
71 69
72 pthread_mutex_lock(&thread_lock); 70 pthread_mutex_lock(&thread_lock);
73 threads_starting--; 71 threads_starting--;
@@ -77,7 +75,7 @@ static void *workerfn(void *arg)
77 pthread_mutex_unlock(&thread_lock); 75 pthread_mutex_unlock(&thread_lock);
78 76
79 do { 77 do {
80 for (i = 0; i < nfutexes; i++, w->ops++) { 78 for (i = 0; i < nfutexes; i++, ops++) {
81 /* 79 /*
82 * We want the futex calls to fail in order to stress 80 * We want the futex calls to fail in order to stress
83 * the hashing of uaddr and not measure other steps, 81 * the hashing of uaddr and not measure other steps,
@@ -91,6 +89,7 @@ static void *workerfn(void *arg)
91 } 89 }
92 } while (!done); 90 } while (!done);
93 91
92 w->ops = ops;
94 return NULL; 93 return NULL;
95} 94}
96 95
@@ -131,6 +130,8 @@ int bench_futex_hash(int argc, const char **argv,
131 } 130 }
132 131
133 ncpus = sysconf(_SC_NPROCESSORS_ONLN); 132 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
133 nsecs = futexbench_sanitize_numeric(nsecs);
134 nfutexes = futexbench_sanitize_numeric(nfutexes);
134 135
135 sigfillset(&act.sa_mask); 136 sigfillset(&act.sa_mask);
136 act.sa_sigaction = toggle_done; 137 act.sa_sigaction = toggle_done;
@@ -138,6 +139,8 @@ int bench_futex_hash(int argc, const char **argv,
138 139
139 if (!nthreads) /* default to the number of CPUs */ 140 if (!nthreads) /* default to the number of CPUs */
140 nthreads = ncpus; 141 nthreads = ncpus;
142 else
143 nthreads = futexbench_sanitize_numeric(nthreads);
141 144
142 worker = calloc(nthreads, sizeof(*worker)); 145 worker = calloc(nthreads, sizeof(*worker));
143 if (!worker) 146 if (!worker)
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c
index 936d89d30483..465012b320ee 100644
--- a/tools/perf/bench/futex-lock-pi.c
+++ b/tools/perf/bench/futex-lock-pi.c
@@ -75,6 +75,7 @@ static void toggle_done(int sig __maybe_unused,
75static void *workerfn(void *arg) 75static void *workerfn(void *arg)
76{ 76{
77 struct worker *w = (struct worker *) arg; 77 struct worker *w = (struct worker *) arg;
78 unsigned long ops = w->ops;
78 79
79 pthread_mutex_lock(&thread_lock); 80 pthread_mutex_lock(&thread_lock);
80 threads_starting--; 81 threads_starting--;
@@ -103,9 +104,10 @@ static void *workerfn(void *arg)
103 if (ret && !silent) 104 if (ret && !silent)
104 warn("thread %d: Could not unlock pi-lock for %p (%d)", 105 warn("thread %d: Could not unlock pi-lock for %p (%d)",
105 w->tid, w->futex, ret); 106 w->tid, w->futex, ret);
106 w->ops++; /* account for thread's share of work */ 107 ops++; /* account for thread's share of work */
107 } while (!done); 108 } while (!done);
108 109
110 w->ops = ops;
109 return NULL; 111 return NULL;
110} 112}
111 113
@@ -150,6 +152,7 @@ int bench_futex_lock_pi(int argc, const char **argv,
150 goto err; 152 goto err;
151 153
152 ncpus = sysconf(_SC_NPROCESSORS_ONLN); 154 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
155 nsecs = futexbench_sanitize_numeric(nsecs);
153 156
154 sigfillset(&act.sa_mask); 157 sigfillset(&act.sa_mask);
155 act.sa_sigaction = toggle_done; 158 act.sa_sigaction = toggle_done;
@@ -157,6 +160,8 @@ int bench_futex_lock_pi(int argc, const char **argv,
157 160
158 if (!nthreads) 161 if (!nthreads)
159 nthreads = ncpus; 162 nthreads = ncpus;
163 else
164 nthreads = futexbench_sanitize_numeric(nthreads);
160 165
161 worker = calloc(nthreads, sizeof(*worker)); 166 worker = calloc(nthreads, sizeof(*worker));
162 if (!worker) 167 if (!worker)
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c
index 2b9705a8734c..fd4ee95b689a 100644
--- a/tools/perf/bench/futex-requeue.c
+++ b/tools/perf/bench/futex-requeue.c
@@ -128,6 +128,8 @@ int bench_futex_requeue(int argc, const char **argv,
128 128
129 if (!nthreads) 129 if (!nthreads)
130 nthreads = ncpus; 130 nthreads = ncpus;
131 else
132 nthreads = futexbench_sanitize_numeric(nthreads);
131 133
132 worker = calloc(nthreads, sizeof(*worker)); 134 worker = calloc(nthreads, sizeof(*worker));
133 if (!worker) 135 if (!worker)
diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c
index 2c8fa67ad537..beaa6c142477 100644
--- a/tools/perf/bench/futex-wake-parallel.c
+++ b/tools/perf/bench/futex-wake-parallel.c
@@ -217,8 +217,12 @@ int bench_futex_wake_parallel(int argc, const char **argv,
217 sigaction(SIGINT, &act, NULL); 217 sigaction(SIGINT, &act, NULL);
218 218
219 ncpus = sysconf(_SC_NPROCESSORS_ONLN); 219 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
220 nwaking_threads = futexbench_sanitize_numeric(nwaking_threads);
221
220 if (!nblocked_threads) 222 if (!nblocked_threads)
221 nblocked_threads = ncpus; 223 nblocked_threads = ncpus;
224 else
225 nblocked_threads = futexbench_sanitize_numeric(nblocked_threads);
222 226
223 /* some sanity checks */ 227 /* some sanity checks */
224 if (nwaking_threads > nblocked_threads || !nwaking_threads) 228 if (nwaking_threads > nblocked_threads || !nwaking_threads)
diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c
index e246b1b8388a..46efcb98b5a4 100644
--- a/tools/perf/bench/futex-wake.c
+++ b/tools/perf/bench/futex-wake.c
@@ -129,6 +129,7 @@ int bench_futex_wake(int argc, const char **argv,
129 } 129 }
130 130
131 ncpus = sysconf(_SC_NPROCESSORS_ONLN); 131 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
132 nwakes = futexbench_sanitize_numeric(nwakes);
132 133
133 sigfillset(&act.sa_mask); 134 sigfillset(&act.sa_mask);
134 act.sa_sigaction = toggle_done; 135 act.sa_sigaction = toggle_done;
@@ -136,6 +137,8 @@ int bench_futex_wake(int argc, const char **argv,
136 137
137 if (!nthreads) 138 if (!nthreads)
138 nthreads = ncpus; 139 nthreads = ncpus;
140 else
141 nthreads = futexbench_sanitize_numeric(nthreads);
139 142
140 worker = calloc(nthreads, sizeof(*worker)); 143 worker = calloc(nthreads, sizeof(*worker));
141 if (!worker) 144 if (!worker)
diff --git a/tools/perf/bench/futex.h b/tools/perf/bench/futex.h
index b2e06d1190d0..ba7c735c0c62 100644
--- a/tools/perf/bench/futex.h
+++ b/tools/perf/bench/futex.h
@@ -7,6 +7,7 @@
7#ifndef _FUTEX_H 7#ifndef _FUTEX_H
8#define _FUTEX_H 8#define _FUTEX_H
9 9
10#include <stdlib.h>
10#include <unistd.h> 11#include <unistd.h>
11#include <sys/syscall.h> 12#include <sys/syscall.h>
12#include <sys/types.h> 13#include <sys/types.h>
@@ -99,4 +100,7 @@ static inline int pthread_attr_setaffinity_np(pthread_attr_t *attr,
99} 100}
100#endif 101#endif
101 102
103/* User input sanitation */
104#define futexbench_sanitize_numeric(__n) abs((__n))
105
102#endif /* _FUTEX_H */ 106#endif /* _FUTEX_H */
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index f5503ca22e1c..fb3441211e4b 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1191,6 +1191,7 @@ static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_
1191 int i; 1191 int i;
1192 int ret; 1192 int ret;
1193 u64 avg; 1193 u64 avg;
1194 char max_lat_at[32];
1194 1195
1195 if (!work_list->nb_atoms) 1196 if (!work_list->nb_atoms)
1196 return; 1197 return;
@@ -1212,12 +1213,13 @@ static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_
1212 printf(" "); 1213 printf(" ");
1213 1214
1214 avg = work_list->total_lat / work_list->nb_atoms; 1215 avg = work_list->total_lat / work_list->nb_atoms;
1216 timestamp__scnprintf_usec(work_list->max_lat_at, max_lat_at, sizeof(max_lat_at));
1215 1217
1216 printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: %13.6f s\n", 1218 printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: %13s s\n",
1217 (double)work_list->total_runtime / NSEC_PER_MSEC, 1219 (double)work_list->total_runtime / NSEC_PER_MSEC,
1218 work_list->nb_atoms, (double)avg / NSEC_PER_MSEC, 1220 work_list->nb_atoms, (double)avg / NSEC_PER_MSEC,
1219 (double)work_list->max_lat / NSEC_PER_MSEC, 1221 (double)work_list->max_lat / NSEC_PER_MSEC,
1220 (double)work_list->max_lat_at / NSEC_PER_SEC); 1222 max_lat_at);
1221} 1223}
1222 1224
1223static int pid_cmp(struct work_atoms *l, struct work_atoms *r) 1225static int pid_cmp(struct work_atoms *l, struct work_atoms *r)
@@ -1402,6 +1404,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
1402 int cpus_nr; 1404 int cpus_nr;
1403 bool new_cpu = false; 1405 bool new_cpu = false;
1404 const char *color = PERF_COLOR_NORMAL; 1406 const char *color = PERF_COLOR_NORMAL;
1407 char stimestamp[32];
1405 1408
1406 BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0); 1409 BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0);
1407 1410
@@ -1479,7 +1482,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
1479 cpu_color = COLOR_CPUS; 1482 cpu_color = COLOR_CPUS;
1480 1483
1481 if (cpu != this_cpu) 1484 if (cpu != this_cpu)
1482 color_fprintf(stdout, cpu_color, " "); 1485 color_fprintf(stdout, color, " ");
1483 else 1486 else
1484 color_fprintf(stdout, cpu_color, "*"); 1487 color_fprintf(stdout, cpu_color, "*");
1485 1488
@@ -1492,8 +1495,9 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
1492 if (sched->map.cpus && !cpu_map__has(sched->map.cpus, this_cpu)) 1495 if (sched->map.cpus && !cpu_map__has(sched->map.cpus, this_cpu))
1493 goto out; 1496 goto out;
1494 1497
1495 color_fprintf(stdout, color, " %12.6f secs ", (double)timestamp / NSEC_PER_SEC); 1498 timestamp__scnprintf_usec(timestamp, stimestamp, sizeof(stimestamp));
1496 if (new_shortname) { 1499 color_fprintf(stdout, color, " %12s secs ", stimestamp);
1500 if (new_shortname || (verbose && sched_in->tid)) {
1497 const char *pid_color = color; 1501 const char *pid_color = color;
1498 1502
1499 if (thread__has_color(sched_in)) 1503 if (thread__has_color(sched_in))
@@ -1954,6 +1958,15 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
1954 .next_shortname2 = '0', 1958 .next_shortname2 = '0',
1955 .skip_merge = 0, 1959 .skip_merge = 0,
1956 }; 1960 };
1961 const struct option sched_options[] = {
1962 OPT_STRING('i', "input", &input_name, "file",
1963 "input file name"),
1964 OPT_INCR('v', "verbose", &verbose,
1965 "be more verbose (show symbol address, etc)"),
1966 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1967 "dump raw trace in ASCII"),
1968 OPT_END()
1969 };
1957 const struct option latency_options[] = { 1970 const struct option latency_options[] = {
1958 OPT_STRING('s', "sort", &sched.sort_order, "key[,key2...]", 1971 OPT_STRING('s', "sort", &sched.sort_order, "key[,key2...]",
1959 "sort by key(s): runtime, switch, avg, max"), 1972 "sort by key(s): runtime, switch, avg, max"),
@@ -1965,7 +1978,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
1965 "dump raw trace in ASCII"), 1978 "dump raw trace in ASCII"),
1966 OPT_BOOLEAN('p', "pids", &sched.skip_merge, 1979 OPT_BOOLEAN('p', "pids", &sched.skip_merge,
1967 "latency stats per pid instead of per comm"), 1980 "latency stats per pid instead of per comm"),
1968 OPT_END() 1981 OPT_PARENT(sched_options)
1969 }; 1982 };
1970 const struct option replay_options[] = { 1983 const struct option replay_options[] = {
1971 OPT_UINTEGER('r', "repeat", &sched.replay_repeat, 1984 OPT_UINTEGER('r', "repeat", &sched.replay_repeat,
@@ -1975,16 +1988,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
1975 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1988 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1976 "dump raw trace in ASCII"), 1989 "dump raw trace in ASCII"),
1977 OPT_BOOLEAN('f', "force", &sched.force, "don't complain, do it"), 1990 OPT_BOOLEAN('f', "force", &sched.force, "don't complain, do it"),
1978 OPT_END() 1991 OPT_PARENT(sched_options)
1979 };
1980 const struct option sched_options[] = {
1981 OPT_STRING('i', "input", &input_name, "file",
1982 "input file name"),
1983 OPT_INCR('v', "verbose", &verbose,
1984 "be more verbose (show symbol address, etc)"),
1985 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1986 "dump raw trace in ASCII"),
1987 OPT_END()
1988 }; 1992 };
1989 const struct option map_options[] = { 1993 const struct option map_options[] = {
1990 OPT_BOOLEAN(0, "compact", &sched.map.comp, 1994 OPT_BOOLEAN(0, "compact", &sched.map.comp,
@@ -1995,7 +1999,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
1995 "highlight given CPUs in map"), 1999 "highlight given CPUs in map"),
1996 OPT_STRING(0, "cpus", &sched.map.cpus_str, "cpus", 2000 OPT_STRING(0, "cpus", &sched.map.cpus_str, "cpus",
1997 "display given CPUs in map"), 2001 "display given CPUs in map"),
1998 OPT_END() 2002 OPT_PARENT(sched_options)
1999 }; 2003 };
2000 const char * const latency_usage[] = { 2004 const char * const latency_usage[] = {
2001 "perf sched latency [<options>]", 2005 "perf sched latency [<options>]",
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 412fb6e65ac0..e1daff36d070 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -441,7 +441,6 @@ static void print_sample_start(struct perf_sample *sample,
441{ 441{
442 struct perf_event_attr *attr = &evsel->attr; 442 struct perf_event_attr *attr = &evsel->attr;
443 unsigned long secs; 443 unsigned long secs;
444 unsigned long usecs;
445 unsigned long long nsecs; 444 unsigned long long nsecs;
446 445
447 if (PRINT_FIELD(COMM)) { 446 if (PRINT_FIELD(COMM)) {
@@ -471,11 +470,14 @@ static void print_sample_start(struct perf_sample *sample,
471 nsecs = sample->time; 470 nsecs = sample->time;
472 secs = nsecs / NSEC_PER_SEC; 471 secs = nsecs / NSEC_PER_SEC;
473 nsecs -= secs * NSEC_PER_SEC; 472 nsecs -= secs * NSEC_PER_SEC;
474 usecs = nsecs / NSEC_PER_USEC; 473
475 if (nanosecs) 474 if (nanosecs)
476 printf("%5lu.%09llu: ", secs, nsecs); 475 printf("%5lu.%09llu: ", secs, nsecs);
477 else 476 else {
478 printf("%5lu.%06lu: ", secs, usecs); 477 char sample_time[32];
478 timestamp__scnprintf_usec(sample->time, sample_time, sizeof(sample_time));
479 printf("%12s: ", sample_time);
480 }
479 } 481 }
480} 482}
481 483
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index ddc4c3e59cc1..84f5dd2fb59c 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -2076,8 +2076,21 @@ void hist_browser__init(struct hist_browser *browser,
2076 browser->b.use_navkeypressed = true; 2076 browser->b.use_navkeypressed = true;
2077 browser->show_headers = symbol_conf.show_hist_headers; 2077 browser->show_headers = symbol_conf.show_hist_headers;
2078 2078
2079 hists__for_each_format(hists, fmt) 2079 if (symbol_conf.report_hierarchy) {
2080 struct perf_hpp_list_node *fmt_node;
2081
2082 /* count overhead columns (in the first node) */
2083 fmt_node = list_first_entry(&hists->hpp_formats,
2084 struct perf_hpp_list_node, list);
2085 perf_hpp_list__for_each_format(&fmt_node->hpp, fmt)
2086 ++browser->b.columns;
2087
2088 /* add a single column for whole hierarchy sort keys*/
2080 ++browser->b.columns; 2089 ++browser->b.columns;
2090 } else {
2091 hists__for_each_format(hists, fmt)
2092 ++browser->b.columns;
2093 }
2081 2094
2082 hists__reset_column_width(hists); 2095 hists__reset_column_width(hists);
2083} 2096}
diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c
index 3634d6974300..38fd11504015 100644
--- a/tools/perf/util/parse-branch-options.c
+++ b/tools/perf/util/parse-branch-options.c
@@ -64,7 +64,7 @@ int parse_branch_str(const char *str, __u64 *mode)
64 } 64 }
65 if (!br->name) { 65 if (!br->name) {
66 ret = -1; 66 ret = -1;
67 ui__warning("unknown branch filter %s," 67 pr_warning("unknown branch filter %s,"
68 " check man page\n", s); 68 " check man page\n", s);
69 goto error; 69 goto error;
70 } 70 }
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 31b845ec32e2..dc6ccaa4e927 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -1141,7 +1141,9 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
1141 if (event_glob != NULL && 1141 if (event_glob != NULL &&
1142 !(strglobmatch_nocase(name, event_glob) || 1142 !(strglobmatch_nocase(name, event_glob) ||
1143 (!is_cpu && strglobmatch_nocase(alias->name, 1143 (!is_cpu && strglobmatch_nocase(alias->name,
1144 event_glob)))) 1144 event_glob)) ||
1145 (alias->topic &&
1146 strglobmatch_nocase(alias->topic, event_glob))))
1145 continue; 1147 continue;
1146 1148
1147 if (is_cpu && !name_only && !alias->desc) 1149 if (is_cpu && !name_only && !alias->desc)
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index b7d4f4aeee61..0546a4304347 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -18,6 +18,7 @@ util/thread_map.c
18util/util.c 18util/util.c
19util/xyarray.c 19util/xyarray.c
20util/cgroup.c 20util/cgroup.c
21util/parse-branch-options.c
21util/rblist.c 22util/rblist.c
22util/counts.c 23util/counts.c
23util/strlist.c 24util/strlist.c
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c
index 9df61059a85d..0ac9077f62a2 100644
--- a/tools/perf/util/trace-event-scripting.c
+++ b/tools/perf/util/trace-event-scripting.c
@@ -25,6 +25,7 @@
25#include <errno.h> 25#include <errno.h>
26 26
27#include "../perf.h" 27#include "../perf.h"
28#include "debug.h"
28#include "util.h" 29#include "util.h"
29#include "trace-event.h" 30#include "trace-event.h"
30 31
@@ -86,16 +87,15 @@ struct scripting_ops python_scripting_unsupported_ops = {
86 87
87static void register_python_scripting(struct scripting_ops *scripting_ops) 88static void register_python_scripting(struct scripting_ops *scripting_ops)
88{ 89{
89 int err; 90 if (scripting_context == NULL)
90 err = script_spec_register("Python", scripting_ops); 91 scripting_context = malloc(sizeof(*scripting_context));
91 if (err) 92
92 die("error registering Python script extension"); 93 if (scripting_context == NULL ||
93 94 script_spec_register("Python", scripting_ops) ||
94 err = script_spec_register("py", scripting_ops); 95 script_spec_register("py", scripting_ops)) {
95 if (err) 96 pr_err("Error registering Python script extension: disabling it\n");
96 die("error registering py script extension"); 97 zfree(&scripting_context);
97 98 }
98 scripting_context = malloc(sizeof(struct scripting_context));
99} 99}
100 100
101#ifdef NO_LIBPYTHON 101#ifdef NO_LIBPYTHON
@@ -150,16 +150,15 @@ struct scripting_ops perl_scripting_unsupported_ops = {
150 150
151static void register_perl_scripting(struct scripting_ops *scripting_ops) 151static void register_perl_scripting(struct scripting_ops *scripting_ops)
152{ 152{
153 int err; 153 if (scripting_context == NULL)
154 err = script_spec_register("Perl", scripting_ops); 154 scripting_context = malloc(sizeof(*scripting_context));
155 if (err) 155
156 die("error registering Perl script extension"); 156 if (scripting_context == NULL ||
157 157 script_spec_register("Perl", scripting_ops) ||
158 err = script_spec_register("pl", scripting_ops); 158 script_spec_register("pl", scripting_ops)) {
159 if (err) 159 pr_err("Error registering Perl script extension: disabling it\n");
160 die("error registering pl script extension"); 160 zfree(&scripting_context);
161 161 }
162 scripting_context = malloc(sizeof(struct scripting_context));
163} 162}
164 163
165#ifdef NO_LIBPERL 164#ifdef NO_LIBPERL
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 85c56800f17a..5bbd1f609f1f 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -433,6 +433,14 @@ int parse_nsec_time(const char *str, u64 *ptime)
433 return 0; 433 return 0;
434} 434}
435 435
436int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz)
437{
438 u64 sec = timestamp / NSEC_PER_SEC;
439 u64 usec = (timestamp % NSEC_PER_SEC) / NSEC_PER_USEC;
440
441 return scnprintf(buf, sz, "%"PRIu64".%06"PRIu64, sec, usec);
442}
443
436unsigned long parse_tag_value(const char *str, struct parse_tag *tags) 444unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
437{ 445{
438 struct parse_tag *i = tags; 446 struct parse_tag *i = tags;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 71b6992f1d98..79662d67891e 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -362,4 +362,7 @@ extern int sched_getcpu(void);
362#endif 362#endif
363 363
364int is_printable_array(char *p, unsigned int len); 364int is_printable_array(char *p, unsigned int len);
365
366int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz);
367
365#endif /* GIT_COMPAT_UTIL_H */ 368#endif /* GIT_COMPAT_UTIL_H */