aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/perf_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/perf_event.c')
-rw-r--r--arch/arm/kernel/perf_event.c347
1 files changed, 51 insertions, 296 deletions
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index ab243b87118d..93971b1a4f0b 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -12,68 +12,15 @@
12 */ 12 */
13#define pr_fmt(fmt) "hw perfevents: " fmt 13#define pr_fmt(fmt) "hw perfevents: " fmt
14 14
15#include <linux/bitmap.h>
16#include <linux/interrupt.h>
17#include <linux/kernel.h> 15#include <linux/kernel.h>
18#include <linux/export.h>
19#include <linux/perf_event.h>
20#include <linux/platform_device.h> 16#include <linux/platform_device.h>
21#include <linux/spinlock.h> 17#include <linux/pm_runtime.h>
22#include <linux/uaccess.h> 18#include <linux/uaccess.h>
23 19
24#include <asm/cputype.h>
25#include <asm/irq.h>
26#include <asm/irq_regs.h> 20#include <asm/irq_regs.h>
27#include <asm/pmu.h> 21#include <asm/pmu.h>
28#include <asm/stacktrace.h> 22#include <asm/stacktrace.h>
29 23
30/*
31 * ARMv6 supports a maximum of 3 events, starting from index 0. If we add
32 * another platform that supports more, we need to increase this to be the
33 * largest of all platforms.
34 *
35 * ARMv7 supports up to 32 events:
36 * cycle counter CCNT + 31 events counters CNT0..30.
37 * Cortex-A8 has 1+4 counters, Cortex-A9 has 1+6 counters.
38 */
39#define ARMPMU_MAX_HWEVENTS 32
40
41static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
42static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
43static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
44
45#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
46
47/* Set at runtime when we know what CPU type we are. */
48static struct arm_pmu *cpu_pmu;
49
50const char *perf_pmu_name(void)
51{
52 if (!cpu_pmu)
53 return NULL;
54
55 return cpu_pmu->pmu.name;
56}
57EXPORT_SYMBOL_GPL(perf_pmu_name);
58
59int perf_num_counters(void)
60{
61 int max_events = 0;
62
63 if (cpu_pmu != NULL)
64 max_events = cpu_pmu->num_events;
65
66 return max_events;
67}
68EXPORT_SYMBOL_GPL(perf_num_counters);
69
70#define HW_OP_UNSUPPORTED 0xFFFF
71
72#define C(_x) \
73 PERF_COUNT_HW_CACHE_##_x
74
75#define CACHE_OP_UNSUPPORTED 0xFFFF
76
77static int 24static int
78armpmu_map_cache_event(const unsigned (*cache_map) 25armpmu_map_cache_event(const unsigned (*cache_map)
79 [PERF_COUNT_HW_CACHE_MAX] 26 [PERF_COUNT_HW_CACHE_MAX]
@@ -104,7 +51,7 @@ armpmu_map_cache_event(const unsigned (*cache_map)
104} 51}
105 52
106static int 53static int
107armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) 54armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
108{ 55{
109 int mapping = (*event_map)[config]; 56 int mapping = (*event_map)[config];
110 return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; 57 return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
@@ -116,19 +63,20 @@ armpmu_map_raw_event(u32 raw_event_mask, u64 config)
116 return (int)(config & raw_event_mask); 63 return (int)(config & raw_event_mask);
117} 64}
118 65
119static int map_cpu_event(struct perf_event *event, 66int
120 const unsigned (*event_map)[PERF_COUNT_HW_MAX], 67armpmu_map_event(struct perf_event *event,
121 const unsigned (*cache_map) 68 const unsigned (*event_map)[PERF_COUNT_HW_MAX],
122 [PERF_COUNT_HW_CACHE_MAX] 69 const unsigned (*cache_map)
123 [PERF_COUNT_HW_CACHE_OP_MAX] 70 [PERF_COUNT_HW_CACHE_MAX]
124 [PERF_COUNT_HW_CACHE_RESULT_MAX], 71 [PERF_COUNT_HW_CACHE_OP_MAX]
125 u32 raw_event_mask) 72 [PERF_COUNT_HW_CACHE_RESULT_MAX],
73 u32 raw_event_mask)
126{ 74{
127 u64 config = event->attr.config; 75 u64 config = event->attr.config;
128 76
129 switch (event->attr.type) { 77 switch (event->attr.type) {
130 case PERF_TYPE_HARDWARE: 78 case PERF_TYPE_HARDWARE:
131 return armpmu_map_event(event_map, config); 79 return armpmu_map_hw_event(event_map, config);
132 case PERF_TYPE_HW_CACHE: 80 case PERF_TYPE_HW_CACHE:
133 return armpmu_map_cache_event(cache_map, config); 81 return armpmu_map_cache_event(cache_map, config);
134 case PERF_TYPE_RAW: 82 case PERF_TYPE_RAW:
@@ -222,7 +170,6 @@ armpmu_stop(struct perf_event *event, int flags)
222 */ 170 */
223 if (!(hwc->state & PERF_HES_STOPPED)) { 171 if (!(hwc->state & PERF_HES_STOPPED)) {
224 armpmu->disable(hwc, hwc->idx); 172 armpmu->disable(hwc, hwc->idx);
225 barrier(); /* why? */
226 armpmu_event_update(event, hwc, hwc->idx); 173 armpmu_event_update(event, hwc, hwc->idx);
227 hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; 174 hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
228 } 175 }
@@ -350,99 +297,41 @@ validate_group(struct perf_event *event)
350 return 0; 297 return 0;
351} 298}
352 299
353static irqreturn_t armpmu_platform_irq(int irq, void *dev) 300static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
354{ 301{
355 struct arm_pmu *armpmu = (struct arm_pmu *) dev; 302 struct arm_pmu *armpmu = (struct arm_pmu *) dev;
356 struct platform_device *plat_device = armpmu->plat_device; 303 struct platform_device *plat_device = armpmu->plat_device;
357 struct arm_pmu_platdata *plat = dev_get_platdata(&plat_device->dev); 304 struct arm_pmu_platdata *plat = dev_get_platdata(&plat_device->dev);
358 305
359 return plat->handle_irq(irq, dev, armpmu->handle_irq); 306 if (plat && plat->handle_irq)
307 return plat->handle_irq(irq, dev, armpmu->handle_irq);
308 else
309 return armpmu->handle_irq(irq, dev);
360} 310}
361 311
362static void 312static void
363armpmu_release_hardware(struct arm_pmu *armpmu) 313armpmu_release_hardware(struct arm_pmu *armpmu)
364{ 314{
365 int i, irq, irqs; 315 armpmu->free_irq();
366 struct platform_device *pmu_device = armpmu->plat_device; 316 pm_runtime_put_sync(&armpmu->plat_device->dev);
367 struct arm_pmu_platdata *plat =
368 dev_get_platdata(&pmu_device->dev);
369
370 irqs = min(pmu_device->num_resources, num_possible_cpus());
371
372 for (i = 0; i < irqs; ++i) {
373 if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
374 continue;
375 irq = platform_get_irq(pmu_device, i);
376 if (irq >= 0) {
377 if (plat && plat->disable_irq)
378 plat->disable_irq(irq);
379 free_irq(irq, armpmu);
380 }
381 }
382
383 release_pmu(armpmu->type);
384} 317}
385 318
386static int 319static int
387armpmu_reserve_hardware(struct arm_pmu *armpmu) 320armpmu_reserve_hardware(struct arm_pmu *armpmu)
388{ 321{
389 struct arm_pmu_platdata *plat; 322 int err;
390 irq_handler_t handle_irq;
391 int i, err, irq, irqs;
392 struct platform_device *pmu_device = armpmu->plat_device; 323 struct platform_device *pmu_device = armpmu->plat_device;
393 324
394 if (!pmu_device) 325 if (!pmu_device)
395 return -ENODEV; 326 return -ENODEV;
396 327
397 err = reserve_pmu(armpmu->type); 328 pm_runtime_get_sync(&pmu_device->dev);
329 err = armpmu->request_irq(armpmu_dispatch_irq);
398 if (err) { 330 if (err) {
399 pr_warning("unable to reserve pmu\n"); 331 armpmu_release_hardware(armpmu);
400 return err; 332 return err;
401 } 333 }
402 334
403 plat = dev_get_platdata(&pmu_device->dev);
404 if (plat && plat->handle_irq)
405 handle_irq = armpmu_platform_irq;
406 else
407 handle_irq = armpmu->handle_irq;
408
409 irqs = min(pmu_device->num_resources, num_possible_cpus());
410 if (irqs < 1) {
411 pr_err("no irqs for PMUs defined\n");
412 return -ENODEV;
413 }
414
415 for (i = 0; i < irqs; ++i) {
416 err = 0;
417 irq = platform_get_irq(pmu_device, i);
418 if (irq < 0)
419 continue;
420
421 /*
422 * If we have a single PMU interrupt that we can't shift,
423 * assume that we're running on a uniprocessor machine and
424 * continue. Otherwise, continue without this interrupt.
425 */
426 if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
427 pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
428 irq, i);
429 continue;
430 }
431
432 err = request_irq(irq, handle_irq,
433 IRQF_DISABLED | IRQF_NOBALANCING,
434 "arm-pmu", armpmu);
435 if (err) {
436 pr_err("unable to request IRQ%d for ARM PMU counters\n",
437 irq);
438 armpmu_release_hardware(armpmu);
439 return err;
440 } else if (plat && plat->enable_irq)
441 plat->enable_irq(irq);
442
443 cpumask_set_cpu(i, &armpmu->active_irqs);
444 }
445
446 return 0; 335 return 0;
447} 336}
448 337
@@ -581,6 +470,32 @@ static void armpmu_disable(struct pmu *pmu)
581 armpmu->stop(); 470 armpmu->stop();
582} 471}
583 472
473#ifdef CONFIG_PM_RUNTIME
474static int armpmu_runtime_resume(struct device *dev)
475{
476 struct arm_pmu_platdata *plat = dev_get_platdata(dev);
477
478 if (plat && plat->runtime_resume)
479 return plat->runtime_resume(dev);
480
481 return 0;
482}
483
484static int armpmu_runtime_suspend(struct device *dev)
485{
486 struct arm_pmu_platdata *plat = dev_get_platdata(dev);
487
488 if (plat && plat->runtime_suspend)
489 return plat->runtime_suspend(dev);
490
491 return 0;
492}
493#endif
494
495const struct dev_pm_ops armpmu_dev_pm_ops = {
496 SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
497};
498
584static void __init armpmu_init(struct arm_pmu *armpmu) 499static void __init armpmu_init(struct arm_pmu *armpmu)
585{ 500{
586 atomic_set(&armpmu->active_events, 0); 501 atomic_set(&armpmu->active_events, 0);
@@ -598,174 +513,14 @@ static void __init armpmu_init(struct arm_pmu *armpmu)
598 }; 513 };
599} 514}
600 515
601int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type) 516int armpmu_register(struct arm_pmu *armpmu, char *name, int type)
602{ 517{
603 armpmu_init(armpmu); 518 armpmu_init(armpmu);
519 pr_info("enabled with %s PMU driver, %d counters available\n",
520 armpmu->name, armpmu->num_events);
604 return perf_pmu_register(&armpmu->pmu, name, type); 521 return perf_pmu_register(&armpmu->pmu, name, type);
605} 522}
606 523
607/* Include the PMU-specific implementations. */
608#include "perf_event_xscale.c"
609#include "perf_event_v6.c"
610#include "perf_event_v7.c"
611
612/*
613 * Ensure the PMU has sane values out of reset.
614 * This requires SMP to be available, so exists as a separate initcall.
615 */
616static int __init
617cpu_pmu_reset(void)
618{
619 if (cpu_pmu && cpu_pmu->reset)
620 return on_each_cpu(cpu_pmu->reset, NULL, 1);
621 return 0;
622}
623arch_initcall(cpu_pmu_reset);
624
625/*
626 * PMU platform driver and devicetree bindings.
627 */
628static struct of_device_id armpmu_of_device_ids[] = {
629 {.compatible = "arm,cortex-a9-pmu"},
630 {.compatible = "arm,cortex-a8-pmu"},
631 {.compatible = "arm,arm1136-pmu"},
632 {.compatible = "arm,arm1176-pmu"},
633 {},
634};
635
636static struct platform_device_id armpmu_plat_device_ids[] = {
637 {.name = "arm-pmu"},
638 {},
639};
640
641static int __devinit armpmu_device_probe(struct platform_device *pdev)
642{
643 if (!cpu_pmu)
644 return -ENODEV;
645
646 cpu_pmu->plat_device = pdev;
647 return 0;
648}
649
650static struct platform_driver armpmu_driver = {
651 .driver = {
652 .name = "arm-pmu",
653 .of_match_table = armpmu_of_device_ids,
654 },
655 .probe = armpmu_device_probe,
656 .id_table = armpmu_plat_device_ids,
657};
658
659static int __init register_pmu_driver(void)
660{
661 return platform_driver_register(&armpmu_driver);
662}
663device_initcall(register_pmu_driver);
664
665static struct pmu_hw_events *armpmu_get_cpu_events(void)
666{
667 return &__get_cpu_var(cpu_hw_events);
668}
669
670static void __init cpu_pmu_init(struct arm_pmu *armpmu)
671{
672 int cpu;
673 for_each_possible_cpu(cpu) {
674 struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu);
675 events->events = per_cpu(hw_events, cpu);
676 events->used_mask = per_cpu(used_mask, cpu);
677 raw_spin_lock_init(&events->pmu_lock);
678 }
679 armpmu->get_hw_events = armpmu_get_cpu_events;
680 armpmu->type = ARM_PMU_DEVICE_CPU;
681}
682
683/*
684 * PMU hardware loses all context when a CPU goes offline.
685 * When a CPU is hotplugged back in, since some hardware registers are
686 * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
687 * junk values out of them.
688 */
689static int __cpuinit pmu_cpu_notify(struct notifier_block *b,
690 unsigned long action, void *hcpu)
691{
692 if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
693 return NOTIFY_DONE;
694
695 if (cpu_pmu && cpu_pmu->reset)
696 cpu_pmu->reset(NULL);
697
698 return NOTIFY_OK;
699}
700
701static struct notifier_block __cpuinitdata pmu_cpu_notifier = {
702 .notifier_call = pmu_cpu_notify,
703};
704
705/*
706 * CPU PMU identification and registration.
707 */
708static int __init
709init_hw_perf_events(void)
710{
711 unsigned long cpuid = read_cpuid_id();
712 unsigned long implementor = (cpuid & 0xFF000000) >> 24;
713 unsigned long part_number = (cpuid & 0xFFF0);
714
715 /* ARM Ltd CPUs. */
716 if (0x41 == implementor) {
717 switch (part_number) {
718 case 0xB360: /* ARM1136 */
719 case 0xB560: /* ARM1156 */
720 case 0xB760: /* ARM1176 */
721 cpu_pmu = armv6pmu_init();
722 break;
723 case 0xB020: /* ARM11mpcore */
724 cpu_pmu = armv6mpcore_pmu_init();
725 break;
726 case 0xC080: /* Cortex-A8 */
727 cpu_pmu = armv7_a8_pmu_init();
728 break;
729 case 0xC090: /* Cortex-A9 */
730 cpu_pmu = armv7_a9_pmu_init();
731 break;
732 case 0xC050: /* Cortex-A5 */
733 cpu_pmu = armv7_a5_pmu_init();
734 break;
735 case 0xC0F0: /* Cortex-A15 */
736 cpu_pmu = armv7_a15_pmu_init();
737 break;
738 case 0xC070: /* Cortex-A7 */
739 cpu_pmu = armv7_a7_pmu_init();
740 break;
741 }
742 /* Intel CPUs [xscale]. */
743 } else if (0x69 == implementor) {
744 part_number = (cpuid >> 13) & 0x7;
745 switch (part_number) {
746 case 1:
747 cpu_pmu = xscale1pmu_init();
748 break;
749 case 2:
750 cpu_pmu = xscale2pmu_init();
751 break;
752 }
753 }
754
755 if (cpu_pmu) {
756 pr_info("enabled with %s PMU driver, %d counters available\n",
757 cpu_pmu->name, cpu_pmu->num_events);
758 cpu_pmu_init(cpu_pmu);
759 register_cpu_notifier(&pmu_cpu_notifier);
760 armpmu_register(cpu_pmu, cpu_pmu->name, PERF_TYPE_RAW);
761 } else {
762 pr_info("no hardware support available\n");
763 }
764
765 return 0;
766}
767early_initcall(init_hw_perf_events);
768
769/* 524/*
770 * Callchain handling code. 525 * Callchain handling code.
771 */ 526 */