Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'perf-tools-fixes-2021-01-17' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

Pull perf tools fixes from Arnaldo Carvalho de Melo:

- Fix 'CPU too large' error in Intel PT

- Correct event attribute sizes in 'perf inject'

- Sync build_bug.h and kvm.h kernel copies

- Fix bpf.h header include directive in 5sec.c 'perf trace' bpf example

- libbpf tests fixes

- Fix shadow stat 'perf test' for non-bash shells

- Take cgroups into account for shadow stats in 'perf stat'

* tag 'perf-tools-fixes-2021-01-17' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux:
perf inject: Correct event attribute sizes
perf intel-pt: Fix 'CPU too large' error
perf stat: Take cgroups into account for shadow stats
perf stat: Introduce struct runtime_stat_data
libperf tests: Fail when failing to get a tracepoint id
libperf tests: If a test fails return non-zero
libperf tests: Avoid uninitialized variable warning
perf test: Fix shadow stat test for non-bash shells
tools headers: Syncronize linux/build_bug.h with the kernel sources
tools headers UAPI: Sync kvm.h headers with the kernel sources
perf bpf examples: Fix bpf.h header include directive in 5sec.c example

+224 -208
-5
tools/include/linux/build_bug.h
··· 79 79 #define __static_assert(expr, msg, ...) _Static_assert(expr, msg) 80 80 #endif // static_assert 81 81 82 - #ifdef __GENKSYMS__ 83 - /* genksyms gets confused by _Static_assert */ 84 - #define _Static_assert(expr, ...) 85 - #endif 86 - 87 82 #endif /* _LINUX_BUILD_BUG_H */
+2
tools/include/uapi/linux/kvm.h
··· 251 251 #define KVM_EXIT_X86_RDMSR 29 252 252 #define KVM_EXIT_X86_WRMSR 30 253 253 #define KVM_EXIT_DIRTY_RING_FULL 31 254 + #define KVM_EXIT_AP_RESET_HOLD 32 254 255 255 256 /* For KVM_EXIT_INTERNAL_ERROR */ 256 257 /* Emulate instruction failed. */ ··· 574 573 #define KVM_MP_STATE_CHECK_STOP 6 575 574 #define KVM_MP_STATE_OPERATING 7 576 575 #define KVM_MP_STATE_LOAD 8 576 + #define KVM_MP_STATE_AP_RESET_HOLD 9 577 577 578 578 struct kvm_mp_state { 579 579 __u32 mp_state;
+1 -1
tools/lib/perf/tests/test-cpumap.c
··· 27 27 perf_cpu_map__put(cpus); 28 28 29 29 __T_END; 30 - return 0; 30 + return tests_failed == 0 ? 0 : -1; 31 31 }
+4 -3
tools/lib/perf/tests/test-evlist.c
··· 208 208 char path[PATH_MAX]; 209 209 int id, err, pid, go_pipe[2]; 210 210 union perf_event *event; 211 - char bf; 212 211 int count = 0; 213 212 214 213 snprintf(path, PATH_MAX, "%s/kernel/debug/tracing/events/syscalls/sys_enter_prctl/id", 215 214 sysfs__mountpoint()); 216 215 217 216 if (filename__read_int(path, &id)) { 217 + tests_failed++; 218 218 fprintf(stderr, "error: failed to get tracepoint id: %s\n", path); 219 219 return -1; 220 220 } ··· 229 229 pid = fork(); 230 230 if (!pid) { 231 231 int i; 232 + char bf; 232 233 233 234 read(go_pipe[0], &bf, 1); 234 235 ··· 267 266 perf_evlist__enable(evlist); 268 267 269 268 /* kick the child and wait for it to finish */ 270 - write(go_pipe[1], &bf, 1); 269 + write(go_pipe[1], "A", 1); 271 270 waitpid(pid, NULL, 0); 272 271 273 272 /* ··· 410 409 test_mmap_cpus(); 411 410 412 411 __T_END; 413 - return 0; 412 + return tests_failed == 0 ? 0 : -1; 414 413 }
+1 -1
tools/lib/perf/tests/test-evsel.c
··· 131 131 test_stat_thread_enable(); 132 132 133 133 __T_END; 134 - return 0; 134 + return tests_failed == 0 ? 0 : -1; 135 135 }
+1 -1
tools/lib/perf/tests/test-threadmap.c
··· 27 27 perf_thread_map__put(threads); 28 28 29 29 __T_END; 30 - return 0; 30 + return tests_failed == 0 ? 0 : -1; 31 31 }
+1 -1
tools/perf/examples/bpf/5sec.c
··· 39 39 Copyright (C) 2018 Red Hat, Inc., Arnaldo Carvalho de Melo <acme@redhat.com> 40 40 */ 41 41 42 - #include <bpf/bpf.h> 42 + #include <bpf.h> 43 43 44 44 #define NSEC_PER_SEC 1000000000L 45 45
+14 -16
tools/perf/tests/shell/stat+shadow_stat.sh
··· 9 9 10 10 test_global_aggr() 11 11 { 12 - local cyc 13 - 14 12 perf stat -a --no-big-num -e cycles,instructions sleep 1 2>&1 | \ 15 13 grep -e cycles -e instructions | \ 16 14 while read num evt hash ipc rest 17 15 do 18 16 # skip not counted events 19 - if [[ $num == "<not" ]]; then 17 + if [ "$num" = "<not" ]; then 20 18 continue 21 19 fi 22 20 23 21 # save cycles count 24 - if [[ $evt == "cycles" ]]; then 22 + if [ "$evt" = "cycles" ]; then 25 23 cyc=$num 26 24 continue 27 25 fi 28 26 29 27 # skip if no cycles 30 - if [[ -z $cyc ]]; then 28 + if [ -z "$cyc" ]; then 31 29 continue 32 30 fi 33 31 34 32 # use printf for rounding and a leading zero 35 - local res=`printf "%.2f" $(echo "scale=6; $num / $cyc" | bc -q)` 36 - if [[ $ipc != $res ]]; then 33 + res=`printf "%.2f" $(echo "scale=6; $num / $cyc" | bc -q)` 34 + if [ "$ipc" != "$res" ]; then 37 35 echo "IPC is different: $res != $ipc ($num / $cyc)" 38 36 exit 1 39 37 fi ··· 40 42 41 43 test_no_aggr() 42 44 { 43 - declare -A results 44 - 45 45 perf stat -a -A --no-big-num -e cycles,instructions sleep 1 2>&1 | \ 46 46 grep ^CPU | \ 47 47 while read cpu num evt hash ipc rest 48 48 do 49 49 # skip not counted events 50 - if [[ $num == "<not" ]]; then 50 + if [ "$num" = "<not" ]; then 51 51 continue 52 52 fi 53 53 54 54 # save cycles count 55 - if [[ $evt == "cycles" ]]; then 56 - results[$cpu]=$num 55 + if [ "$evt" = "cycles" ]; then 56 + results="$results $cpu:$num" 57 57 continue 58 58 fi 59 59 60 + cyc=${results##* $cpu:} 61 + cyc=${cyc%% *} 62 + 60 63 # skip if no cycles 61 - local cyc=${results[$cpu]} 62 - if [[ -z $cyc ]]; then 64 + if [ -z "$cyc" ]; then 63 65 continue 64 66 fi 65 67 66 68 # use printf for rounding and a leading zero 67 - local res=`printf "%.2f" $(echo "scale=6; $num / $cyc" | bc -q)` 68 - if [[ $ipc != $res ]]; then 69 + res=`printf "%.2f" $(echo "scale=6; $num / $cyc" | bc -q)` 70 + if [ "$ipc" != "$res" ]; then 69 71 echo "IPC is different for $cpu: $res != $ipc ($num / $cyc)" 70 72 exit 1 71 73 fi
+8
tools/perf/util/header.c
··· 3323 3323 attr_offset = lseek(ff.fd, 0, SEEK_CUR); 3324 3324 3325 3325 evlist__for_each_entry(evlist, evsel) { 3326 + if (evsel->core.attr.size < sizeof(evsel->core.attr)) { 3327 + /* 3328 + * We are likely in "perf inject" and have read 3329 + * from an older file. Update attr size so that 3330 + * reader gets the right offset to the ids. 3331 + */ 3332 + evsel->core.attr.size = sizeof(evsel->core.attr); 3333 + } 3326 3334 f_attr = (struct perf_file_attr){ 3327 3335 .attr = evsel->core.attr, 3328 3336 .ids = {
+2 -2
tools/perf/util/machine.c
··· 2980 2980 2981 2981 pid_t machine__get_current_tid(struct machine *machine, int cpu) 2982 2982 { 2983 - int nr_cpus = min(machine->env->nr_cpus_online, MAX_NR_CPUS); 2983 + int nr_cpus = min(machine->env->nr_cpus_avail, MAX_NR_CPUS); 2984 2984 2985 2985 if (cpu < 0 || cpu >= nr_cpus || !machine->current_tid) 2986 2986 return -1; ··· 2992 2992 pid_t tid) 2993 2993 { 2994 2994 struct thread *thread; 2995 - int nr_cpus = min(machine->env->nr_cpus_online, MAX_NR_CPUS); 2995 + int nr_cpus = min(machine->env->nr_cpus_avail, MAX_NR_CPUS); 2996 2996 2997 2997 if (cpu < 0) 2998 2998 return -EINVAL;
+1 -1
tools/perf/util/session.c
··· 2404 2404 { 2405 2405 int i, err = -1; 2406 2406 struct perf_cpu_map *map; 2407 - int nr_cpus = min(session->header.env.nr_cpus_online, MAX_NR_CPUS); 2407 + int nr_cpus = min(session->header.env.nr_cpus_avail, MAX_NR_CPUS); 2408 2408 2409 2409 for (i = 0; i < PERF_TYPE_MAX; ++i) { 2410 2410 struct evsel *evsel;
+189 -177
tools/perf/util/stat-shadow.c
··· 8 8 #include "evlist.h" 9 9 #include "expr.h" 10 10 #include "metricgroup.h" 11 + #include "cgroup.h" 11 12 #include <linux/zalloc.h> 12 13 13 14 /* ··· 29 28 enum stat_type type; 30 29 int ctx; 31 30 int cpu; 31 + struct cgroup *cgrp; 32 32 struct runtime_stat *stat; 33 33 struct stats stats; 34 34 u64 metric_total; ··· 58 56 59 57 if (a->ctx != b->ctx) 60 58 return a->ctx - b->ctx; 59 + 60 + if (a->cgrp != b->cgrp) 61 + return (char *)a->cgrp < (char *)b->cgrp ? -1 : +1; 61 62 62 63 if (a->evsel == NULL && b->evsel == NULL) { 63 64 if (a->stat == b->stat) ··· 105 100 bool create, 106 101 enum stat_type type, 107 102 int ctx, 108 - struct runtime_stat *st) 103 + struct runtime_stat *st, 104 + struct cgroup *cgrp) 109 105 { 110 106 struct rblist *rblist; 111 107 struct rb_node *nd; ··· 116 110 .type = type, 117 111 .ctx = ctx, 118 112 .stat = st, 113 + .cgrp = cgrp, 119 114 }; 120 115 121 116 rblist = &st->value_list; 117 + 118 + /* don't use context info for clock events */ 119 + if (type == STAT_NSECS) 120 + dm.ctx = 0; 122 121 123 122 nd = rblist__find(rblist, &dm); 124 123 if (nd) ··· 202 191 reset_stat(st); 203 192 } 204 193 194 + struct runtime_stat_data { 195 + int ctx; 196 + struct cgroup *cgrp; 197 + }; 198 + 205 199 static void update_runtime_stat(struct runtime_stat *st, 206 200 enum stat_type type, 207 - int ctx, int cpu, u64 count) 201 + int cpu, u64 count, 202 + struct runtime_stat_data *rsd) 208 203 { 209 - struct saved_value *v = saved_value_lookup(NULL, cpu, true, 210 - type, ctx, st); 204 + struct saved_value *v = saved_value_lookup(NULL, cpu, true, type, 205 + rsd->ctx, st, rsd->cgrp); 211 206 212 207 if (v) 213 208 update_stats(&v->stats, count); ··· 227 210 void perf_stat__update_shadow_stats(struct evsel *counter, u64 count, 228 211 int cpu, struct runtime_stat *st) 229 212 { 230 - int ctx = evsel_context(counter); 231 213 u64 count_ns = count; 232 214 struct saved_value *v; 215 + struct runtime_stat_data rsd = { 216 + .ctx = evsel_context(counter), 217 + .cgrp = counter->cgrp, 218 + }; 233 219 234 220 count *= counter->scale; 235 221 236 222 if (evsel__is_clock(counter)) 237 - update_runtime_stat(st, STAT_NSECS, 0, cpu, count_ns); 223 + update_runtime_stat(st, STAT_NSECS, cpu, count_ns, &rsd); 238 224 else if (evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) 239 - update_runtime_stat(st, STAT_CYCLES, ctx, cpu, count); 225 + update_runtime_stat(st, STAT_CYCLES, cpu, count, &rsd); 240 226 else if (perf_stat_evsel__is(counter, CYCLES_IN_TX)) 241 - update_runtime_stat(st, STAT_CYCLES_IN_TX, ctx, cpu, count); 227 + update_runtime_stat(st, STAT_CYCLES_IN_TX, cpu, count, &rsd); 242 228 else if (perf_stat_evsel__is(counter, TRANSACTION_START)) 243 - update_runtime_stat(st, STAT_TRANSACTION, ctx, cpu, count); 229 + update_runtime_stat(st, STAT_TRANSACTION, cpu, count, &rsd); 244 230 else if (perf_stat_evsel__is(counter, ELISION_START)) 245 - update_runtime_stat(st, STAT_ELISION, ctx, cpu, count); 231 + update_runtime_stat(st, STAT_ELISION, cpu, count, &rsd); 246 232 else if (perf_stat_evsel__is(counter, TOPDOWN_TOTAL_SLOTS)) 247 233 update_runtime_stat(st, STAT_TOPDOWN_TOTAL_SLOTS, 248 - ctx, cpu, count); 234 + cpu, count, &rsd); 249 235 else if (perf_stat_evsel__is(counter, TOPDOWN_SLOTS_ISSUED)) 250 236 update_runtime_stat(st, STAT_TOPDOWN_SLOTS_ISSUED, 251 - ctx, cpu, count); 237 + cpu, count, &rsd); 252 238 else if (perf_stat_evsel__is(counter, TOPDOWN_SLOTS_RETIRED)) 253 239 update_runtime_stat(st, STAT_TOPDOWN_SLOTS_RETIRED, 254 - ctx, cpu, count); 240 + cpu, count, &rsd); 255 241 else if (perf_stat_evsel__is(counter, TOPDOWN_FETCH_BUBBLES)) 256 242 update_runtime_stat(st, STAT_TOPDOWN_FETCH_BUBBLES, 257 - ctx, cpu, count); 243 + cpu, count, &rsd); 258 244 else if (perf_stat_evsel__is(counter, TOPDOWN_RECOVERY_BUBBLES)) 259 245 update_runtime_stat(st, STAT_TOPDOWN_RECOVERY_BUBBLES, 260 - ctx, cpu, count); 246 + cpu, count, &rsd); 261 247 else if (perf_stat_evsel__is(counter, TOPDOWN_RETIRING)) 262 248 update_runtime_stat(st, STAT_TOPDOWN_RETIRING, 263 - ctx, cpu, count); 249 + cpu, count, &rsd); 264 250 else if (perf_stat_evsel__is(counter, TOPDOWN_BAD_SPEC)) 265 251 update_runtime_stat(st, STAT_TOPDOWN_BAD_SPEC, 266 - ctx, cpu, count); 252 + cpu, count, &rsd); 267 253 else if (perf_stat_evsel__is(counter, TOPDOWN_FE_BOUND)) 268 254 update_runtime_stat(st, STAT_TOPDOWN_FE_BOUND, 269 - ctx, cpu, count); 255 + cpu, count, &rsd); 270 256 else if (perf_stat_evsel__is(counter, TOPDOWN_BE_BOUND)) 271 257 update_runtime_stat(st, STAT_TOPDOWN_BE_BOUND, 272 - ctx, cpu, count); 258 + cpu, count, &rsd); 273 259 else if (evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) 274 260 update_runtime_stat(st, STAT_STALLED_CYCLES_FRONT, 275 - ctx, cpu, count); 261 + cpu, count, &rsd); 276 262 else if (evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND)) 277 263 update_runtime_stat(st, STAT_STALLED_CYCLES_BACK, 278 - ctx, cpu, count); 264 + cpu, count, &rsd); 279 265 else if (evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS)) 280 - update_runtime_stat(st, STAT_BRANCHES, ctx, cpu, count); 266 + update_runtime_stat(st, STAT_BRANCHES, cpu, count, &rsd); 281 267 else if (evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES)) 282 - update_runtime_stat(st, STAT_CACHEREFS, ctx, cpu, count); 268 + update_runtime_stat(st, STAT_CACHEREFS, cpu, count, &rsd); 283 269 else if (evsel__match(counter, HW_CACHE, HW_CACHE_L1D)) 284 - update_runtime_stat(st, STAT_L1_DCACHE, ctx, cpu, count); 270 + update_runtime_stat(st, STAT_L1_DCACHE, cpu, count, &rsd); 285 271 else if (evsel__match(counter, HW_CACHE, HW_CACHE_L1I)) 286 - update_runtime_stat(st, STAT_L1_ICACHE, ctx, cpu, count); 272 + update_runtime_stat(st, STAT_L1_ICACHE, cpu, count, &rsd); 287 273 else if (evsel__match(counter, HW_CACHE, HW_CACHE_LL)) 288 - update_runtime_stat(st, STAT_LL_CACHE, ctx, cpu, count); 274 + update_runtime_stat(st, STAT_LL_CACHE, cpu, count, &rsd); 289 275 else if (evsel__match(counter, HW_CACHE, HW_CACHE_DTLB)) 290 - update_runtime_stat(st, STAT_DTLB_CACHE, ctx, cpu, count); 276 + update_runtime_stat(st, STAT_DTLB_CACHE, cpu, count, &rsd); 291 277 else if (evsel__match(counter, HW_CACHE, HW_CACHE_ITLB)) 292 - update_runtime_stat(st, STAT_ITLB_CACHE, ctx, cpu, count); 278 + update_runtime_stat(st, STAT_ITLB_CACHE, cpu, count, &rsd); 293 279 else if (perf_stat_evsel__is(counter, SMI_NUM)) 294 - update_runtime_stat(st, STAT_SMI_NUM, ctx, cpu, count); 280 + update_runtime_stat(st, STAT_SMI_NUM, cpu, count, &rsd); 295 281 else if (perf_stat_evsel__is(counter, APERF)) 296 - update_runtime_stat(st, STAT_APERF, ctx, cpu, count); 282 + update_runtime_stat(st, STAT_APERF, cpu, count, &rsd); 297 283 298 284 if (counter->collect_stat) { 299 - v = saved_value_lookup(counter, cpu, true, STAT_NONE, 0, st); 285 + v = saved_value_lookup(counter, cpu, true, STAT_NONE, 0, st, 286 + rsd.cgrp); 300 287 update_stats(&v->stats, count); 301 288 if (counter->metric_leader) 302 289 v->metric_total += count; 303 290 } else if (counter->metric_leader) { 304 291 v = saved_value_lookup(counter->metric_leader, 305 - cpu, true, STAT_NONE, 0, st); 292 + cpu, true, STAT_NONE, 0, st, rsd.cgrp); 306 293 v->metric_total += count; 307 294 v->metric_other++; 308 295 } ··· 443 422 } 444 423 445 424 static double runtime_stat_avg(struct runtime_stat *st, 446 - enum stat_type type, int ctx, int cpu) 425 + enum stat_type type, int cpu, 426 + struct runtime_stat_data *rsd) 447 427 { 448 428 struct saved_value *v; 449 429 450 - v = saved_value_lookup(NULL, cpu, false, type, ctx, st); 430 + v = saved_value_lookup(NULL, cpu, false, type, rsd->ctx, st, rsd->cgrp); 451 431 if (!v) 452 432 return 0.0; 453 433 ··· 456 434 } 457 435 458 436 static double runtime_stat_n(struct runtime_stat *st, 459 - enum stat_type type, int ctx, int cpu) 437 + enum stat_type type, int cpu, 438 + struct runtime_stat_data *rsd) 460 439 { 461 440 struct saved_value *v; 462 441 463 - v = saved_value_lookup(NULL, cpu, false, type, ctx, st); 442 + v = saved_value_lookup(NULL, cpu, false, type, rsd->ctx, st, rsd->cgrp); 464 443 if (!v) 465 444 return 0.0; 466 445 ··· 469 446 } 470 447 471 448 static void print_stalled_cycles_frontend(struct perf_stat_config *config, 472 - int cpu, 473 - struct evsel *evsel, double avg, 449 + int cpu, double avg, 474 450 struct perf_stat_output_ctx *out, 475 - struct runtime_stat *st) 451 + struct runtime_stat *st, 452 + struct runtime_stat_data *rsd) 476 453 { 477 454 double total, ratio = 0.0; 478 455 const char *color; 479 - int ctx = evsel_context(evsel); 480 456 481 - total = runtime_stat_avg(st, STAT_CYCLES, ctx, cpu); 457 + total = runtime_stat_avg(st, STAT_CYCLES, cpu, rsd); 482 458 483 459 if (total) 484 460 ratio = avg / total * 100.0; ··· 492 470 } 493 471 494 472 static void print_stalled_cycles_backend(struct perf_stat_config *config, 495 - int cpu, 496 - struct evsel *evsel, double avg, 473 + int cpu, double avg, 497 474 struct perf_stat_output_ctx *out, 498 - struct runtime_stat *st) 475 + struct runtime_stat *st, 476 + struct runtime_stat_data *rsd) 499 477 { 500 478 double total, ratio = 0.0; 501 479 const char *color; 502 - int ctx = evsel_context(evsel); 503 480 504 - total = runtime_stat_avg(st, STAT_CYCLES, ctx, cpu); 481 + total = runtime_stat_avg(st, STAT_CYCLES, cpu, rsd); 505 482 506 483 if (total) 507 484 ratio = avg / total * 100.0; ··· 511 490 } 512 491 513 492 static void print_branch_misses(struct perf_stat_config *config, 514 - int cpu, 515 - struct evsel *evsel, 516 - double avg, 493 + int cpu, double avg, 517 494 struct perf_stat_output_ctx *out, 518 - struct runtime_stat *st) 495 + struct runtime_stat *st, 496 + struct runtime_stat_data *rsd) 519 497 { 520 498 double total, ratio = 0.0; 521 499 const char *color; 522 - int ctx = evsel_context(evsel); 523 500 524 - total = runtime_stat_avg(st, STAT_BRANCHES, ctx, cpu); 501 + total = runtime_stat_avg(st, STAT_BRANCHES, cpu, rsd); 525 502 526 503 if (total) 527 504 ratio = avg / total * 100.0; ··· 530 511 } 531 512 532 513 static void print_l1_dcache_misses(struct perf_stat_config *config, 533 - int cpu, 534 - struct evsel *evsel, 535 - double avg, 514 + int cpu, double avg, 536 515 struct perf_stat_output_ctx *out, 537 - struct runtime_stat *st) 538 - 516 + struct runtime_stat *st, 517 + struct runtime_stat_data *rsd) 539 518 { 540 519 double total, ratio = 0.0; 541 520 const char *color; 542 - int ctx = evsel_context(evsel); 543 521 544 - total = runtime_stat_avg(st, STAT_L1_DCACHE, ctx, cpu); 522 + total = runtime_stat_avg(st, STAT_L1_DCACHE, cpu, rsd); 545 523 546 524 if (total) 547 525 ratio = avg / total * 100.0; ··· 549 533 } 550 534 551 535 static void print_l1_icache_misses(struct perf_stat_config *config, 552 - int cpu, 553 - struct evsel *evsel, 554 - double avg, 536 + int cpu, double avg, 555 537 struct perf_stat_output_ctx *out, 556 - struct runtime_stat *st) 557 - 538 + struct runtime_stat *st, 539 + struct runtime_stat_data *rsd) 558 540 { 559 541 double total, ratio = 0.0; 560 542 const char *color; 561 - int ctx = evsel_context(evsel); 562 543 563 - total = runtime_stat_avg(st, STAT_L1_ICACHE, ctx, cpu); 544 + total = runtime_stat_avg(st, STAT_L1_ICACHE, cpu, rsd); 564 545 565 546 if (total) 566 547 ratio = avg / total * 100.0; ··· 567 554 } 568 555 569 556 static void print_dtlb_cache_misses(struct perf_stat_config *config, 570 - int cpu, 571 - struct evsel *evsel, 572 - double avg, 557 + int cpu, double avg, 573 558 struct perf_stat_output_ctx *out, 574 - struct runtime_stat *st) 559 + struct runtime_stat *st, 560 + struct runtime_stat_data *rsd) 575 561 { 576 562 double total, ratio = 0.0; 577 563 const char *color; 578 - int ctx = evsel_context(evsel); 579 564 580 - total = runtime_stat_avg(st, STAT_DTLB_CACHE, ctx, cpu); 565 + total = runtime_stat_avg(st, STAT_DTLB_CACHE, cpu, rsd); 581 566 582 567 if (total) 583 568 ratio = avg / total * 100.0; ··· 585 574 } 586 575 587 576 static void print_itlb_cache_misses(struct perf_stat_config *config, 588 - int cpu, 589 - struct evsel *evsel, 590 - double avg, 577 + int cpu, double avg, 591 578 struct perf_stat_output_ctx *out, 592 - struct runtime_stat *st) 579 + struct runtime_stat *st, 580 + struct runtime_stat_data *rsd) 593 581 { 594 582 double total, ratio = 0.0; 595 583 const char *color; 596 - int ctx = evsel_context(evsel); 597 584 598 - total = runtime_stat_avg(st, STAT_ITLB_CACHE, ctx, cpu); 585 + total = runtime_stat_avg(st, STAT_ITLB_CACHE, cpu, rsd); 599 586 600 587 if (total) 601 588 ratio = avg / total * 100.0; ··· 603 594 } 604 595 605 596 static void print_ll_cache_misses(struct perf_stat_config *config, 606 - int cpu, 607 - struct evsel *evsel, 608 - double avg, 597 + int cpu, double avg, 609 598 struct perf_stat_output_ctx *out, 610 - struct runtime_stat *st) 599 + struct runtime_stat *st, 600 + struct runtime_stat_data *rsd) 611 601 { 612 602 double total, ratio = 0.0; 613 603 const char *color; 614 - int ctx = evsel_context(evsel); 615 604 616 - total = runtime_stat_avg(st, STAT_LL_CACHE, ctx, cpu); 605 + total = runtime_stat_avg(st, STAT_LL_CACHE, cpu, rsd); 617 606 618 607 if (total) 619 608 ratio = avg / total * 100.0; ··· 669 662 return x; 670 663 } 671 664 672 - static double td_total_slots(int ctx, int cpu, struct runtime_stat *st) 665 + static double td_total_slots(int cpu, struct runtime_stat *st, 666 + struct runtime_stat_data *rsd) 673 667 { 674 - return runtime_stat_avg(st, STAT_TOPDOWN_TOTAL_SLOTS, ctx, cpu); 668 + return runtime_stat_avg(st, STAT_TOPDOWN_TOTAL_SLOTS, cpu, rsd); 675 669 } 676 670 677 - static double td_bad_spec(int ctx, int cpu, struct runtime_stat *st) 671 + static double td_bad_spec(int cpu, struct runtime_stat *st, 672 + struct runtime_stat_data *rsd) 678 673 { 679 674 double bad_spec = 0; 680 675 double total_slots; 681 676 double total; 682 677 683 - total = runtime_stat_avg(st, STAT_TOPDOWN_SLOTS_ISSUED, ctx, cpu) - 684 - runtime_stat_avg(st, STAT_TOPDOWN_SLOTS_RETIRED, ctx, cpu) + 685 - runtime_stat_avg(st, STAT_TOPDOWN_RECOVERY_BUBBLES, ctx, cpu); 678 + total = runtime_stat_avg(st, STAT_TOPDOWN_SLOTS_ISSUED, cpu, rsd) - 679 + runtime_stat_avg(st, STAT_TOPDOWN_SLOTS_RETIRED, cpu, rsd) + 680 + runtime_stat_avg(st, STAT_TOPDOWN_RECOVERY_BUBBLES, cpu, rsd); 686 681 687 - total_slots = td_total_slots(ctx, cpu, st); 682 + total_slots = td_total_slots(cpu, st, rsd); 688 683 if (total_slots) 689 684 bad_spec = total / total_slots; 690 685 return sanitize_val(bad_spec); 691 686 } 692 687 693 - static double td_retiring(int ctx, int cpu, struct runtime_stat *st) 688 + static double td_retiring(int cpu, struct runtime_stat *st, 689 + struct runtime_stat_data *rsd) 694 690 { 695 691 double retiring = 0; 696 - double total_slots = td_total_slots(ctx, cpu, st); 692 + double total_slots = td_total_slots(cpu, st, rsd); 697 693 double ret_slots = runtime_stat_avg(st, STAT_TOPDOWN_SLOTS_RETIRED, 698 - ctx, cpu); 694 + cpu, rsd); 699 695 700 696 if (total_slots) 701 697 retiring = ret_slots / total_slots; 702 698 return retiring; 703 699 } 704 700 705 - static double td_fe_bound(int ctx, int cpu, struct runtime_stat *st) 701 + static double td_fe_bound(int cpu, struct runtime_stat *st, 702 + struct runtime_stat_data *rsd) 706 703 { 707 704 double fe_bound = 0; 708 - double total_slots = td_total_slots(ctx, cpu, st); 705 + double total_slots = td_total_slots(cpu, st, rsd); 709 706 double fetch_bub = runtime_stat_avg(st, STAT_TOPDOWN_FETCH_BUBBLES, 710 - ctx, cpu); 707 + cpu, rsd); 711 708 712 709 if (total_slots) 713 710 fe_bound = fetch_bub / total_slots; 714 711 return fe_bound; 715 712 } 716 713 717 - static double td_be_bound(int ctx, int cpu, struct runtime_stat *st) 714 + static double td_be_bound(int cpu, struct runtime_stat *st, 715 + struct runtime_stat_data *rsd) 718 716 { 719 - double sum = (td_fe_bound(ctx, cpu, st) + 720 - td_bad_spec(ctx, cpu, st) + 721 - td_retiring(ctx, cpu, st)); 717 + double sum = (td_fe_bound(cpu, st, rsd) + 718 + td_bad_spec(cpu, st, rsd) + 719 + td_retiring(cpu, st, rsd)); 722 720 if (sum == 0) 723 721 return 0; 724 722 return sanitize_val(1.0 - sum); ··· 734 722 * the ratios we need to recreate the sum. 735 723 */ 736 724 737 - static double td_metric_ratio(int ctx, int cpu, 738 - enum stat_type type, 739 - struct runtime_stat *stat) 725 + static double td_metric_ratio(int cpu, enum stat_type type, 726 + struct runtime_stat *stat, 727 + struct runtime_stat_data *rsd) 740 728 { 741 - double sum = runtime_stat_avg(stat, STAT_TOPDOWN_RETIRING, ctx, cpu) + 742 - runtime_stat_avg(stat, STAT_TOPDOWN_FE_BOUND, ctx, cpu) + 743 - runtime_stat_avg(stat, STAT_TOPDOWN_BE_BOUND, ctx, cpu) + 744 - runtime_stat_avg(stat, STAT_TOPDOWN_BAD_SPEC, ctx, cpu); 745 - double d = runtime_stat_avg(stat, type, ctx, cpu); 729 + double sum = runtime_stat_avg(stat, STAT_TOPDOWN_RETIRING, cpu, rsd) + 730 + runtime_stat_avg(stat, STAT_TOPDOWN_FE_BOUND, cpu, rsd) + 731 + runtime_stat_avg(stat, STAT_TOPDOWN_BE_BOUND, cpu, rsd) + 732 + runtime_stat_avg(stat, STAT_TOPDOWN_BAD_SPEC, cpu, rsd); 733 + double d = runtime_stat_avg(stat, type, cpu, rsd); 746 734 747 735 if (sum) 748 736 return d / sum; ··· 754 742 * We allow two missing. 755 743 */ 756 744 757 - static bool full_td(int ctx, int cpu, 758 - struct runtime_stat *stat) 745 + static bool full_td(int cpu, struct runtime_stat *stat, 746 + struct runtime_stat_data *rsd) 759 747 { 760 748 int c = 0; 761 749 762 - if (runtime_stat_avg(stat, STAT_TOPDOWN_RETIRING, ctx, cpu) > 0) 750 + if (runtime_stat_avg(stat, STAT_TOPDOWN_RETIRING, cpu, rsd) > 0) 763 751 c++; 764 - if (runtime_stat_avg(stat, STAT_TOPDOWN_BE_BOUND, ctx, cpu) > 0) 752 + if (runtime_stat_avg(stat, STAT_TOPDOWN_BE_BOUND, cpu, rsd) > 0) 765 753 c++; 766 - if (runtime_stat_avg(stat, STAT_TOPDOWN_FE_BOUND, ctx, cpu) > 0) 754 + if (runtime_stat_avg(stat, STAT_TOPDOWN_FE_BOUND, cpu, rsd) > 0) 767 755 c++; 768 - if (runtime_stat_avg(stat, STAT_TOPDOWN_BAD_SPEC, ctx, cpu) > 0) 756 + if (runtime_stat_avg(stat, STAT_TOPDOWN_BAD_SPEC, cpu, rsd) > 0) 769 757 c++; 770 758 return c >= 2; 771 759 } 772 760 773 - static void print_smi_cost(struct perf_stat_config *config, 774 - int cpu, struct evsel *evsel, 761 + static void print_smi_cost(struct perf_stat_config *config, int cpu, 775 762 struct perf_stat_output_ctx *out, 776 - struct runtime_stat *st) 763 + struct runtime_stat *st, 764 + struct runtime_stat_data *rsd) 777 765 { 778 766 double smi_num, aperf, cycles, cost = 0.0; 779 - int ctx = evsel_context(evsel); 780 767 const char *color = NULL; 781 768 782 - smi_num = runtime_stat_avg(st, STAT_SMI_NUM, ctx, cpu); 783 - aperf = runtime_stat_avg(st, STAT_APERF, ctx, cpu); 784 - cycles = runtime_stat_avg(st, STAT_CYCLES, ctx, cpu); 769 + smi_num = runtime_stat_avg(st, STAT_SMI_NUM, cpu, rsd); 770 + aperf = runtime_stat_avg(st, STAT_APERF, cpu, rsd); 771 + cycles = runtime_stat_avg(st, STAT_CYCLES, cpu, rsd); 785 772 786 773 if ((cycles == 0) || (aperf == 0)) 787 774 return; ··· 815 804 scale = 1e-9; 816 805 } else { 817 806 v = saved_value_lookup(metric_events[i], cpu, false, 818 - STAT_NONE, 0, st); 807 + STAT_NONE, 0, st, 808 + metric_events[i]->cgrp); 819 809 if (!v) 820 810 break; 821 811 stats = &v->stats; ··· 942 930 print_metric_t print_metric = out->print_metric; 943 931 double total, ratio = 0.0, total2; 944 932 const char *color = NULL; 945 - int ctx = evsel_context(evsel); 933 + struct runtime_stat_data rsd = { 934 + .ctx = evsel_context(evsel), 935 + .cgrp = evsel->cgrp, 936 + }; 946 937 struct metric_event *me; 947 938 int num = 1; 948 939 949 940 if (evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) { 950 - total = runtime_stat_avg(st, STAT_CYCLES, ctx, cpu); 941 + total = runtime_stat_avg(st, STAT_CYCLES, cpu, &rsd); 951 942 952 943 if (total) { 953 944 ratio = avg / total; ··· 960 945 print_metric(config, ctxp, NULL, NULL, "insn per cycle", 0); 961 946 } 962 947 963 - total = runtime_stat_avg(st, STAT_STALLED_CYCLES_FRONT, 964 - ctx, cpu); 948 + total = runtime_stat_avg(st, STAT_STALLED_CYCLES_FRONT, cpu, &rsd); 965 949 966 950 total = max(total, runtime_stat_avg(st, 967 951 STAT_STALLED_CYCLES_BACK, 968 - ctx, cpu)); 952 + cpu, &rsd)); 969 953 970 954 if (total && avg) { 971 955 out->new_line(config, ctxp); ··· 974 960 ratio); 975 961 } 976 962 } else if (evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES)) { 977 - if (runtime_stat_n(st, STAT_BRANCHES, ctx, cpu) != 0) 978 - print_branch_misses(config, cpu, evsel, avg, out, st); 963 + if (runtime_stat_n(st, STAT_BRANCHES, cpu, &rsd) != 0) 964 + print_branch_misses(config, cpu, avg, out, st, &rsd); 979 965 else 980 966 print_metric(config, ctxp, NULL, NULL, "of all branches", 0); 981 967 } else if ( ··· 984 970 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 985 971 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) { 986 972 987 - if (runtime_stat_n(st, STAT_L1_DCACHE, ctx, cpu) != 0) 988 - print_l1_dcache_misses(config, cpu, evsel, avg, out, st); 973 + if (runtime_stat_n(st, STAT_L1_DCACHE, cpu, &rsd) != 0) 974 + print_l1_dcache_misses(config, cpu, avg, out, st, &rsd); 989 975 else 990 976 print_metric(config, ctxp, NULL, NULL, "of all L1-dcache accesses", 0); 991 977 } else if ( ··· 994 980 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 995 981 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) { 996 982 997 - if (runtime_stat_n(st, STAT_L1_ICACHE, ctx, cpu) != 0) 998 - print_l1_icache_misses(config, cpu, evsel, avg, out, st); 983 + if (runtime_stat_n(st, STAT_L1_ICACHE, cpu, &rsd) != 0) 984 + print_l1_icache_misses(config, cpu, avg, out, st, &rsd); 999 985 else 1000 986 print_metric(config, ctxp, NULL, NULL, "of all L1-icache accesses", 0); 1001 987 } else if ( ··· 1004 990 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 1005 991 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) { 1006 992 1007 - if (runtime_stat_n(st, STAT_DTLB_CACHE, ctx, cpu) != 0) 1008 - print_dtlb_cache_misses(config, cpu, evsel, avg, out, st); 993 + if (runtime_stat_n(st, STAT_DTLB_CACHE, cpu, &rsd) != 0) 994 + print_dtlb_cache_misses(config, cpu, avg, out, st, &rsd); 1009 995 else 1010 996 print_metric(config, ctxp, NULL, NULL, "of all dTLB cache accesses", 0); 1011 997 } else if ( ··· 1014 1000 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 1015 1001 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) { 1016 1002 1017 - if (runtime_stat_n(st, STAT_ITLB_CACHE, ctx, cpu) != 0) 1018 - print_itlb_cache_misses(config, cpu, evsel, avg, out, st); 1003 + if (runtime_stat_n(st, STAT_ITLB_CACHE, cpu, &rsd) != 0) 1004 + print_itlb_cache_misses(config, cpu, avg, out, st, &rsd); 1019 1005 else 1020 1006 print_metric(config, ctxp, NULL, NULL, "of all iTLB cache accesses", 0); 1021 1007 } else if ( ··· 1024 1010 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 1025 1011 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) { 1026 1012 1027 - if (runtime_stat_n(st, STAT_LL_CACHE, ctx, cpu) != 0) 1028 - print_ll_cache_misses(config, cpu, evsel, avg, out, st); 1013 + if (runtime_stat_n(st, STAT_LL_CACHE, cpu, &rsd) != 0) 1014 + print_ll_cache_misses(config, cpu, avg, out, st, &rsd); 1029 1015 else 1030 1016 print_metric(config, ctxp, NULL, NULL, "of all LL-cache accesses", 0); 1031 1017 } else if (evsel__match(evsel, HARDWARE, HW_CACHE_MISSES)) { 1032 - total = runtime_stat_avg(st, STAT_CACHEREFS, ctx, cpu); 1018 + total = runtime_stat_avg(st, STAT_CACHEREFS, cpu, &rsd); 1033 1019 1034 1020 if (total) 1035 1021 ratio = avg * 100 / total; 1036 1022 1037 - if (runtime_stat_n(st, STAT_CACHEREFS, ctx, cpu) != 0) 1023 + if (runtime_stat_n(st, STAT_CACHEREFS, cpu, &rsd) != 0) 1038 1024 print_metric(config, ctxp, NULL, "%8.3f %%", 1039 1025 "of all cache refs", ratio); 1040 1026 else 1041 1027 print_metric(config, ctxp, NULL, NULL, "of all cache refs", 0); 1042 1028 } else if (evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) { 1043 - print_stalled_cycles_frontend(config, cpu, evsel, avg, out, st); 1029 + print_stalled_cycles_frontend(config, cpu, avg, out, st, &rsd); 1044 1030 } else if (evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) { 1045 - print_stalled_cycles_backend(config, cpu, evsel, avg, out, st); 1031 + print_stalled_cycles_backend(config, cpu, avg, out, st, &rsd); 1046 1032 } else if (evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) { 1047 - total = runtime_stat_avg(st, STAT_NSECS, 0, cpu); 1033 + total = runtime_stat_avg(st, STAT_NSECS, cpu, &rsd); 1048 1034 1049 1035 if (total) { 1050 1036 ratio = avg / total; ··· 1053 1039 print_metric(config, ctxp, NULL, NULL, "Ghz", 0); 1054 1040 } 1055 1041 } else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) { 1056 - total = runtime_stat_avg(st, STAT_CYCLES, ctx, cpu); 1042 + total = runtime_stat_avg(st, STAT_CYCLES, cpu, &rsd); 1057 1043 1058 1044 if (total) 1059 1045 print_metric(config, ctxp, NULL, ··· 1063 1049 print_metric(config, ctxp, NULL, NULL, "transactional cycles", 1064 1050 0); 1065 1051 } else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) { 1066 - total = runtime_stat_avg(st, STAT_CYCLES, ctx, cpu); 1067 - total2 = runtime_stat_avg(st, STAT_CYCLES_IN_TX, ctx, cpu); 1052 + total = runtime_stat_avg(st, STAT_CYCLES, cpu, &rsd); 1053 + total2 = runtime_stat_avg(st, STAT_CYCLES_IN_TX, cpu, &rsd); 1068 1054 1069 1055 if (total2 < avg) 1070 1056 total2 = avg; ··· 1074 1060 else 1075 1061 print_metric(config, ctxp, NULL, NULL, "aborted cycles", 0); 1076 1062 } else if (perf_stat_evsel__is(evsel, TRANSACTION_START)) { 1077 - total = runtime_stat_avg(st, STAT_CYCLES_IN_TX, 1078 - ctx, cpu); 1063 + total = runtime_stat_avg(st, STAT_CYCLES_IN_TX, cpu, &rsd); 1079 1064 1080 1065 if (avg) 1081 1066 ratio = total / avg; 1082 1067 1083 - if (runtime_stat_n(st, STAT_CYCLES_IN_TX, ctx, cpu) != 0) 1068 + if (runtime_stat_n(st, STAT_CYCLES_IN_TX, cpu, &rsd) != 0) 1084 1069 print_metric(config, ctxp, NULL, "%8.0f", 1085 1070 "cycles / transaction", ratio); 1086 1071 else 1087 1072 print_metric(config, ctxp, NULL, NULL, "cycles / transaction", 1088 1073 0); 1089 1074 } else if (perf_stat_evsel__is(evsel, ELISION_START)) { 1090 - total = runtime_stat_avg(st, STAT_CYCLES_IN_TX, 1091 - ctx, cpu); 1075 + total = runtime_stat_avg(st, STAT_CYCLES_IN_TX, cpu, &rsd); 1092 1076 1093 1077 if (avg) 1094 1078 ratio = total / avg; ··· 1099 1087 else 1100 1088 print_metric(config, ctxp, NULL, NULL, "CPUs utilized", 0); 1101 1089 } else if (perf_stat_evsel__is(evsel, TOPDOWN_FETCH_BUBBLES)) { 1102 - double fe_bound = td_fe_bound(ctx, cpu, st); 1090 + double fe_bound = td_fe_bound(cpu, st, &rsd); 1103 1091 1104 1092 if (fe_bound > 0.2) 1105 1093 color = PERF_COLOR_RED; 1106 1094 print_metric(config, ctxp, color, "%8.1f%%", "frontend bound", 1107 1095 fe_bound * 100.); 1108 1096 } else if (perf_stat_evsel__is(evsel, TOPDOWN_SLOTS_RETIRED)) { 1109 - double retiring = td_retiring(ctx, cpu, st); 1097 + double retiring = td_retiring(cpu, st, &rsd); 1110 1098 1111 1099 if (retiring > 0.7) 1112 1100 color = PERF_COLOR_GREEN; 1113 1101 print_metric(config, ctxp, color, "%8.1f%%", "retiring", 1114 1102 retiring * 100.); 1115 1103 } else if (perf_stat_evsel__is(evsel, TOPDOWN_RECOVERY_BUBBLES)) { 1116 - double bad_spec = td_bad_spec(ctx, cpu, st); 1104 + double bad_spec = td_bad_spec(cpu, st, &rsd); 1117 1105 1118 1106 if (bad_spec > 0.1) 1119 1107 color = PERF_COLOR_RED; 1120 1108 print_metric(config, ctxp, color, "%8.1f%%", "bad speculation", 1121 1109 bad_spec * 100.); 1122 1110 } else if (perf_stat_evsel__is(evsel, TOPDOWN_SLOTS_ISSUED)) { 1123 - double be_bound = td_be_bound(ctx, cpu, st); 1111 + double be_bound = td_be_bound(cpu, st, &rsd); 1124 1112 const char *name = "backend bound"; 1125 1113 static int have_recovery_bubbles = -1; 1126 1114 ··· 1133 1121 1134 1122 if (be_bound > 0.2) 1135 1123 color = PERF_COLOR_RED; 1136 - if (td_total_slots(ctx, cpu, st) > 0) 1124 + if (td_total_slots(cpu, st, &rsd) > 0) 1137 1125 print_metric(config, ctxp, color, "%8.1f%%", name, 1138 1126 be_bound * 100.); 1139 1127 else 1140 1128 print_metric(config, ctxp, NULL, NULL, name, 0); 1141 1129 } else if (perf_stat_evsel__is(evsel, TOPDOWN_RETIRING) && 1142 - full_td(ctx, cpu, st)) { 1143 - double retiring = td_metric_ratio(ctx, cpu, 1144 - STAT_TOPDOWN_RETIRING, st); 1145 - 1130 + full_td(cpu, st, &rsd)) { 1131 + double retiring = td_metric_ratio(cpu, 1132 + STAT_TOPDOWN_RETIRING, st, 1133 + &rsd); 1146 1134 if (retiring > 0.7) 1147 1135 color = PERF_COLOR_GREEN; 1148 1136 print_metric(config, ctxp, color, "%8.1f%%", "retiring", 1149 1137 retiring * 100.); 1150 1138 } else if (perf_stat_evsel__is(evsel, TOPDOWN_FE_BOUND) && 1151 - full_td(ctx, cpu, st)) { 1152 - double fe_bound = td_metric_ratio(ctx, cpu, 1153 - STAT_TOPDOWN_FE_BOUND, st); 1154 - 1139 + full_td(cpu, st, &rsd)) { 1140 + double fe_bound = td_metric_ratio(cpu, 1141 + STAT_TOPDOWN_FE_BOUND, st, 1142 + &rsd); 1155 1143 if (fe_bound > 0.2) 1156 1144 color = PERF_COLOR_RED; 1157 1145 print_metric(config, ctxp, color, "%8.1f%%", "frontend bound", 1158 1146 fe_bound * 100.); 1159 1147 } else if (perf_stat_evsel__is(evsel, TOPDOWN_BE_BOUND) && 1160 - full_td(ctx, cpu, st)) { 1161 - double be_bound = td_metric_ratio(ctx, cpu, 1162 - STAT_TOPDOWN_BE_BOUND, st); 1163 - 1148 + full_td(cpu, st, &rsd)) { 1149 + double be_bound = td_metric_ratio(cpu, 1150 + STAT_TOPDOWN_BE_BOUND, st, 1151 + &rsd); 1164 1152 if (be_bound > 0.2) 1165 1153 color = PERF_COLOR_RED; 1166 1154 print_metric(config, ctxp, color, "%8.1f%%", "backend bound", 1167 1155 be_bound * 100.); 1168 1156 } else if (perf_stat_evsel__is(evsel, TOPDOWN_BAD_SPEC) && 1169 - full_td(ctx, cpu, st)) { 1170 - double bad_spec = td_metric_ratio(ctx, cpu, 1171 - STAT_TOPDOWN_BAD_SPEC, st); 1172 - 1157 + full_td(cpu, st, &rsd)) { 1158 + double bad_spec = td_metric_ratio(cpu, 1159 + STAT_TOPDOWN_BAD_SPEC, st, 1160 + &rsd); 1173 1161 if (bad_spec > 0.1) 1174 1162 color = PERF_COLOR_RED; 1175 1163 print_metric(config, ctxp, color, "%8.1f%%", "bad speculation", ··· 1177 1165 } else if (evsel->metric_expr) { 1178 1166 generic_metric(config, evsel->metric_expr, evsel->metric_events, NULL, 1179 1167 evsel->name, evsel->metric_name, NULL, 1, cpu, out, st); 1180 - } else if (runtime_stat_n(st, STAT_NSECS, 0, cpu) != 0) { 1168 + } else if (runtime_stat_n(st, STAT_NSECS, cpu, &rsd) != 0) { 1181 1169 char unit = 'M'; 1182 1170 char unit_buf[10]; 1183 1171 1184 - total = runtime_stat_avg(st, STAT_NSECS, 0, cpu); 1172 + total = runtime_stat_avg(st, STAT_NSECS, cpu, &rsd); 1185 1173 1186 1174 if (total) 1187 1175 ratio = 1000.0 * avg / total; ··· 1192 1180 snprintf(unit_buf, sizeof(unit_buf), "%c/sec", unit); 1193 1181 print_metric(config, ctxp, NULL, "%8.3f", unit_buf, ratio); 1194 1182 } else if (perf_stat_evsel__is(evsel, SMI_NUM)) { 1195 - print_smi_cost(config, cpu, evsel, out, st); 1183 + print_smi_cost(config, cpu, out, st, &rsd); 1196 1184 } else { 1197 1185 num = 0; 1198 1186 }