aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2018-02-05 11:41:58 -0500
committerWill Deacon <will.deacon@arm.com>2018-02-20 06:34:54 -0500
commit0dc1a1851af1d593eee248b94c1277c7c7ccbbce (patch)
treef32aed65915b0416167c0ec6e867ce0a25fc2307
parentd3d5aac206b4e9e569a22fe1811c909dde17587c (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.c17
-rw-r--r--drivers/perf/arm_pmu_acpi.c2
-rw-r--r--include/linux/perf/arm_pmu.h1
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
763struct arm_pmu *armpmu_alloc(void) 763static 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
820struct arm_pmu *armpmu_alloc(void)
821{
822 return __armpmu_alloc(GFP_KERNEL);
823}
824
825struct arm_pmu *armpmu_alloc_atomic(void)
826{
827 return __armpmu_alloc(GFP_ATOMIC);
828}
829
830
820void armpmu_free(struct arm_pmu *pmu) 831void 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 */
159struct arm_pmu *armpmu_alloc(void); 159struct arm_pmu *armpmu_alloc(void);
160struct arm_pmu *armpmu_alloc_atomic(void);
160void armpmu_free(struct arm_pmu *pmu); 161void armpmu_free(struct arm_pmu *pmu);
161int armpmu_register(struct arm_pmu *pmu); 162int armpmu_register(struct arm_pmu *pmu);
162int armpmu_request_irq(struct arm_pmu *armpmu, int cpu); 163int armpmu_request_irq(struct arm_pmu *armpmu, int cpu);