summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2013-12-12 15:47:00 (GMT)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-12-16 13:37:52 (GMT)
commit55baa2f831ae4a41da9617ab9e7cef5ebc991ec9 (patch)
tree700ba9a81a60e1c4eaff56f57d38fd818f6de6a8
parent8c069ff4bd6063a3f15e606c882e03f75c7e7711 (diff)
downloadlinux-55baa2f831ae4a41da9617ab9e7cef5ebc991ec9.tar.xz
s390/perf: Improve PMU selection for PERF_COUNT_HW_CPU_CYCLES events
The cpum_cf (counter facility) PMU does not support sampling events. With cpum_sf (sampling facility), a PMU for sampling CPU cycles is available. Make cpum_sf the "default" PMU for PERF_COUNT_HW_CPU_CYCLES sampling events but use the more precise cpum_cf PMU for non-sampling events. Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/kernel/perf_cpum_sf.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c
index 141eca0..52bf36e 100644
--- a/arch/s390/kernel/perf_cpum_sf.c
+++ b/arch/s390/kernel/perf_cpum_sf.c
@@ -468,11 +468,29 @@ static int cpumsf_pmu_event_init(struct perf_event *event)
{
int err;
- if (event->attr.type != PERF_TYPE_RAW)
- return -ENOENT;
-
- if (event->attr.config != PERF_EVENT_CPUM_SF)
+ /* No support for taken branch sampling */
+ if (has_branch_stack(event))
+ return -EOPNOTSUPP;
+
+ switch (event->attr.type) {
+ case PERF_TYPE_RAW:
+ if (event->attr.config != PERF_EVENT_CPUM_SF)
+ return -ENOENT;
+ break;
+ case PERF_TYPE_HARDWARE:
+ /* Support sampling of CPU cycles in addition to the
+ * counter facility. However, the counter facility
+ * is more precise and, hence, restrict this PMU to
+ * sampling events only.
+ */
+ if (event->attr.config != PERF_COUNT_HW_CPU_CYCLES)
+ return -ENOENT;
+ if (!is_sampling_event(event))
+ return -ENOENT;
+ break;
+ default:
return -ENOENT;
+ }
if (event->cpu >= nr_cpumask_bits ||
(event->cpu >= 0 && !cpu_online(event->cpu)))