diff options
author | Peter Zijlstra <peterz@infradead.org> | 2012-03-22 12:26:36 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-03-23 04:52:16 -0400 |
commit | c7206205d00ab375839bd6c7ddb247d600693c09 (patch) | |
tree | 24b9d66a5eaef77c1fc40bc8f6f28acfd167bf5b /arch | |
parent | c5bc437702b24817cabd65a6a57971ff91a7712c (diff) |
perf: Fix mmap_page capabilities and docs
Complete the syscall-less self-profiling feature and address
all complaints, namely:
- capabilities, so we can detect what is actually available at runtime
Add a capabilities field to perf_event_mmap_page to indicate
what is actually available for use.
- on x86: RDPMC weirdness due to being 40/48 bits and not sign-extending
properly.
- ABI documentation as to how all this stuff works.
Also improve the documentation for the new features.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Vince Weaver <vweaver1@eecs.utk.edu>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1332433596.2487.33.camel@twins
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 453ac9497574..4ef8104958ee 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -1622,6 +1622,9 @@ static int x86_pmu_event_idx(struct perf_event *event) | |||
1622 | { | 1622 | { |
1623 | int idx = event->hw.idx; | 1623 | int idx = event->hw.idx; |
1624 | 1624 | ||
1625 | if (!x86_pmu.attr_rdpmc) | ||
1626 | return 0; | ||
1627 | |||
1625 | if (x86_pmu.num_counters_fixed && idx >= X86_PMC_IDX_FIXED) { | 1628 | if (x86_pmu.num_counters_fixed && idx >= X86_PMC_IDX_FIXED) { |
1626 | idx -= X86_PMC_IDX_FIXED; | 1629 | idx -= X86_PMC_IDX_FIXED; |
1627 | idx |= 1 << 30; | 1630 | idx |= 1 << 30; |
@@ -1706,14 +1709,19 @@ static struct pmu pmu = { | |||
1706 | .flush_branch_stack = x86_pmu_flush_branch_stack, | 1709 | .flush_branch_stack = x86_pmu_flush_branch_stack, |
1707 | }; | 1710 | }; |
1708 | 1711 | ||
1709 | void perf_update_user_clock(struct perf_event_mmap_page *userpg, u64 now) | 1712 | void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) |
1710 | { | 1713 | { |
1714 | userpg->cap_usr_time = 0; | ||
1715 | userpg->cap_usr_rdpmc = x86_pmu.attr_rdpmc; | ||
1716 | userpg->pmc_width = x86_pmu.cntval_bits; | ||
1717 | |||
1711 | if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) | 1718 | if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) |
1712 | return; | 1719 | return; |
1713 | 1720 | ||
1714 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) | 1721 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) |
1715 | return; | 1722 | return; |
1716 | 1723 | ||
1724 | userpg->cap_usr_time = 1; | ||
1717 | userpg->time_mult = this_cpu_read(cyc2ns); | 1725 | userpg->time_mult = this_cpu_read(cyc2ns); |
1718 | userpg->time_shift = CYC2NS_SCALE_FACTOR; | 1726 | userpg->time_shift = CYC2NS_SCALE_FACTOR; |
1719 | userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; | 1727 | userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; |