diff options
author | Mark Rutland <mark.rutland@arm.com> | 2018-02-05 11:41:58 -0500 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2018-02-20 06:34:54 -0500 |
commit | 0dc1a1851af1d593eee248b94c1277c7c7ccbbce (patch) | |
tree | f32aed65915b0416167c0ec6e867ce0a25fc2307 | |
parent | d3d5aac206b4e9e569a22fe1811c909dde17587c (diff) |
arm_pmu: add armpmu_alloc_atomic()
In ACPI systems, we don't know the makeup of CPUs until we hotplug them
on, and thus have to allocate the PMU datastructures at hotplug time.
Thus, we must use GFP_ATOMIC allocations.
Let's add an armpmu_alloc_atomic() that we can use in this case.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r-- | drivers/perf/arm_pmu.c | 17 | ||||
-rw-r--r-- | drivers/perf/arm_pmu_acpi.c | 2 | ||||
-rw-r--r-- | include/linux/perf/arm_pmu.h | 1 |
3 files changed, 16 insertions, 4 deletions
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 373dfd7d8a1d..4f73c5e8d623 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c | |||
@@ -760,18 +760,18 @@ static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu) | |||
760 | &cpu_pmu->node); | 760 | &cpu_pmu->node); |
761 | } | 761 | } |
762 | 762 | ||
763 | struct arm_pmu *armpmu_alloc(void) | 763 | static struct arm_pmu *__armpmu_alloc(gfp_t flags) |
764 | { | 764 | { |
765 | struct arm_pmu *pmu; | 765 | struct arm_pmu *pmu; |
766 | int cpu; | 766 | int cpu; |
767 | 767 | ||
768 | pmu = kzalloc(sizeof(*pmu), GFP_KERNEL); | 768 | pmu = kzalloc(sizeof(*pmu), flags); |
769 | if (!pmu) { | 769 | if (!pmu) { |
770 | pr_info("failed to allocate PMU device!\n"); | 770 | pr_info("failed to allocate PMU device!\n"); |
771 | goto out; | 771 | goto out; |
772 | } | 772 | } |
773 | 773 | ||
774 | pmu->hw_events = alloc_percpu(struct pmu_hw_events); | 774 | pmu->hw_events = alloc_percpu_gfp(struct pmu_hw_events, flags); |
775 | if (!pmu->hw_events) { | 775 | if (!pmu->hw_events) { |
776 | pr_info("failed to allocate per-cpu PMU data.\n"); | 776 | pr_info("failed to allocate per-cpu PMU data.\n"); |
777 | goto out_free_pmu; | 777 | goto out_free_pmu; |
@@ -817,6 +817,17 @@ out: | |||
817 | return NULL; | 817 | return NULL; |
818 | } | 818 | } |
819 | 819 | ||
820 | struct arm_pmu *armpmu_alloc(void) | ||
821 | { | ||
822 | return __armpmu_alloc(GFP_KERNEL); | ||
823 | } | ||
824 | |||
825 | struct arm_pmu *armpmu_alloc_atomic(void) | ||
826 | { | ||
827 | return __armpmu_alloc(GFP_ATOMIC); | ||
828 | } | ||
829 | |||
830 | |||
820 | void armpmu_free(struct arm_pmu *pmu) | 831 | void armpmu_free(struct arm_pmu *pmu) |
821 | { | 832 | { |
822 | free_percpu(pmu->hw_events); | 833 | free_percpu(pmu->hw_events); |
diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c index 705f1a390e31..30c5f2bbce59 100644 --- a/drivers/perf/arm_pmu_acpi.c +++ b/drivers/perf/arm_pmu_acpi.c | |||
@@ -127,7 +127,7 @@ static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void) | |||
127 | return pmu; | 127 | return pmu; |
128 | } | 128 | } |
129 | 129 | ||
130 | pmu = armpmu_alloc(); | 130 | pmu = armpmu_alloc_atomic(); |
131 | if (!pmu) { | 131 | if (!pmu) { |
132 | pr_warn("Unable to allocate PMU for CPU%d\n", | 132 | pr_warn("Unable to allocate PMU for CPU%d\n", |
133 | smp_processor_id()); | 133 | smp_processor_id()); |
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index 899bc7ef0881..1f8bb83ef42f 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h | |||
@@ -157,6 +157,7 @@ static inline int arm_pmu_acpi_probe(armpmu_init_fn init_fn) { return 0; } | |||
157 | 157 | ||
158 | /* Internal functions only for core arm_pmu code */ | 158 | /* Internal functions only for core arm_pmu code */ |
159 | struct arm_pmu *armpmu_alloc(void); | 159 | struct arm_pmu *armpmu_alloc(void); |
160 | struct arm_pmu *armpmu_alloc_atomic(void); | ||
160 | void armpmu_free(struct arm_pmu *pmu); | 161 | void armpmu_free(struct arm_pmu *pmu); |
161 | int armpmu_register(struct arm_pmu *pmu); | 162 | int armpmu_register(struct arm_pmu *pmu); |
162 | int armpmu_request_irq(struct arm_pmu *armpmu, int cpu); | 163 | int armpmu_request_irq(struct arm_pmu *armpmu, int cpu); |