diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2011-11-20 14:44:06 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-12-21 05:01:10 -0500 |
commit | fe4a330885aee20f233de36085fb15c38094e635 (patch) | |
tree | 2dae96591caf2bd98131b3d75b685d41be7d1264 | |
parent | 365a4038486b57bb2bd516706a80f82f250f5306 (diff) |
perf, x86: Implement user-space RDPMC support, to allow fast, user-space access to self-monitoring counters
Implement a correct pmu::event_idx for the x86 counter index rules and
set CR4.PCE on CPU_STARTING.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Arun Sharma <asharma@fb.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Link: http://lkml.kernel.org/n/tip-mwxab34dibqgzk5zywutfnha@git.kernel.org
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 5adce1040b11..53b569910175 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -1210,6 +1210,7 @@ x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) | |||
1210 | break; | 1210 | break; |
1211 | 1211 | ||
1212 | case CPU_STARTING: | 1212 | case CPU_STARTING: |
1213 | set_in_cr4(X86_CR4_PCE); | ||
1213 | if (x86_pmu.cpu_starting) | 1214 | if (x86_pmu.cpu_starting) |
1214 | x86_pmu.cpu_starting(cpu); | 1215 | x86_pmu.cpu_starting(cpu); |
1215 | break; | 1216 | break; |
@@ -1542,6 +1543,18 @@ static int x86_pmu_event_init(struct perf_event *event) | |||
1542 | return err; | 1543 | return err; |
1543 | } | 1544 | } |
1544 | 1545 | ||
1546 | static int x86_pmu_event_idx(struct perf_event *event) | ||
1547 | { | ||
1548 | int idx = event->hw.idx; | ||
1549 | |||
1550 | if (x86_pmu.num_counters_fixed && idx >= X86_PMC_IDX_FIXED) { | ||
1551 | idx -= X86_PMC_IDX_FIXED; | ||
1552 | idx |= 1 << 30; | ||
1553 | } | ||
1554 | |||
1555 | return idx + 1; | ||
1556 | } | ||
1557 | |||
1545 | static struct pmu pmu = { | 1558 | static struct pmu pmu = { |
1546 | .pmu_enable = x86_pmu_enable, | 1559 | .pmu_enable = x86_pmu_enable, |
1547 | .pmu_disable = x86_pmu_disable, | 1560 | .pmu_disable = x86_pmu_disable, |
@@ -1557,6 +1570,8 @@ static struct pmu pmu = { | |||
1557 | .start_txn = x86_pmu_start_txn, | 1570 | .start_txn = x86_pmu_start_txn, |
1558 | .cancel_txn = x86_pmu_cancel_txn, | 1571 | .cancel_txn = x86_pmu_cancel_txn, |
1559 | .commit_txn = x86_pmu_commit_txn, | 1572 | .commit_txn = x86_pmu_commit_txn, |
1573 | |||
1574 | .event_idx = x86_pmu_event_idx, | ||
1560 | }; | 1575 | }; |
1561 | 1576 | ||
1562 | /* | 1577 | /* |