diff options
author | Robert Richter <robert.richter@amd.com> | 2011-02-02 11:40:59 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-02-16 07:30:52 -0500 |
commit | 73d6e52206a20354738418625cedc244cbfd5023 (patch) | |
tree | d09c58e5cbf770e7d33c77b251326c975e17fb16 | |
parent | 69d8e1e8ac0a7d829f1c0fd5bd07eb3022d9a1a0 (diff) |
perf, x86: Store perfctr msr addresses in config_base/event_base
Instead of storing the base addresses we can store the counter's msr
addresses directly in config_base/event_base of struct hw_perf_event.
This avoids recalculating the address with each msr access. The
addresses are configured one time. We also need this change to later
modify the address calculation.
Signed-off-by: Robert Richter <robert.richter@amd.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1296664860-10886-5-git-send-email-robert.richter@amd.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 21 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_p4.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_p6.c | 4 |
3 files changed, 14 insertions, 19 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index ee40c1ad0ebc..316194330da0 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -298,7 +298,7 @@ x86_perf_event_update(struct perf_event *event) | |||
298 | */ | 298 | */ |
299 | again: | 299 | again: |
300 | prev_raw_count = local64_read(&hwc->prev_count); | 300 | prev_raw_count = local64_read(&hwc->prev_count); |
301 | rdmsrl(hwc->event_base + idx, new_raw_count); | 301 | rdmsrl(hwc->event_base, new_raw_count); |
302 | 302 | ||
303 | if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, | 303 | if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, |
304 | new_raw_count) != prev_raw_count) | 304 | new_raw_count) != prev_raw_count) |
@@ -655,7 +655,7 @@ static void x86_pmu_disable(struct pmu *pmu) | |||
655 | static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, | 655 | static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, |
656 | u64 enable_mask) | 656 | u64 enable_mask) |
657 | { | 657 | { |
658 | wrmsrl(hwc->config_base + hwc->idx, hwc->config | enable_mask); | 658 | wrmsrl(hwc->config_base, hwc->config | enable_mask); |
659 | } | 659 | } |
660 | 660 | ||
661 | static void x86_pmu_enable_all(int added) | 661 | static void x86_pmu_enable_all(int added) |
@@ -834,15 +834,10 @@ static inline void x86_assign_hw_event(struct perf_event *event, | |||
834 | hwc->event_base = 0; | 834 | hwc->event_base = 0; |
835 | } else if (hwc->idx >= X86_PMC_IDX_FIXED) { | 835 | } else if (hwc->idx >= X86_PMC_IDX_FIXED) { |
836 | hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; | 836 | hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; |
837 | /* | 837 | hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0; |
838 | * We set it so that event_base + idx in wrmsr/rdmsr maps to | ||
839 | * MSR_ARCH_PERFMON_FIXED_CTR0 ... CTR2: | ||
840 | */ | ||
841 | hwc->event_base = | ||
842 | MSR_ARCH_PERFMON_FIXED_CTR0 - X86_PMC_IDX_FIXED; | ||
843 | } else { | 838 | } else { |
844 | hwc->config_base = x86_pmu.eventsel; | 839 | hwc->config_base = x86_pmu_config_addr(hwc->idx); |
845 | hwc->event_base = x86_pmu.perfctr; | 840 | hwc->event_base = x86_pmu_event_addr(hwc->idx); |
846 | } | 841 | } |
847 | } | 842 | } |
848 | 843 | ||
@@ -932,7 +927,7 @@ static inline void x86_pmu_disable_event(struct perf_event *event) | |||
932 | { | 927 | { |
933 | struct hw_perf_event *hwc = &event->hw; | 928 | struct hw_perf_event *hwc = &event->hw; |
934 | 929 | ||
935 | wrmsrl(hwc->config_base + hwc->idx, hwc->config); | 930 | wrmsrl(hwc->config_base, hwc->config); |
936 | } | 931 | } |
937 | 932 | ||
938 | static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left); | 933 | static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left); |
@@ -985,7 +980,7 @@ x86_perf_event_set_period(struct perf_event *event) | |||
985 | */ | 980 | */ |
986 | local64_set(&hwc->prev_count, (u64)-left); | 981 | local64_set(&hwc->prev_count, (u64)-left); |
987 | 982 | ||
988 | wrmsrl(hwc->event_base + idx, (u64)(-left) & x86_pmu.cntval_mask); | 983 | wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask); |
989 | 984 | ||
990 | /* | 985 | /* |
991 | * Due to erratum on certan cpu we need | 986 | * Due to erratum on certan cpu we need |
@@ -993,7 +988,7 @@ x86_perf_event_set_period(struct perf_event *event) | |||
993 | * is updated properly | 988 | * is updated properly |
994 | */ | 989 | */ |
995 | if (x86_pmu.perfctr_second_write) { | 990 | if (x86_pmu.perfctr_second_write) { |
996 | wrmsrl(hwc->event_base + idx, | 991 | wrmsrl(hwc->event_base, |
997 | (u64)(-left) & x86_pmu.cntval_mask); | 992 | (u64)(-left) & x86_pmu.cntval_mask); |
998 | } | 993 | } |
999 | 994 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index ff751a9f182b..3769ac822f96 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c | |||
@@ -764,9 +764,9 @@ static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc) | |||
764 | u64 v; | 764 | u64 v; |
765 | 765 | ||
766 | /* an official way for overflow indication */ | 766 | /* an official way for overflow indication */ |
767 | rdmsrl(hwc->config_base + hwc->idx, v); | 767 | rdmsrl(hwc->config_base, v); |
768 | if (v & P4_CCCR_OVF) { | 768 | if (v & P4_CCCR_OVF) { |
769 | wrmsrl(hwc->config_base + hwc->idx, v & ~P4_CCCR_OVF); | 769 | wrmsrl(hwc->config_base, v & ~P4_CCCR_OVF); |
770 | return 1; | 770 | return 1; |
771 | } | 771 | } |
772 | 772 | ||
@@ -815,7 +815,7 @@ static inline void p4_pmu_disable_event(struct perf_event *event) | |||
815 | * state we need to clear P4_CCCR_OVF, otherwise interrupt get | 815 | * state we need to clear P4_CCCR_OVF, otherwise interrupt get |
816 | * asserted again and again | 816 | * asserted again and again |
817 | */ | 817 | */ |
818 | (void)checking_wrmsrl(hwc->config_base + hwc->idx, | 818 | (void)checking_wrmsrl(hwc->config_base, |
819 | (u64)(p4_config_unpack_cccr(hwc->config)) & | 819 | (u64)(p4_config_unpack_cccr(hwc->config)) & |
820 | ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED); | 820 | ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED); |
821 | } | 821 | } |
@@ -885,7 +885,7 @@ static void p4_pmu_enable_event(struct perf_event *event) | |||
885 | p4_pmu_enable_pebs(hwc->config); | 885 | p4_pmu_enable_pebs(hwc->config); |
886 | 886 | ||
887 | (void)checking_wrmsrl(escr_addr, escr_conf); | 887 | (void)checking_wrmsrl(escr_addr, escr_conf); |
888 | (void)checking_wrmsrl(hwc->config_base + hwc->idx, | 888 | (void)checking_wrmsrl(hwc->config_base, |
889 | (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE); | 889 | (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE); |
890 | } | 890 | } |
891 | 891 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index 34ba07be2cda..20c097e33860 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c | |||
@@ -68,7 +68,7 @@ p6_pmu_disable_event(struct perf_event *event) | |||
68 | if (cpuc->enabled) | 68 | if (cpuc->enabled) |
69 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; | 69 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; |
70 | 70 | ||
71 | (void)checking_wrmsrl(hwc->config_base + hwc->idx, val); | 71 | (void)checking_wrmsrl(hwc->config_base, val); |
72 | } | 72 | } |
73 | 73 | ||
74 | static void p6_pmu_enable_event(struct perf_event *event) | 74 | static void p6_pmu_enable_event(struct perf_event *event) |
@@ -81,7 +81,7 @@ static void p6_pmu_enable_event(struct perf_event *event) | |||
81 | if (cpuc->enabled) | 81 | if (cpuc->enabled) |
82 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; | 82 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; |
83 | 83 | ||
84 | (void)checking_wrmsrl(hwc->config_base + hwc->idx, val); | 84 | (void)checking_wrmsrl(hwc->config_base, val); |
85 | } | 85 | } |
86 | 86 | ||
87 | static __initconst const struct x86_pmu p6_pmu = { | 87 | static __initconst const struct x86_pmu p6_pmu = { |