diff options
| -rw-r--r-- | drivers/perf/arm_pmu.c | 8 | ||||
| -rw-r--r-- | include/linux/perf_event.h | 1 | ||||
| -rw-r--r-- | kernel/events/core.c | 8 |
3 files changed, 16 insertions, 1 deletions
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index f70090897fdf..f2d01d4d9364 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c | |||
| @@ -847,6 +847,14 @@ static int cpu_pmu_init(struct arm_pmu *cpu_pmu) | |||
| 847 | if (!platform_get_irq(cpu_pmu->plat_device, 0)) | 847 | if (!platform_get_irq(cpu_pmu->plat_device, 0)) |
| 848 | cpu_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; | 848 | cpu_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; |
| 849 | 849 | ||
| 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 | |||
| 850 | return 0; | 858 | return 0; |
| 851 | 859 | ||
| 852 | out_unregister: | 860 | out_unregister: |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index c77e4a159fa2..9e1c3ada91c4 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -225,6 +225,7 @@ struct perf_event; | |||
| 225 | #define PERF_PMU_CAP_AUX_SW_DOUBLEBUF 0x08 | 225 | #define PERF_PMU_CAP_AUX_SW_DOUBLEBUF 0x08 |
| 226 | #define PERF_PMU_CAP_EXCLUSIVE 0x10 | 226 | #define PERF_PMU_CAP_EXCLUSIVE 0x10 |
| 227 | #define PERF_PMU_CAP_ITRACE 0x20 | 227 | #define PERF_PMU_CAP_ITRACE 0x20 |
| 228 | #define PERF_PMU_CAP_HETEROGENEOUS_CPUS 0x40 | ||
| 228 | 229 | ||
| 229 | /** | 230 | /** |
| 230 | * struct pmu - generic performance monitoring unit | 231 | * struct pmu - generic performance monitoring unit |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 63be65437e9e..fc0290f25482 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -8443,7 +8443,13 @@ skip_type: | |||
| 8443 | if (pmu->task_ctx_nr == perf_hw_context) { | 8443 | if (pmu->task_ctx_nr == perf_hw_context) { |
| 8444 | static int hw_context_taken = 0; | 8444 | static int hw_context_taken = 0; |
| 8445 | 8445 | ||
| 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))) | ||
| 8447 | pmu->task_ctx_nr = perf_invalid_context; | 8453 | pmu->task_ctx_nr = perf_invalid_context; |
| 8448 | 8454 | ||
| 8449 | hw_context_taken = 1; | 8455 | hw_context_taken = 1; |
