diff options
author | Mark Rutland <mark.rutland@arm.com> | 2011-04-28 05:17:04 -0400 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2011-08-31 05:50:07 -0400 |
commit | 0f78d2d5ccf72ec834da6901886a40fd8e3b7615 (patch) | |
tree | da1262d040b2c10d95c6fc313b44e18801bcb4a3 /arch/arm/kernel/perf_event_v7.c | |
parent | 1b69beb7684c79673995607939d8acab51056b63 (diff) |
ARM: perf: lock PMU registers per-CPU
Currently, a single lock serialises access to CPU PMU registers. This
global locking is unnecessary as PMU registers are local to the CPU
they monitor.
This patch replaces the global lock with a per-CPU lock. As the lock is
in struct cpu_hw_events, PMUs providing a single cpu_hw_events instance
can be locked globally.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Jamie Iles <jamie@jamieiles.com>
Reviewed-by: Ashwin Chaugule <ashwinc@codeaurora.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm/kernel/perf_event_v7.c')
-rw-r--r-- | arch/arm/kernel/perf_event_v7.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index f4170fc228b6..68ac522fd940 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c | |||
@@ -936,12 +936,13 @@ static void armv7_pmnc_dump_regs(void) | |||
936 | static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) | 936 | static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) |
937 | { | 937 | { |
938 | unsigned long flags; | 938 | unsigned long flags; |
939 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
939 | 940 | ||
940 | /* | 941 | /* |
941 | * Enable counter and interrupt, and set the counter to count | 942 | * Enable counter and interrupt, and set the counter to count |
942 | * the event that we're interested in. | 943 | * the event that we're interested in. |
943 | */ | 944 | */ |
944 | raw_spin_lock_irqsave(&pmu_lock, flags); | 945 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
945 | 946 | ||
946 | /* | 947 | /* |
947 | * Disable counter | 948 | * Disable counter |
@@ -966,17 +967,18 @@ static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) | |||
966 | */ | 967 | */ |
967 | armv7_pmnc_enable_counter(idx); | 968 | armv7_pmnc_enable_counter(idx); |
968 | 969 | ||
969 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 970 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
970 | } | 971 | } |
971 | 972 | ||
972 | static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) | 973 | static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) |
973 | { | 974 | { |
974 | unsigned long flags; | 975 | unsigned long flags; |
976 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
975 | 977 | ||
976 | /* | 978 | /* |
977 | * Disable counter and interrupt | 979 | * Disable counter and interrupt |
978 | */ | 980 | */ |
979 | raw_spin_lock_irqsave(&pmu_lock, flags); | 981 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
980 | 982 | ||
981 | /* | 983 | /* |
982 | * Disable counter | 984 | * Disable counter |
@@ -988,7 +990,7 @@ static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) | |||
988 | */ | 990 | */ |
989 | armv7_pmnc_disable_intens(idx); | 991 | armv7_pmnc_disable_intens(idx); |
990 | 992 | ||
991 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 993 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
992 | } | 994 | } |
993 | 995 | ||
994 | static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | 996 | static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) |
@@ -1054,21 +1056,23 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | |||
1054 | static void armv7pmu_start(void) | 1056 | static void armv7pmu_start(void) |
1055 | { | 1057 | { |
1056 | unsigned long flags; | 1058 | unsigned long flags; |
1059 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
1057 | 1060 | ||
1058 | raw_spin_lock_irqsave(&pmu_lock, flags); | 1061 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
1059 | /* Enable all counters */ | 1062 | /* Enable all counters */ |
1060 | armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E); | 1063 | armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E); |
1061 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 1064 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
1062 | } | 1065 | } |
1063 | 1066 | ||
1064 | static void armv7pmu_stop(void) | 1067 | static void armv7pmu_stop(void) |
1065 | { | 1068 | { |
1066 | unsigned long flags; | 1069 | unsigned long flags; |
1070 | struct cpu_hw_events *events = armpmu->get_hw_events(); | ||
1067 | 1071 | ||
1068 | raw_spin_lock_irqsave(&pmu_lock, flags); | 1072 | raw_spin_lock_irqsave(&events->pmu_lock, flags); |
1069 | /* Disable all counters */ | 1073 | /* Disable all counters */ |
1070 | armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E); | 1074 | armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E); |
1071 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | 1075 | raw_spin_unlock_irqrestore(&events->pmu_lock, flags); |
1072 | } | 1076 | } |
1073 | 1077 | ||
1074 | static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc, | 1078 | static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc, |