diff options
author | Ingo Molnar <mingo@kernel.org> | 2016-03-04 06:19:21 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-03-04 06:19:21 -0500 |
commit | 009668520ae00d52026ccdb3884864e3473c6b65 (patch) | |
tree | 15b2cf5b2f7f6b80773d53247bfcacfa9fcad571 | |
parent | 6f6e151692625e29810f2fe036b4f410540567c8 (diff) | |
parent | fb4605ba47e772ff9d62d1d54218a832ec8b3e1d (diff) |
Merge tag 'perf-core-for-mingo-20160303' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes:
User visible changes:
- Check existence of frontend/backed stalled cycles in 'perf stat' (Andi Kleen)
- Implement CSV metrics output in 'perf stat' (Andi Kleen)
- Support metrics in 'perf stat' --per-core/socket mode (Andi Kleen)
- Avoid installing .o files from tools/lib/ into the python extension (Jiri Olsa)
- Rename the tracepoint '/format' field that carries the syscall ID from 'nr',
that is also the name of some syscalls arguments, to "__syscall_nr", to
avoid having multiple fields with the same name, that was breaking the
python script skeleton generator from perf.data files (Taeung Song)
- Support converting data from bpf events in 'perf data' (Wang Nan)
- Fix segfault in 'perf test' hists related entries (Arnaldo Carvalho de Melo)
- Fix output of %llu for 64 bit values read on 32 bit machines in libtraceevent (Steven Rostedt)
- Fix time stamp rounding issue in libtraceevent (Chaos.Chen)
Infrastructure changes:
- Fix setlocale() breakage in the pmu parsing code (Jiri Olsa)
- Split libtraceevent's pevent_print_event() (Steven Rostedt)
- Librarize some 'perf record' bits to allow handling multiple perf.data
files per session (Wang Nan)
- Ensure return non-zero rc when mmap fails in 'perf record' (Wang Nan)
- Fix double free on 'command_line' in a error path in 'perf script' (Colin Ian King)
- Initialize struct sigaction 'sa_flags' field in a 'perf test' entry (Colin Ian King)
- Fix various build warnings in turbostat, detected with gcc6 (Colin Ian King)
- Use .s extension for preprocessed assembler code (Masahiro Yamada)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | kernel/trace/trace_syscalls.c | 16 | ||||
-rw-r--r-- | tools/build/Makefile.build | 2 | ||||
-rw-r--r-- | tools/lib/traceevent/event-parse.c | 146 | ||||
-rw-r--r-- | tools/lib/traceevent/event-parse.h | 13 | ||||
-rw-r--r-- | tools/perf/arch/x86/tests/rdpmc.c | 1 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 168 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 158 | ||||
-rw-r--r-- | tools/perf/builtin-trace.c | 8 | ||||
-rw-r--r-- | tools/perf/util/data-convert-bt.c | 118 | ||||
-rw-r--r-- | tools/perf/util/pmu.c | 13 | ||||
-rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 4 | ||||
-rw-r--r-- | tools/perf/util/setup.py | 4 | ||||
-rw-r--r-- | tools/perf/util/sort.c | 37 | ||||
-rw-r--r-- | tools/perf/util/stat-shadow.c | 18 | ||||
-rw-r--r-- | tools/perf/util/stat.h | 1 | ||||
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 8 |
16 files changed, 566 insertions, 149 deletions
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 0655afbea83f..d1663083d903 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
@@ -186,11 +186,11 @@ print_syscall_exit(struct trace_iterator *iter, int flags, | |||
186 | 186 | ||
187 | extern char *__bad_type_size(void); | 187 | extern char *__bad_type_size(void); |
188 | 188 | ||
189 | #define SYSCALL_FIELD(type, name) \ | 189 | #define SYSCALL_FIELD(type, field, name) \ |
190 | sizeof(type) != sizeof(trace.name) ? \ | 190 | sizeof(type) != sizeof(trace.field) ? \ |
191 | __bad_type_size() : \ | 191 | __bad_type_size() : \ |
192 | #type, #name, offsetof(typeof(trace), name), \ | 192 | #type, #name, offsetof(typeof(trace), field), \ |
193 | sizeof(trace.name), is_signed_type(type) | 193 | sizeof(trace.field), is_signed_type(type) |
194 | 194 | ||
195 | static int __init | 195 | static int __init |
196 | __set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len) | 196 | __set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len) |
@@ -261,7 +261,8 @@ static int __init syscall_enter_define_fields(struct trace_event_call *call) | |||
261 | int i; | 261 | int i; |
262 | int offset = offsetof(typeof(trace), args); | 262 | int offset = offsetof(typeof(trace), args); |
263 | 263 | ||
264 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); | 264 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr, __syscall_nr), |
265 | FILTER_OTHER); | ||
265 | if (ret) | 266 | if (ret) |
266 | return ret; | 267 | return ret; |
267 | 268 | ||
@@ -281,11 +282,12 @@ static int __init syscall_exit_define_fields(struct trace_event_call *call) | |||
281 | struct syscall_trace_exit trace; | 282 | struct syscall_trace_exit trace; |
282 | int ret; | 283 | int ret; |
283 | 284 | ||
284 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); | 285 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr, __syscall_nr), |
286 | FILTER_OTHER); | ||
285 | if (ret) | 287 | if (ret) |
286 | return ret; | 288 | return ret; |
287 | 289 | ||
288 | ret = trace_define_field(call, SYSCALL_FIELD(long, ret), | 290 | ret = trace_define_field(call, SYSCALL_FIELD(long, ret, ret), |
289 | FILTER_OTHER); | 291 | FILTER_OTHER); |
290 | 292 | ||
291 | return ret; | 293 | return ret; |
diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build index 4a96473b180f..ee566e8bd1cf 100644 --- a/tools/build/Makefile.build +++ b/tools/build/Makefile.build | |||
@@ -85,7 +85,7 @@ $(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,cc_i_c) |
87 | 87 | ||
88 | $(OUTPUT)%.i: %.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,cc_i_c) |
91 | 91 | ||
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 575e75174087..865dea55454b 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -2635,6 +2635,7 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) | |||
2635 | 2635 | ||
2636 | free_field: | 2636 | free_field: |
2637 | free_arg(arg->hex.field); | 2637 | free_arg(arg->hex.field); |
2638 | arg->hex.field = NULL; | ||
2638 | out: | 2639 | out: |
2639 | *tok = NULL; | 2640 | *tok = NULL; |
2640 | return EVENT_ERROR; | 2641 | return EVENT_ERROR; |
@@ -2659,8 +2660,10 @@ process_int_array(struct event_format *event, struct print_arg *arg, char **tok) | |||
2659 | 2660 | ||
2660 | free_size: | 2661 | free_size: |
2661 | free_arg(arg->int_array.count); | 2662 | free_arg(arg->int_array.count); |
2663 | arg->int_array.count = NULL; | ||
2662 | free_field: | 2664 | free_field: |
2663 | free_arg(arg->int_array.field); | 2665 | free_arg(arg->int_array.field); |
2666 | arg->int_array.field = NULL; | ||
2664 | out: | 2667 | out: |
2665 | *tok = NULL; | 2668 | *tok = NULL; |
2666 | return EVENT_ERROR; | 2669 | return EVENT_ERROR; |
@@ -4975,7 +4978,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
4975 | break; | 4978 | break; |
4976 | } | 4979 | } |
4977 | } | 4980 | } |
4978 | if (pevent->long_size == 8 && ls && | 4981 | if (pevent->long_size == 8 && ls == 1 && |
4979 | sizeof(long) != 8) { | 4982 | sizeof(long) != 8) { |
4980 | char *p; | 4983 | char *p; |
4981 | 4984 | ||
@@ -5339,41 +5342,45 @@ static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock) | |||
5339 | return false; | 5342 | return false; |
5340 | } | 5343 | } |
5341 | 5344 | ||
5342 | void pevent_print_event(struct pevent *pevent, struct trace_seq *s, | 5345 | /** |
5343 | struct pevent_record *record, bool use_trace_clock) | 5346 | * pevent_find_event_by_record - return the event from a given record |
5347 | * @pevent: a handle to the pevent | ||
5348 | * @record: The record to get the event from | ||
5349 | * | ||
5350 | * Returns the associated event for a given record, or NULL if non is | ||
5351 | * is found. | ||
5352 | */ | ||
5353 | struct event_format * | ||
5354 | pevent_find_event_by_record(struct pevent *pevent, struct pevent_record *record) | ||
5344 | { | 5355 | { |
5345 | static const char *spaces = " "; /* 20 spaces */ | ||
5346 | struct event_format *event; | ||
5347 | unsigned long secs; | ||
5348 | unsigned long usecs; | ||
5349 | unsigned long nsecs; | ||
5350 | const char *comm; | ||
5351 | void *data = record->data; | ||
5352 | int type; | 5356 | int type; |
5353 | int pid; | ||
5354 | int len; | ||
5355 | int p; | ||
5356 | bool use_usec_format; | ||
5357 | |||
5358 | use_usec_format = is_timestamp_in_us(pevent->trace_clock, | ||
5359 | use_trace_clock); | ||
5360 | if (use_usec_format) { | ||
5361 | secs = record->ts / NSECS_PER_SEC; | ||
5362 | nsecs = record->ts - secs * NSECS_PER_SEC; | ||
5363 | } | ||
5364 | 5357 | ||
5365 | if (record->size < 0) { | 5358 | if (record->size < 0) { |
5366 | do_warning("ug! negative record size %d", record->size); | 5359 | do_warning("ug! negative record size %d", record->size); |
5367 | return; | 5360 | return NULL; |
5368 | } | 5361 | } |
5369 | 5362 | ||
5370 | type = trace_parse_common_type(pevent, data); | 5363 | type = trace_parse_common_type(pevent, record->data); |
5371 | 5364 | ||
5372 | event = pevent_find_event(pevent, type); | 5365 | return pevent_find_event(pevent, type); |
5373 | if (!event) { | 5366 | } |
5374 | do_warning("ug! no event found for type %d", type); | 5367 | |
5375 | return; | 5368 | /** |
5376 | } | 5369 | * pevent_print_event_task - Write the event task comm, pid and CPU |
5370 | * @pevent: a handle to the pevent | ||
5371 | * @s: the trace_seq to write to | ||
5372 | * @event: the handle to the record's event | ||
5373 | * @record: The record to get the event from | ||
5374 | * | ||
5375 | * Writes the tasks comm, pid and CPU to @s. | ||
5376 | */ | ||
5377 | void pevent_print_event_task(struct pevent *pevent, struct trace_seq *s, | ||
5378 | struct event_format *event, | ||
5379 | struct pevent_record *record) | ||
5380 | { | ||
5381 | void *data = record->data; | ||
5382 | const char *comm; | ||
5383 | int pid; | ||
5377 | 5384 | ||
5378 | pid = parse_common_pid(pevent, data); | 5385 | pid = parse_common_pid(pevent, data); |
5379 | comm = find_cmdline(pevent, pid); | 5386 | comm = find_cmdline(pevent, pid); |
@@ -5381,9 +5388,43 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s, | |||
5381 | if (pevent->latency_format) { | 5388 | if (pevent->latency_format) { |
5382 | trace_seq_printf(s, "%8.8s-%-5d %3d", | 5389 | trace_seq_printf(s, "%8.8s-%-5d %3d", |
5383 | comm, pid, record->cpu); | 5390 | comm, pid, record->cpu); |
5384 | pevent_data_lat_fmt(pevent, s, record); | ||
5385 | } else | 5391 | } else |
5386 | trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu); | 5392 | trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu); |
5393 | } | ||
5394 | |||
5395 | /** | ||
5396 | * pevent_print_event_time - Write the event timestamp | ||
5397 | * @pevent: a handle to the pevent | ||
5398 | * @s: the trace_seq to write to | ||
5399 | * @event: the handle to the record's event | ||
5400 | * @record: The record to get the event from | ||
5401 | * @use_trace_clock: Set to parse according to the @pevent->trace_clock | ||
5402 | * | ||
5403 | * Writes the timestamp of the record into @s. | ||
5404 | */ | ||
5405 | void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s, | ||
5406 | struct event_format *event, | ||
5407 | struct pevent_record *record, | ||
5408 | bool use_trace_clock) | ||
5409 | { | ||
5410 | unsigned long secs; | ||
5411 | unsigned long usecs; | ||
5412 | unsigned long nsecs; | ||
5413 | int p; | ||
5414 | bool use_usec_format; | ||
5415 | |||
5416 | use_usec_format = is_timestamp_in_us(pevent->trace_clock, | ||
5417 | use_trace_clock); | ||
5418 | if (use_usec_format) { | ||
5419 | secs = record->ts / NSECS_PER_SEC; | ||
5420 | nsecs = record->ts - secs * NSECS_PER_SEC; | ||
5421 | } | ||
5422 | |||
5423 | if (pevent->latency_format) { | ||
5424 | trace_seq_printf(s, " %3d", record->cpu); | ||
5425 | pevent_data_lat_fmt(pevent, s, record); | ||
5426 | } else | ||
5427 | trace_seq_printf(s, " [%03d]", record->cpu); | ||
5387 | 5428 | ||
5388 | if (use_usec_format) { | 5429 | if (use_usec_format) { |
5389 | if (pevent->flags & PEVENT_NSEC_OUTPUT) { | 5430 | if (pevent->flags & PEVENT_NSEC_OUTPUT) { |
@@ -5391,14 +5432,36 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s, | |||
5391 | p = 9; | 5432 | p = 9; |
5392 | } else { | 5433 | } else { |
5393 | usecs = (nsecs + 500) / NSECS_PER_USEC; | 5434 | usecs = (nsecs + 500) / NSECS_PER_USEC; |
5435 | /* To avoid usecs larger than 1 sec */ | ||
5436 | if (usecs >= 1000000) { | ||
5437 | usecs -= 1000000; | ||
5438 | secs++; | ||
5439 | } | ||
5394 | p = 6; | 5440 | p = 6; |
5395 | } | 5441 | } |
5396 | 5442 | ||
5397 | trace_seq_printf(s, " %5lu.%0*lu: %s: ", | 5443 | trace_seq_printf(s, " %5lu.%0*lu:", secs, p, usecs); |
5398 | secs, p, usecs, event->name); | ||
5399 | } else | 5444 | } else |
5400 | trace_seq_printf(s, " %12llu: %s: ", | 5445 | trace_seq_printf(s, " %12llu:", record->ts); |
5401 | record->ts, event->name); | 5446 | } |
5447 | |||
5448 | /** | ||
5449 | * pevent_print_event_data - Write the event data section | ||
5450 | * @pevent: a handle to the pevent | ||
5451 | * @s: the trace_seq to write to | ||
5452 | * @event: the handle to the record's event | ||
5453 | * @record: The record to get the event from | ||
5454 | * | ||
5455 | * Writes the parsing of the record's data to @s. | ||
5456 | */ | ||
5457 | void pevent_print_event_data(struct pevent *pevent, struct trace_seq *s, | ||
5458 | struct event_format *event, | ||
5459 | struct pevent_record *record) | ||
5460 | { | ||
5461 | static const char *spaces = " "; /* 20 spaces */ | ||
5462 | int len; | ||
5463 | |||
5464 | trace_seq_printf(s, " %s: ", event->name); | ||
5402 | 5465 | ||
5403 | /* Space out the event names evenly. */ | 5466 | /* Space out the event names evenly. */ |
5404 | len = strlen(event->name); | 5467 | len = strlen(event->name); |
@@ -5408,6 +5471,23 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s, | |||
5408 | pevent_event_info(s, event, record); | 5471 | pevent_event_info(s, event, record); |
5409 | } | 5472 | } |
5410 | 5473 | ||
5474 | void pevent_print_event(struct pevent *pevent, struct trace_seq *s, | ||
5475 | struct pevent_record *record, bool use_trace_clock) | ||
5476 | { | ||
5477 | struct event_format *event; | ||
5478 | |||
5479 | event = pevent_find_event_by_record(pevent, record); | ||
5480 | if (!event) { | ||
5481 | do_warning("ug! no event found for type %d", | ||
5482 | trace_parse_common_type(pevent, record->data)); | ||
5483 | return; | ||
5484 | } | ||
5485 | |||
5486 | pevent_print_event_task(pevent, s, event, record); | ||
5487 | pevent_print_event_time(pevent, s, event, record, use_trace_clock); | ||
5488 | pevent_print_event_data(pevent, s, event, record); | ||
5489 | } | ||
5490 | |||
5411 | static int events_id_cmp(const void *a, const void *b) | 5491 | static int events_id_cmp(const void *a, const void *b) |
5412 | { | 5492 | { |
5413 | struct event_format * const * ea = a; | 5493 | struct event_format * const * ea = a; |
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 706d9bc24066..9ffde377e89d 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
@@ -628,6 +628,16 @@ int pevent_register_print_string(struct pevent *pevent, const char *fmt, | |||
628 | unsigned long long addr); | 628 | unsigned long long addr); |
629 | int pevent_pid_is_registered(struct pevent *pevent, int pid); | 629 | int pevent_pid_is_registered(struct pevent *pevent, int pid); |
630 | 630 | ||
631 | void pevent_print_event_task(struct pevent *pevent, struct trace_seq *s, | ||
632 | struct event_format *event, | ||
633 | struct pevent_record *record); | ||
634 | void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s, | ||
635 | struct event_format *event, | ||
636 | struct pevent_record *record, | ||
637 | bool use_trace_clock); | ||
638 | void pevent_print_event_data(struct pevent *pevent, struct trace_seq *s, | ||
639 | struct event_format *event, | ||
640 | struct pevent_record *record); | ||
631 | void pevent_print_event(struct pevent *pevent, struct trace_seq *s, | 641 | void pevent_print_event(struct pevent *pevent, struct trace_seq *s, |
632 | struct pevent_record *record, bool use_trace_clock); | 642 | struct pevent_record *record, bool use_trace_clock); |
633 | 643 | ||
@@ -694,6 +704,9 @@ struct event_format *pevent_find_event(struct pevent *pevent, int id); | |||
694 | struct event_format * | 704 | struct event_format * |
695 | pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name); | 705 | pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name); |
696 | 706 | ||
707 | struct event_format * | ||
708 | pevent_find_event_by_record(struct pevent *pevent, struct pevent_record *record); | ||
709 | |||
697 | void pevent_data_lat_fmt(struct pevent *pevent, | 710 | void pevent_data_lat_fmt(struct pevent *pevent, |
698 | struct trace_seq *s, struct pevent_record *record); | 711 | struct trace_seq *s, struct pevent_record *record); |
699 | int pevent_data_type(struct pevent *pevent, struct pevent_record *rec); | 712 | int pevent_data_type(struct pevent *pevent, struct pevent_record *rec); |
diff --git a/tools/perf/arch/x86/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c index 7bb0d13c235f..7945462851a4 100644 --- a/tools/perf/arch/x86/tests/rdpmc.c +++ b/tools/perf/arch/x86/tests/rdpmc.c | |||
@@ -103,6 +103,7 @@ static int __test__rdpmc(void) | |||
103 | 103 | ||
104 | sigfillset(&sa.sa_mask); | 104 | sigfillset(&sa.sa_mask); |
105 | sa.sa_sigaction = segfault_handler; | 105 | sa.sa_sigaction = segfault_handler; |
106 | sa.sa_flags = 0; | ||
106 | sigaction(SIGSEGV, &sa, NULL); | 107 | sigaction(SIGSEGV, &sa, NULL); |
107 | 108 | ||
108 | fd = sys_perf_event_open(&attr, 0, -1, -1, | 109 | fd = sys_perf_event_open(&attr, 0, -1, -1, |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 7d11162b6c41..515510ecc76a 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "util/parse-regs-options.h" | 33 | #include "util/parse-regs-options.h" |
34 | #include "util/llvm-utils.h" | 34 | #include "util/llvm-utils.h" |
35 | #include "util/bpf-loader.h" | 35 | #include "util/bpf-loader.h" |
36 | #include "asm/bug.h" | ||
36 | 37 | ||
37 | #include <unistd.h> | 38 | #include <unistd.h> |
38 | #include <sched.h> | 39 | #include <sched.h> |
@@ -323,7 +324,10 @@ try_again: | |||
323 | } else { | 324 | } else { |
324 | pr_err("failed to mmap with %d (%s)\n", errno, | 325 | pr_err("failed to mmap with %d (%s)\n", errno, |
325 | strerror_r(errno, msg, sizeof(msg))); | 326 | strerror_r(errno, msg, sizeof(msg))); |
326 | rc = -errno; | 327 | if (errno) |
328 | rc = -errno; | ||
329 | else | ||
330 | rc = -EINVAL; | ||
327 | } | 331 | } |
328 | goto out; | 332 | goto out; |
329 | } | 333 | } |
@@ -467,6 +471,29 @@ static void record__init_features(struct record *rec) | |||
467 | perf_header__clear_feat(&session->header, HEADER_STAT); | 471 | perf_header__clear_feat(&session->header, HEADER_STAT); |
468 | } | 472 | } |
469 | 473 | ||
474 | static void | ||
475 | record__finish_output(struct record *rec) | ||
476 | { | ||
477 | struct perf_data_file *file = &rec->file; | ||
478 | int fd = perf_data_file__fd(file); | ||
479 | |||
480 | if (file->is_pipe) | ||
481 | return; | ||
482 | |||
483 | rec->session->header.data_size += rec->bytes_written; | ||
484 | file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR); | ||
485 | |||
486 | if (!rec->no_buildid) { | ||
487 | process_buildids(rec); | ||
488 | |||
489 | if (rec->buildid_all) | ||
490 | dsos__hit_all(rec->session); | ||
491 | } | ||
492 | perf_session__write_header(rec->session, rec->evlist, fd, true); | ||
493 | |||
494 | return; | ||
495 | } | ||
496 | |||
470 | static volatile int workload_exec_errno; | 497 | static volatile int workload_exec_errno; |
471 | 498 | ||
472 | /* | 499 | /* |
@@ -485,6 +512,74 @@ static void workload_exec_failed_signal(int signo __maybe_unused, | |||
485 | 512 | ||
486 | static void snapshot_sig_handler(int sig); | 513 | static void snapshot_sig_handler(int sig); |
487 | 514 | ||
515 | static int record__synthesize(struct record *rec) | ||
516 | { | ||
517 | struct perf_session *session = rec->session; | ||
518 | struct machine *machine = &session->machines.host; | ||
519 | struct perf_data_file *file = &rec->file; | ||
520 | struct record_opts *opts = &rec->opts; | ||
521 | struct perf_tool *tool = &rec->tool; | ||
522 | int fd = perf_data_file__fd(file); | ||
523 | int err = 0; | ||
524 | |||
525 | if (file->is_pipe) { | ||
526 | err = perf_event__synthesize_attrs(tool, session, | ||
527 | process_synthesized_event); | ||
528 | if (err < 0) { | ||
529 | pr_err("Couldn't synthesize attrs.\n"); | ||
530 | goto out; | ||
531 | } | ||
532 | |||
533 | if (have_tracepoints(&rec->evlist->entries)) { | ||
534 | /* | ||
535 | * FIXME err <= 0 here actually means that | ||
536 | * there were no tracepoints so its not really | ||
537 | * an error, just that we don't need to | ||
538 | * synthesize anything. We really have to | ||
539 | * return this more properly and also | ||
540 | * propagate errors that now are calling die() | ||
541 | */ | ||
542 | err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist, | ||
543 | process_synthesized_event); | ||
544 | if (err <= 0) { | ||
545 | pr_err("Couldn't record tracing data.\n"); | ||
546 | goto out; | ||
547 | } | ||
548 | rec->bytes_written += err; | ||
549 | } | ||
550 | } | ||
551 | |||
552 | if (rec->opts.full_auxtrace) { | ||
553 | err = perf_event__synthesize_auxtrace_info(rec->itr, tool, | ||
554 | session, process_synthesized_event); | ||
555 | if (err) | ||
556 | goto out; | ||
557 | } | ||
558 | |||
559 | err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, | ||
560 | machine); | ||
561 | WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n" | ||
562 | "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" | ||
563 | "Check /proc/kallsyms permission or run as root.\n"); | ||
564 | |||
565 | err = perf_event__synthesize_modules(tool, process_synthesized_event, | ||
566 | machine); | ||
567 | WARN_ONCE(err < 0, "Couldn't record kernel module information.\n" | ||
568 | "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" | ||
569 | "Check /proc/modules permission or run as root.\n"); | ||
570 | |||
571 | if (perf_guest) { | ||
572 | machines__process_guests(&session->machines, | ||
573 | perf_event__synthesize_guest_os, tool); | ||
574 | } | ||
575 | |||
576 | err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads, | ||
577 | process_synthesized_event, opts->sample_address, | ||
578 | opts->proc_map_timeout); | ||
579 | out: | ||
580 | return err; | ||
581 | } | ||
582 | |||
488 | static int __cmd_record(struct record *rec, int argc, const char **argv) | 583 | static int __cmd_record(struct record *rec, int argc, const char **argv) |
489 | { | 584 | { |
490 | int err; | 585 | int err; |
@@ -579,63 +674,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) | |||
579 | 674 | ||
580 | machine = &session->machines.host; | 675 | machine = &session->machines.host; |
581 | 676 | ||
582 | if (file->is_pipe) { | 677 | err = record__synthesize(rec); |
583 | err = perf_event__synthesize_attrs(tool, session, | ||
584 | process_synthesized_event); | ||
585 | if (err < 0) { | ||
586 | pr_err("Couldn't synthesize attrs.\n"); | ||
587 | goto out_child; | ||
588 | } | ||
589 | |||
590 | if (have_tracepoints(&rec->evlist->entries)) { | ||
591 | /* | ||
592 | * FIXME err <= 0 here actually means that | ||
593 | * there were no tracepoints so its not really | ||
594 | * an error, just that we don't need to | ||
595 | * synthesize anything. We really have to | ||
596 | * return this more properly and also | ||
597 | * propagate errors that now are calling die() | ||
598 | */ | ||
599 | err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist, | ||
600 | process_synthesized_event); | ||
601 | if (err <= 0) { | ||
602 | pr_err("Couldn't record tracing data.\n"); | ||
603 | goto out_child; | ||
604 | } | ||
605 | rec->bytes_written += err; | ||
606 | } | ||
607 | } | ||
608 | |||
609 | if (rec->opts.full_auxtrace) { | ||
610 | err = perf_event__synthesize_auxtrace_info(rec->itr, tool, | ||
611 | session, process_synthesized_event); | ||
612 | if (err) | ||
613 | goto out_delete_session; | ||
614 | } | ||
615 | |||
616 | err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event, | ||
617 | machine); | ||
618 | if (err < 0) | ||
619 | pr_err("Couldn't record kernel reference relocation symbol\n" | ||
620 | "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" | ||
621 | "Check /proc/kallsyms permission or run as root.\n"); | ||
622 | |||
623 | err = perf_event__synthesize_modules(tool, process_synthesized_event, | ||
624 | machine); | ||
625 | if (err < 0) | 678 | if (err < 0) |
626 | pr_err("Couldn't record kernel module information.\n" | ||
627 | "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" | ||
628 | "Check /proc/modules permission or run as root.\n"); | ||
629 | |||
630 | if (perf_guest) { | ||
631 | machines__process_guests(&session->machines, | ||
632 | perf_event__synthesize_guest_os, tool); | ||
633 | } | ||
634 | |||
635 | err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads, | ||
636 | process_synthesized_event, opts->sample_address, | ||
637 | opts->proc_map_timeout); | ||
638 | if (err != 0) | ||
639 | goto out_child; | 679 | goto out_child; |
640 | 680 | ||
641 | if (rec->realtime_prio) { | 681 | if (rec->realtime_prio) { |
@@ -771,18 +811,8 @@ out_child: | |||
771 | /* this will be recalculated during process_buildids() */ | 811 | /* this will be recalculated during process_buildids() */ |
772 | rec->samples = 0; | 812 | rec->samples = 0; |
773 | 813 | ||
774 | if (!err && !file->is_pipe) { | 814 | if (!err) |
775 | rec->session->header.data_size += rec->bytes_written; | 815 | record__finish_output(rec); |
776 | file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR); | ||
777 | |||
778 | if (!rec->no_buildid) { | ||
779 | process_buildids(rec); | ||
780 | |||
781 | if (rec->buildid_all) | ||
782 | dsos__hit_all(rec->session); | ||
783 | } | ||
784 | perf_session__write_header(rec->session, rec->evlist, fd, true); | ||
785 | } | ||
786 | 816 | ||
787 | if (!err && !quiet) { | 817 | if (!err && !quiet) { |
788 | char samples[128]; | 818 | char samples[128]; |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 8c0bc0fe5179..baa82078c148 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -739,6 +739,9 @@ struct outstate { | |||
739 | FILE *fh; | 739 | FILE *fh; |
740 | bool newline; | 740 | bool newline; |
741 | const char *prefix; | 741 | const char *prefix; |
742 | int nfields; | ||
743 | int id, nr; | ||
744 | struct perf_evsel *evsel; | ||
742 | }; | 745 | }; |
743 | 746 | ||
744 | #define METRIC_LEN 35 | 747 | #define METRIC_LEN 35 |
@@ -754,12 +757,9 @@ static void do_new_line_std(struct outstate *os) | |||
754 | { | 757 | { |
755 | fputc('\n', os->fh); | 758 | fputc('\n', os->fh); |
756 | fputs(os->prefix, os->fh); | 759 | fputs(os->prefix, os->fh); |
760 | aggr_printout(os->evsel, os->id, os->nr); | ||
757 | if (stat_config.aggr_mode == AGGR_NONE) | 761 | if (stat_config.aggr_mode == AGGR_NONE) |
758 | fprintf(os->fh, " "); | 762 | fprintf(os->fh, " "); |
759 | if (stat_config.aggr_mode == AGGR_CORE) | ||
760 | fprintf(os->fh, " "); | ||
761 | if (stat_config.aggr_mode == AGGR_SOCKET) | ||
762 | fprintf(os->fh, " "); | ||
763 | fprintf(os->fh, " "); | 763 | fprintf(os->fh, " "); |
764 | } | 764 | } |
765 | 765 | ||
@@ -789,6 +789,44 @@ static void print_metric_std(void *ctx, const char *color, const char *fmt, | |||
789 | fprintf(out, " %-*s", METRIC_LEN - n - 1, unit); | 789 | fprintf(out, " %-*s", METRIC_LEN - n - 1, unit); |
790 | } | 790 | } |
791 | 791 | ||
792 | static void new_line_csv(void *ctx) | ||
793 | { | ||
794 | struct outstate *os = ctx; | ||
795 | int i; | ||
796 | |||
797 | fputc('\n', os->fh); | ||
798 | if (os->prefix) | ||
799 | fprintf(os->fh, "%s%s", os->prefix, csv_sep); | ||
800 | aggr_printout(os->evsel, os->id, os->nr); | ||
801 | for (i = 0; i < os->nfields; i++) | ||
802 | fputs(csv_sep, os->fh); | ||
803 | } | ||
804 | |||
805 | static void print_metric_csv(void *ctx, | ||
806 | const char *color __maybe_unused, | ||
807 | const char *fmt, const char *unit, double val) | ||
808 | { | ||
809 | struct outstate *os = ctx; | ||
810 | FILE *out = os->fh; | ||
811 | char buf[64], *vals, *ends; | ||
812 | |||
813 | if (unit == NULL || fmt == NULL) { | ||
814 | fprintf(out, "%s%s%s%s", csv_sep, csv_sep, csv_sep, csv_sep); | ||
815 | return; | ||
816 | } | ||
817 | snprintf(buf, sizeof(buf), fmt, val); | ||
818 | vals = buf; | ||
819 | while (isspace(*vals)) | ||
820 | vals++; | ||
821 | ends = vals; | ||
822 | while (isdigit(*ends) || *ends == '.') | ||
823 | ends++; | ||
824 | *ends = 0; | ||
825 | while (isspace(*unit)) | ||
826 | unit++; | ||
827 | fprintf(out, "%s%s%s%s", csv_sep, vals, csv_sep, unit); | ||
828 | } | ||
829 | |||
792 | static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg) | 830 | static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg) |
793 | { | 831 | { |
794 | FILE *output = stat_config.output; | 832 | FILE *output = stat_config.output; |
@@ -817,6 +855,28 @@ static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg) | |||
817 | fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); | 855 | fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); |
818 | } | 856 | } |
819 | 857 | ||
858 | static int first_shadow_cpu(struct perf_evsel *evsel, int id) | ||
859 | { | ||
860 | int i; | ||
861 | |||
862 | if (!aggr_get_id) | ||
863 | return 0; | ||
864 | |||
865 | if (stat_config.aggr_mode == AGGR_NONE) | ||
866 | return id; | ||
867 | |||
868 | if (stat_config.aggr_mode == AGGR_GLOBAL) | ||
869 | return 0; | ||
870 | |||
871 | for (i = 0; i < perf_evsel__nr_cpus(evsel); i++) { | ||
872 | int cpu2 = perf_evsel__cpus(evsel)->map[i]; | ||
873 | |||
874 | if (aggr_get_id(evsel_list->cpus, cpu2) == id) | ||
875 | return cpu2; | ||
876 | } | ||
877 | return 0; | ||
878 | } | ||
879 | |||
820 | static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg) | 880 | static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg) |
821 | { | 881 | { |
822 | FILE *output = stat_config.output; | 882 | FILE *output = stat_config.output; |
@@ -853,13 +913,32 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, | |||
853 | struct perf_stat_output_ctx out; | 913 | struct perf_stat_output_ctx out; |
854 | struct outstate os = { | 914 | struct outstate os = { |
855 | .fh = stat_config.output, | 915 | .fh = stat_config.output, |
856 | .prefix = prefix ? prefix : "" | 916 | .prefix = prefix ? prefix : "", |
917 | .id = id, | ||
918 | .nr = nr, | ||
919 | .evsel = counter, | ||
857 | }; | 920 | }; |
858 | print_metric_t pm = print_metric_std; | 921 | print_metric_t pm = print_metric_std; |
859 | void (*nl)(void *); | 922 | void (*nl)(void *); |
860 | 923 | ||
861 | nl = new_line_std; | 924 | nl = new_line_std; |
862 | 925 | ||
926 | if (csv_output) { | ||
927 | static int aggr_fields[] = { | ||
928 | [AGGR_GLOBAL] = 0, | ||
929 | [AGGR_THREAD] = 1, | ||
930 | [AGGR_NONE] = 1, | ||
931 | [AGGR_SOCKET] = 2, | ||
932 | [AGGR_CORE] = 2, | ||
933 | }; | ||
934 | |||
935 | pm = print_metric_csv; | ||
936 | nl = new_line_csv; | ||
937 | os.nfields = 3; | ||
938 | os.nfields += aggr_fields[stat_config.aggr_mode]; | ||
939 | if (counter->cgrp) | ||
940 | os.nfields++; | ||
941 | } | ||
863 | if (run == 0 || ena == 0 || counter->counts->scaled == -1) { | 942 | if (run == 0 || ena == 0 || counter->counts->scaled == -1) { |
864 | aggr_printout(counter, id, nr); | 943 | aggr_printout(counter, id, nr); |
865 | 944 | ||
@@ -880,7 +959,12 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, | |||
880 | fprintf(stat_config.output, "%s%s", | 959 | fprintf(stat_config.output, "%s%s", |
881 | csv_sep, counter->cgrp->name); | 960 | csv_sep, counter->cgrp->name); |
882 | 961 | ||
962 | if (!csv_output) | ||
963 | pm(&os, NULL, NULL, "", 0); | ||
964 | print_noise(counter, noise); | ||
883 | print_running(run, ena); | 965 | print_running(run, ena); |
966 | if (csv_output) | ||
967 | pm(&os, NULL, NULL, "", 0); | ||
884 | return; | 968 | return; |
885 | } | 969 | } |
886 | 970 | ||
@@ -893,14 +977,41 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, | |||
893 | out.new_line = nl; | 977 | out.new_line = nl; |
894 | out.ctx = &os; | 978 | out.ctx = &os; |
895 | 979 | ||
896 | if (!csv_output) | 980 | if (csv_output) { |
897 | perf_stat__print_shadow_stats(counter, uval, | 981 | print_noise(counter, noise); |
898 | stat_config.aggr_mode == AGGR_GLOBAL ? 0 : | 982 | print_running(run, ena); |
899 | cpu_map__id_to_cpu(id), | 983 | } |
984 | |||
985 | perf_stat__print_shadow_stats(counter, uval, | ||
986 | first_shadow_cpu(counter, id), | ||
900 | &out); | 987 | &out); |
988 | if (!csv_output) { | ||
989 | print_noise(counter, noise); | ||
990 | print_running(run, ena); | ||
991 | } | ||
992 | } | ||
993 | |||
994 | static void aggr_update_shadow(void) | ||
995 | { | ||
996 | int cpu, s2, id, s; | ||
997 | u64 val; | ||
998 | struct perf_evsel *counter; | ||
901 | 999 | ||
902 | print_noise(counter, noise); | 1000 | for (s = 0; s < aggr_map->nr; s++) { |
903 | print_running(run, ena); | 1001 | id = aggr_map->map[s]; |
1002 | evlist__for_each(evsel_list, counter) { | ||
1003 | val = 0; | ||
1004 | for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { | ||
1005 | s2 = aggr_get_id(evsel_list->cpus, cpu); | ||
1006 | if (s2 != id) | ||
1007 | continue; | ||
1008 | val += perf_counts(counter->counts, cpu, 0)->val; | ||
1009 | } | ||
1010 | val = val * counter->scale; | ||
1011 | perf_stat__update_shadow_stats(counter, &val, | ||
1012 | first_shadow_cpu(counter, id)); | ||
1013 | } | ||
1014 | } | ||
904 | } | 1015 | } |
905 | 1016 | ||
906 | static void print_aggr(char *prefix) | 1017 | static void print_aggr(char *prefix) |
@@ -914,6 +1025,8 @@ static void print_aggr(char *prefix) | |||
914 | if (!(aggr_map || aggr_get_id)) | 1025 | if (!(aggr_map || aggr_get_id)) |
915 | return; | 1026 | return; |
916 | 1027 | ||
1028 | aggr_update_shadow(); | ||
1029 | |||
917 | for (s = 0; s < aggr_map->nr; s++) { | 1030 | for (s = 0; s < aggr_map->nr; s++) { |
918 | id = aggr_map->map[s]; | 1031 | id = aggr_map->map[s]; |
919 | evlist__for_each(evsel_list, counter) { | 1032 | evlist__for_each(evsel_list, counter) { |
@@ -1441,7 +1554,7 @@ static int perf_stat_init_aggr_mode_file(struct perf_stat *st) | |||
1441 | */ | 1554 | */ |
1442 | static int add_default_attributes(void) | 1555 | static int add_default_attributes(void) |
1443 | { | 1556 | { |
1444 | struct perf_event_attr default_attrs[] = { | 1557 | struct perf_event_attr default_attrs0[] = { |
1445 | 1558 | ||
1446 | { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, | 1559 | { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, |
1447 | { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, | 1560 | { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, |
@@ -1449,8 +1562,14 @@ static int add_default_attributes(void) | |||
1449 | { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, | 1562 | { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, |
1450 | 1563 | ||
1451 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, | 1564 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, |
1565 | }; | ||
1566 | struct perf_event_attr frontend_attrs[] = { | ||
1452 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, | 1567 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, |
1568 | }; | ||
1569 | struct perf_event_attr backend_attrs[] = { | ||
1453 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, | 1570 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, |
1571 | }; | ||
1572 | struct perf_event_attr default_attrs1[] = { | ||
1454 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, | 1573 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, |
1455 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, | 1574 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, |
1456 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, | 1575 | { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, |
@@ -1567,7 +1686,19 @@ static int add_default_attributes(void) | |||
1567 | } | 1686 | } |
1568 | 1687 | ||
1569 | if (!evsel_list->nr_entries) { | 1688 | if (!evsel_list->nr_entries) { |
1570 | if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0) | 1689 | if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0) |
1690 | return -1; | ||
1691 | if (pmu_have_event("cpu", "stalled-cycles-frontend")) { | ||
1692 | if (perf_evlist__add_default_attrs(evsel_list, | ||
1693 | frontend_attrs) < 0) | ||
1694 | return -1; | ||
1695 | } | ||
1696 | if (pmu_have_event("cpu", "stalled-cycles-backend")) { | ||
1697 | if (perf_evlist__add_default_attrs(evsel_list, | ||
1698 | backend_attrs) < 0) | ||
1699 | return -1; | ||
1700 | } | ||
1701 | if (perf_evlist__add_default_attrs(evsel_list, default_attrs1) < 0) | ||
1571 | return -1; | 1702 | return -1; |
1572 | } | 1703 | } |
1573 | 1704 | ||
@@ -1835,6 +1966,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1835 | argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands, | 1966 | argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands, |
1836 | (const char **) stat_usage, | 1967 | (const char **) stat_usage, |
1837 | PARSE_OPT_STOP_AT_NON_OPTION); | 1968 | PARSE_OPT_STOP_AT_NON_OPTION); |
1969 | perf_stat__init_shadow_stats(); | ||
1838 | 1970 | ||
1839 | if (csv_sep) { | 1971 | if (csv_sep) { |
1840 | csv_output = true; | 1972 | csv_output = true; |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 26a337f939d8..8dc98c598b1a 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -1725,8 +1725,12 @@ static int trace__read_syscall_info(struct trace *trace, int id) | |||
1725 | 1725 | ||
1726 | sc->args = sc->tp_format->format.fields; | 1726 | sc->args = sc->tp_format->format.fields; |
1727 | sc->nr_args = sc->tp_format->format.nr_fields; | 1727 | sc->nr_args = sc->tp_format->format.nr_fields; |
1728 | /* drop nr field - not relevant here; does not exist on older kernels */ | 1728 | /* |
1729 | if (sc->args && strcmp(sc->args->name, "nr") == 0) { | 1729 | * We need to check and discard the first variable '__syscall_nr' |
1730 | * or 'nr' that mean the syscall number. It is needless here. | ||
1731 | * So drop '__syscall_nr' or 'nr' field but does not exist on older kernels. | ||
1732 | */ | ||
1733 | if (sc->args && (!strcmp(sc->args->name, "__syscall_nr") || !strcmp(sc->args->name, "nr"))) { | ||
1730 | sc->args = sc->args->next; | 1734 | sc->args = sc->args->next; |
1731 | --sc->nr_args; | 1735 | --sc->nr_args; |
1732 | } | 1736 | } |
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 6729f4d9df7c..811af89ce0bb 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c | |||
@@ -352,6 +352,84 @@ static int add_tracepoint_values(struct ctf_writer *cw, | |||
352 | return ret; | 352 | return ret; |
353 | } | 353 | } |
354 | 354 | ||
355 | static int | ||
356 | add_bpf_output_values(struct bt_ctf_event_class *event_class, | ||
357 | struct bt_ctf_event *event, | ||
358 | struct perf_sample *sample) | ||
359 | { | ||
360 | struct bt_ctf_field_type *len_type, *seq_type; | ||
361 | struct bt_ctf_field *len_field, *seq_field; | ||
362 | unsigned int raw_size = sample->raw_size; | ||
363 | unsigned int nr_elements = raw_size / sizeof(u32); | ||
364 | unsigned int i; | ||
365 | int ret; | ||
366 | |||
367 | if (nr_elements * sizeof(u32) != raw_size) | ||
368 | pr_warning("Incorrect raw_size (%u) in bpf output event, skip %lu bytes\n", | ||
369 | raw_size, nr_elements * sizeof(u32) - raw_size); | ||
370 | |||
371 | len_type = bt_ctf_event_class_get_field_by_name(event_class, "raw_len"); | ||
372 | len_field = bt_ctf_field_create(len_type); | ||
373 | if (!len_field) { | ||
374 | pr_err("failed to create 'raw_len' for bpf output event\n"); | ||
375 | ret = -1; | ||
376 | goto put_len_type; | ||
377 | } | ||
378 | |||
379 | ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements); | ||
380 | if (ret) { | ||
381 | pr_err("failed to set field value for raw_len\n"); | ||
382 | goto put_len_field; | ||
383 | } | ||
384 | ret = bt_ctf_event_set_payload(event, "raw_len", len_field); | ||
385 | if (ret) { | ||
386 | pr_err("failed to set payload to raw_len\n"); | ||
387 | goto put_len_field; | ||
388 | } | ||
389 | |||
390 | seq_type = bt_ctf_event_class_get_field_by_name(event_class, "raw_data"); | ||
391 | seq_field = bt_ctf_field_create(seq_type); | ||
392 | if (!seq_field) { | ||
393 | pr_err("failed to create 'raw_data' for bpf output event\n"); | ||
394 | ret = -1; | ||
395 | goto put_seq_type; | ||
396 | } | ||
397 | |||
398 | ret = bt_ctf_field_sequence_set_length(seq_field, len_field); | ||
399 | if (ret) { | ||
400 | pr_err("failed to set length of 'raw_data'\n"); | ||
401 | goto put_seq_field; | ||
402 | } | ||
403 | |||
404 | for (i = 0; i < nr_elements; i++) { | ||
405 | struct bt_ctf_field *elem_field = | ||
406 | bt_ctf_field_sequence_get_field(seq_field, i); | ||
407 | |||
408 | ret = bt_ctf_field_unsigned_integer_set_value(elem_field, | ||
409 | ((u32 *)(sample->raw_data))[i]); | ||
410 | |||
411 | bt_ctf_field_put(elem_field); | ||
412 | if (ret) { | ||
413 | pr_err("failed to set raw_data[%d]\n", i); | ||
414 | goto put_seq_field; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | ret = bt_ctf_event_set_payload(event, "raw_data", seq_field); | ||
419 | if (ret) | ||
420 | pr_err("failed to set payload for raw_data\n"); | ||
421 | |||
422 | put_seq_field: | ||
423 | bt_ctf_field_put(seq_field); | ||
424 | put_seq_type: | ||
425 | bt_ctf_field_type_put(seq_type); | ||
426 | put_len_field: | ||
427 | bt_ctf_field_put(len_field); | ||
428 | put_len_type: | ||
429 | bt_ctf_field_type_put(len_type); | ||
430 | return ret; | ||
431 | } | ||
432 | |||
355 | static int add_generic_values(struct ctf_writer *cw, | 433 | static int add_generic_values(struct ctf_writer *cw, |
356 | struct bt_ctf_event *event, | 434 | struct bt_ctf_event *event, |
357 | struct perf_evsel *evsel, | 435 | struct perf_evsel *evsel, |
@@ -597,6 +675,12 @@ static int process_sample_event(struct perf_tool *tool, | |||
597 | return -1; | 675 | return -1; |
598 | } | 676 | } |
599 | 677 | ||
678 | if (perf_evsel__is_bpf_output(evsel)) { | ||
679 | ret = add_bpf_output_values(event_class, event, sample); | ||
680 | if (ret) | ||
681 | return -1; | ||
682 | } | ||
683 | |||
600 | cs = ctf_stream(cw, get_sample_cpu(cw, sample, evsel)); | 684 | cs = ctf_stream(cw, get_sample_cpu(cw, sample, evsel)); |
601 | if (cs) { | 685 | if (cs) { |
602 | if (is_flush_needed(cs)) | 686 | if (is_flush_needed(cs)) |
@@ -744,6 +828,25 @@ static int add_tracepoint_types(struct ctf_writer *cw, | |||
744 | return ret; | 828 | return ret; |
745 | } | 829 | } |
746 | 830 | ||
831 | static int add_bpf_output_types(struct ctf_writer *cw, | ||
832 | struct bt_ctf_event_class *class) | ||
833 | { | ||
834 | struct bt_ctf_field_type *len_type = cw->data.u32; | ||
835 | struct bt_ctf_field_type *seq_base_type = cw->data.u32_hex; | ||
836 | struct bt_ctf_field_type *seq_type; | ||
837 | int ret; | ||
838 | |||
839 | ret = bt_ctf_event_class_add_field(class, len_type, "raw_len"); | ||
840 | if (ret) | ||
841 | return ret; | ||
842 | |||
843 | seq_type = bt_ctf_field_type_sequence_create(seq_base_type, "raw_len"); | ||
844 | if (!seq_type) | ||
845 | return -1; | ||
846 | |||
847 | return bt_ctf_event_class_add_field(class, seq_type, "raw_data"); | ||
848 | } | ||
849 | |||
747 | static int add_generic_types(struct ctf_writer *cw, struct perf_evsel *evsel, | 850 | static int add_generic_types(struct ctf_writer *cw, struct perf_evsel *evsel, |
748 | struct bt_ctf_event_class *event_class) | 851 | struct bt_ctf_event_class *event_class) |
749 | { | 852 | { |
@@ -755,7 +858,8 @@ static int add_generic_types(struct ctf_writer *cw, struct perf_evsel *evsel, | |||
755 | * ctf event header | 858 | * ctf event header |
756 | * PERF_SAMPLE_READ - TODO | 859 | * PERF_SAMPLE_READ - TODO |
757 | * PERF_SAMPLE_CALLCHAIN - TODO | 860 | * PERF_SAMPLE_CALLCHAIN - TODO |
758 | * PERF_SAMPLE_RAW - tracepoint fields are handled separately | 861 | * PERF_SAMPLE_RAW - tracepoint fields and BPF output |
862 | * are handled separately | ||
759 | * PERF_SAMPLE_BRANCH_STACK - TODO | 863 | * PERF_SAMPLE_BRANCH_STACK - TODO |
760 | * PERF_SAMPLE_REGS_USER - TODO | 864 | * PERF_SAMPLE_REGS_USER - TODO |
761 | * PERF_SAMPLE_STACK_USER - TODO | 865 | * PERF_SAMPLE_STACK_USER - TODO |
@@ -824,6 +928,12 @@ static int add_event(struct ctf_writer *cw, struct perf_evsel *evsel) | |||
824 | goto err; | 928 | goto err; |
825 | } | 929 | } |
826 | 930 | ||
931 | if (perf_evsel__is_bpf_output(evsel)) { | ||
932 | ret = add_bpf_output_types(cw, event_class); | ||
933 | if (ret) | ||
934 | goto err; | ||
935 | } | ||
936 | |||
827 | ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class); | 937 | ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class); |
828 | if (ret) { | 938 | if (ret) { |
829 | pr("Failed to add event class into stream.\n"); | 939 | pr("Failed to add event class into stream.\n"); |
@@ -970,6 +1080,12 @@ static struct bt_ctf_field_type *create_int_type(int size, bool sign, bool hex) | |||
970 | bt_ctf_field_type_integer_set_base(type, BT_CTF_INTEGER_BASE_HEXADECIMAL)) | 1080 | bt_ctf_field_type_integer_set_base(type, BT_CTF_INTEGER_BASE_HEXADECIMAL)) |
971 | goto err; | 1081 | goto err; |
972 | 1082 | ||
1083 | #if __BYTE_ORDER == __BIG_ENDIAN | ||
1084 | bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_BIG_ENDIAN); | ||
1085 | #else | ||
1086 | bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN); | ||
1087 | #endif | ||
1088 | |||
973 | pr2("Created type: INTEGER %d-bit %ssigned %s\n", | 1089 | pr2("Created type: INTEGER %d-bit %ssigned %s\n", |
974 | size, sign ? "un" : "", hex ? "hex" : ""); | 1090 | size, sign ? "un" : "", hex ? "hex" : ""); |
975 | return type; | 1091 | return type; |
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index ce61f79dbaae..d8cd038baed2 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
@@ -124,6 +124,17 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char * | |||
124 | lc = setlocale(LC_NUMERIC, NULL); | 124 | lc = setlocale(LC_NUMERIC, NULL); |
125 | 125 | ||
126 | /* | 126 | /* |
127 | * The lc string may be allocated in static storage, | ||
128 | * so get a dynamic copy to make it survive setlocale | ||
129 | * call below. | ||
130 | */ | ||
131 | lc = strdup(lc); | ||
132 | if (!lc) { | ||
133 | ret = -ENOMEM; | ||
134 | goto error; | ||
135 | } | ||
136 | |||
137 | /* | ||
127 | * force to C locale to ensure kernel | 138 | * force to C locale to ensure kernel |
128 | * scale string is converted correctly. | 139 | * scale string is converted correctly. |
129 | * kernel uses default C locale. | 140 | * kernel uses default C locale. |
@@ -135,6 +146,8 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char * | |||
135 | /* restore locale */ | 146 | /* restore locale */ |
136 | setlocale(LC_NUMERIC, lc); | 147 | setlocale(LC_NUMERIC, lc); |
137 | 148 | ||
149 | free((char *) lc); | ||
150 | |||
138 | ret = 0; | 151 | ret = 0; |
139 | error: | 152 | error: |
140 | close(fd); | 153 | close(fd); |
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 309d90fa7698..fbd05242b4e5 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
@@ -1094,8 +1094,6 @@ static int python_start_script(const char *script, int argc, const char **argv) | |||
1094 | goto error; | 1094 | goto error; |
1095 | } | 1095 | } |
1096 | 1096 | ||
1097 | free(command_line); | ||
1098 | |||
1099 | set_table_handlers(tables); | 1097 | set_table_handlers(tables); |
1100 | 1098 | ||
1101 | if (tables->db_export_mode) { | 1099 | if (tables->db_export_mode) { |
@@ -1104,6 +1102,8 @@ static int python_start_script(const char *script, int argc, const char **argv) | |||
1104 | goto error; | 1102 | goto error; |
1105 | } | 1103 | } |
1106 | 1104 | ||
1105 | free(command_line); | ||
1106 | |||
1107 | return err; | 1107 | return err; |
1108 | error: | 1108 | error: |
1109 | Py_Finalize(); | 1109 | Py_Finalize(); |
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index 1833103768cb..c8680984d2d6 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py | |||
@@ -22,6 +22,7 @@ cflags = getenv('CFLAGS', '').split() | |||
22 | # switch off several checks (need to be at the end of cflags list) | 22 | # switch off several checks (need to be at the end of cflags list) |
23 | cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ] | 23 | cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ] |
24 | 24 | ||
25 | src_perf = getenv('srctree') + '/tools/perf' | ||
25 | build_lib = getenv('PYTHON_EXTBUILD_LIB') | 26 | build_lib = getenv('PYTHON_EXTBUILD_LIB') |
26 | build_tmp = getenv('PYTHON_EXTBUILD_TMP') | 27 | build_tmp = getenv('PYTHON_EXTBUILD_TMP') |
27 | libtraceevent = getenv('LIBTRACEEVENT') | 28 | libtraceevent = getenv('LIBTRACEEVENT') |
@@ -30,6 +31,9 @@ libapikfs = getenv('LIBAPI') | |||
30 | ext_sources = [f.strip() for f in file('util/python-ext-sources') | 31 | ext_sources = [f.strip() for f in file('util/python-ext-sources') |
31 | if len(f.strip()) > 0 and f[0] != '#'] | 32 | if len(f.strip()) > 0 and f[0] != '#'] |
32 | 33 | ||
34 | # use full paths with source files | ||
35 | ext_sources = map(lambda x: '%s/%s' % (src_perf, x) , ext_sources) | ||
36 | |||
33 | perf = Extension('perf', | 37 | perf = Extension('perf', |
34 | sources = ext_sources, | 38 | sources = ext_sources, |
35 | include_dirs = ['util/include'], | 39 | include_dirs = ['util/include'], |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 5888bfe9a193..4380a2858802 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -2635,25 +2635,14 @@ out: | |||
2635 | return ret; | 2635 | return ret; |
2636 | } | 2636 | } |
2637 | 2637 | ||
2638 | int setup_sorting(struct perf_evlist *evlist) | 2638 | static void evlist__set_hists_nr_sort_keys(struct perf_evlist *evlist) |
2639 | { | 2639 | { |
2640 | int err; | ||
2641 | struct hists *hists; | ||
2642 | struct perf_evsel *evsel; | 2640 | struct perf_evsel *evsel; |
2643 | struct perf_hpp_fmt *fmt; | ||
2644 | |||
2645 | err = __setup_sorting(evlist); | ||
2646 | if (err < 0) | ||
2647 | return err; | ||
2648 | |||
2649 | if (parent_pattern != default_parent_pattern) { | ||
2650 | err = sort_dimension__add("parent", evlist); | ||
2651 | if (err < 0) | ||
2652 | return err; | ||
2653 | } | ||
2654 | 2641 | ||
2655 | evlist__for_each(evlist, evsel) { | 2642 | evlist__for_each(evlist, evsel) { |
2656 | hists = evsel__hists(evsel); | 2643 | struct perf_hpp_fmt *fmt; |
2644 | struct hists *hists = evsel__hists(evsel); | ||
2645 | |||
2657 | hists->nr_sort_keys = perf_hpp_list.nr_sort_keys; | 2646 | hists->nr_sort_keys = perf_hpp_list.nr_sort_keys; |
2658 | 2647 | ||
2659 | /* | 2648 | /* |
@@ -2667,6 +2656,24 @@ int setup_sorting(struct perf_evlist *evlist) | |||
2667 | hists->nr_sort_keys--; | 2656 | hists->nr_sort_keys--; |
2668 | } | 2657 | } |
2669 | } | 2658 | } |
2659 | } | ||
2660 | |||
2661 | int setup_sorting(struct perf_evlist *evlist) | ||
2662 | { | ||
2663 | int err; | ||
2664 | |||
2665 | err = __setup_sorting(evlist); | ||
2666 | if (err < 0) | ||
2667 | return err; | ||
2668 | |||
2669 | if (parent_pattern != default_parent_pattern) { | ||
2670 | err = sort_dimension__add("parent", evlist); | ||
2671 | if (err < 0) | ||
2672 | return err; | ||
2673 | } | ||
2674 | |||
2675 | if (evlist != NULL) | ||
2676 | evlist__set_hists_nr_sort_keys(evlist); | ||
2670 | 2677 | ||
2671 | reset_dimensions(); | 2678 | reset_dimensions(); |
2672 | 2679 | ||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 4d8f18581b9b..b33ffb2af2cf 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include "evsel.h" | 2 | #include "evsel.h" |
3 | #include "stat.h" | 3 | #include "stat.h" |
4 | #include "color.h" | 4 | #include "color.h" |
5 | #include "pmu.h" | ||
5 | 6 | ||
6 | enum { | 7 | enum { |
7 | CTX_BIT_USER = 1 << 0, | 8 | CTX_BIT_USER = 1 << 0, |
@@ -14,6 +15,13 @@ enum { | |||
14 | 15 | ||
15 | #define NUM_CTX CTX_BIT_MAX | 16 | #define NUM_CTX CTX_BIT_MAX |
16 | 17 | ||
18 | /* | ||
19 | * AGGR_GLOBAL: Use CPU 0 | ||
20 | * AGGR_SOCKET: Use first CPU of socket | ||
21 | * AGGR_CORE: Use first CPU of core | ||
22 | * AGGR_NONE: Use matching CPU | ||
23 | * AGGR_THREAD: Not supported? | ||
24 | */ | ||
17 | static struct stats runtime_nsecs_stats[MAX_NR_CPUS]; | 25 | static struct stats runtime_nsecs_stats[MAX_NR_CPUS]; |
18 | static struct stats runtime_cycles_stats[NUM_CTX][MAX_NR_CPUS]; | 26 | static struct stats runtime_cycles_stats[NUM_CTX][MAX_NR_CPUS]; |
19 | static struct stats runtime_stalled_cycles_front_stats[NUM_CTX][MAX_NR_CPUS]; | 27 | static struct stats runtime_stalled_cycles_front_stats[NUM_CTX][MAX_NR_CPUS]; |
@@ -28,9 +36,15 @@ static struct stats runtime_dtlb_cache_stats[NUM_CTX][MAX_NR_CPUS]; | |||
28 | static struct stats runtime_cycles_in_tx_stats[NUM_CTX][MAX_NR_CPUS]; | 36 | static struct stats runtime_cycles_in_tx_stats[NUM_CTX][MAX_NR_CPUS]; |
29 | static struct stats runtime_transaction_stats[NUM_CTX][MAX_NR_CPUS]; | 37 | static struct stats runtime_transaction_stats[NUM_CTX][MAX_NR_CPUS]; |
30 | static struct stats runtime_elision_stats[NUM_CTX][MAX_NR_CPUS]; | 38 | static struct stats runtime_elision_stats[NUM_CTX][MAX_NR_CPUS]; |
39 | static bool have_frontend_stalled; | ||
31 | 40 | ||
32 | struct stats walltime_nsecs_stats; | 41 | struct stats walltime_nsecs_stats; |
33 | 42 | ||
43 | void perf_stat__init_shadow_stats(void) | ||
44 | { | ||
45 | have_frontend_stalled = pmu_have_event("cpu", "stalled-cycles-frontend"); | ||
46 | } | ||
47 | |||
34 | static int evsel_context(struct perf_evsel *evsel) | 48 | static int evsel_context(struct perf_evsel *evsel) |
35 | { | 49 | { |
36 | int ctx = 0; | 50 | int ctx = 0; |
@@ -310,13 +324,13 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel, | |||
310 | total = avg_stats(&runtime_stalled_cycles_front_stats[ctx][cpu]); | 324 | total = avg_stats(&runtime_stalled_cycles_front_stats[ctx][cpu]); |
311 | total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[ctx][cpu])); | 325 | total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[ctx][cpu])); |
312 | 326 | ||
313 | out->new_line(ctxp); | ||
314 | if (total && avg) { | 327 | if (total && avg) { |
328 | out->new_line(ctxp); | ||
315 | ratio = total / avg; | 329 | ratio = total / avg; |
316 | print_metric(ctxp, NULL, "%7.2f ", | 330 | print_metric(ctxp, NULL, "%7.2f ", |
317 | "stalled cycles per insn", | 331 | "stalled cycles per insn", |
318 | ratio); | 332 | ratio); |
319 | } else { | 333 | } else if (have_frontend_stalled) { |
320 | print_metric(ctxp, NULL, NULL, | 334 | print_metric(ctxp, NULL, NULL, |
321 | "stalled cycles per insn", 0); | 335 | "stalled cycles per insn", 0); |
322 | } | 336 | } |
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index f02af68adc04..0150e786ccc7 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h | |||
@@ -72,6 +72,7 @@ typedef void (*print_metric_t)(void *ctx, const char *color, const char *unit, | |||
72 | const char *fmt, double val); | 72 | const char *fmt, double val); |
73 | typedef void (*new_line_t )(void *ctx); | 73 | typedef void (*new_line_t )(void *ctx); |
74 | 74 | ||
75 | void perf_stat__init_shadow_stats(void); | ||
75 | void perf_stat__reset_shadow_stats(void); | 76 | void perf_stat__reset_shadow_stats(void); |
76 | void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count, | 77 | void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count, |
77 | int cpu); | 78 | int cpu); |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 0dac7e05a6ac..3fa94e291d16 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -1970,7 +1970,7 @@ int has_config_tdp(unsigned int family, unsigned int model) | |||
1970 | } | 1970 | } |
1971 | 1971 | ||
1972 | static void | 1972 | static void |
1973 | dump_cstate_pstate_config_info(family, model) | 1973 | dump_cstate_pstate_config_info(unsigned int family, unsigned int model) |
1974 | { | 1974 | { |
1975 | if (!do_nhm_platform_info) | 1975 | if (!do_nhm_platform_info) |
1976 | return; | 1976 | return; |
@@ -2142,7 +2142,7 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data | |||
2142 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ | 2142 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ |
2143 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ | 2143 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ |
2144 | 2144 | ||
2145 | double get_tdp(model) | 2145 | double get_tdp(unsigned int model) |
2146 | { | 2146 | { |
2147 | unsigned long long msr; | 2147 | unsigned long long msr; |
2148 | 2148 | ||
@@ -2256,7 +2256,7 @@ void rapl_probe(unsigned int family, unsigned int model) | |||
2256 | return; | 2256 | return; |
2257 | } | 2257 | } |
2258 | 2258 | ||
2259 | void perf_limit_reasons_probe(family, model) | 2259 | void perf_limit_reasons_probe(unsigned int family, unsigned int model) |
2260 | { | 2260 | { |
2261 | if (!genuine_intel) | 2261 | if (!genuine_intel) |
2262 | return; | 2262 | return; |
@@ -2792,7 +2792,7 @@ void process_cpuid() | |||
2792 | perf_limit_reasons_probe(family, model); | 2792 | perf_limit_reasons_probe(family, model); |
2793 | 2793 | ||
2794 | if (debug) | 2794 | if (debug) |
2795 | dump_cstate_pstate_config_info(); | 2795 | dump_cstate_pstate_config_info(family, model); |
2796 | 2796 | ||
2797 | if (has_skl_msrs(family, model)) | 2797 | if (has_skl_msrs(family, model)) |
2798 | calculate_tsc_tweak(); | 2798 | calculate_tsc_tweak(); |