Skip to content

Commit 5101ef2

Browse files
mrutland-armIngo Molnar
authored andcommitted
perf/arm: Special-case hetereogeneous CPUs
Commit: 2665784 ("perf/core: Verify we have a single perf_hw_context PMU") forcefully prevents multiple PMUs from sharing perf_hw_context, as this generally doesn't make sense. It is a common bug for uncore PMUs to use perf_hw_context rather than perf_invalid_context, which this detects. However, systems exist with heterogeneous CPUs (and hence heterogeneous HW PMUs), for which sharing perf_hw_context is necessary, and possible in some limited cases. To make this work we have to perform some gymnastics, as we did in these commits: 66eb579 ("perf: allow for PMU-specific event filtering") c904e32 ("arm: perf: filter unschedulable events") To allow those systems to work, we must allow PMUs for heterogeneous CPUs to share perf_hw_context, though we must still disallow sharing otherwise to detect the common misuse of perf_hw_context. This patch adds a new PERF_PMU_CAP_HETEROGENEOUS_CPUS for this, updates the core logic to account for this, and makes use of it in the arm_pmu code that is used for systems with heterogeneous CPUs. Comments are added to make the rationale clear and hopefully avoid accidental abuse. Signed-off-by: Mark Rutland <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vince Weaver <[email protected]> Cc: Will Deacon <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/20160426103346.GA20836@leverpostej Signed-off-by: Ingo Molnar <[email protected]>
1 parent 6e855cd commit 5101ef2

File tree

3 files changed

+16
-1
lines changed

3 files changed

+16
-1
lines changed

drivers/perf/arm_pmu.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,14 @@ static int cpu_pmu_init(struct arm_pmu *cpu_pmu)
847847
if (!platform_get_irq(cpu_pmu->plat_device, 0))
848848
cpu_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
849849

850+
/*
851+
* This is a CPU PMU potentially in a heterogeneous configuration (e.g.
852+
* big.LITTLE). This is not an uncore PMU, and we have taken ctx
853+
* sharing into account (e.g. with our pmu::filter_match callback and
854+
* pmu::event_init group validation).
855+
*/
856+
cpu_pmu->pmu.capabilities |= PERF_PMU_CAP_HETEROGENEOUS_CPUS;
857+
850858
return 0;
851859

852860
out_unregister:

include/linux/perf_event.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ struct perf_event;
225225
#define PERF_PMU_CAP_AUX_SW_DOUBLEBUF 0x08
226226
#define PERF_PMU_CAP_EXCLUSIVE 0x10
227227
#define PERF_PMU_CAP_ITRACE 0x20
228+
#define PERF_PMU_CAP_HETEROGENEOUS_CPUS 0x40
228229

229230
/**
230231
* struct pmu - generic performance monitoring unit

kernel/events/core.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8443,7 +8443,13 @@ int perf_pmu_register(struct pmu *pmu, const char *name, int type)
84438443
if (pmu->task_ctx_nr == perf_hw_context) {
84448444
static int hw_context_taken = 0;
84458445

8446-
if (WARN_ON_ONCE(hw_context_taken))
8446+
/*
8447+
* Other than systems with heterogeneous CPUs, it never makes
8448+
* sense for two PMUs to share perf_hw_context. PMUs which are
8449+
* uncore must use perf_invalid_context.
8450+
*/
8451+
if (WARN_ON_ONCE(hw_context_taken &&
8452+
!(pmu->capabilities & PERF_PMU_CAP_HETEROGENEOUS_CPUS)))
84478453
pmu->task_ctx_nr = perf_invalid_context;
84488454

84498455
hw_context_taken = 1;

0 commit comments

Comments
 (0)