Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-rmk/perf' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into devel-stable

There's quite a lot here, most of it from Mark Rutland, who has been
working on big.LITTLE PMU support for a while now. His work also brings
us significantly closer to moving the bulk of the CPU PMU driver out
into drivers/, where it can be shared with arm64.

As part of this work, there is a small patch to perf/core, which has
been Acked-by PeterZ and doesn't conflict with tip/perf/core at present.
I've kept that patch on a separate branch, merged in here, so that the
tip guys can pull it too if any unexpected issues crop up.

Please note that there is a conflict with mainline, since we remove
perf_event_cpu.c. The correct resolution is also to remove the file,
since the changes there are already reflected in the rework (and this
resolution is already included in linux-next).

+530 -552
+7
arch/arm/include/asm/perf_event.h
··· 19 19 #define perf_misc_flags(regs) perf_misc_flags(regs) 20 20 #endif 21 21 22 + #define perf_arch_fetch_caller_regs(regs, __ip) { \ 23 + (regs)->ARM_pc = (__ip); \ 24 + (regs)->ARM_fp = (unsigned long) __builtin_frame_address(0); \ 25 + (regs)->ARM_sp = current_stack_pointer; \ 26 + (regs)->ARM_cpsr = SVC_MODE; \ 27 + } 28 + 22 29 #endif /* __ARM_PERF_EVENT_H__ */
+5 -14
arch/arm/include/asm/pmu.h
··· 24 24 * interrupt and passed the address of the low level handler, 25 25 * and can be used to implement any platform specific handling 26 26 * before or after calling it. 27 - * @runtime_resume: an optional handler which will be called by the 28 - * runtime PM framework following a call to pm_runtime_get(). 29 - * Note that if pm_runtime_get() is called more than once in 30 - * succession this handler will only be called once. 31 - * @runtime_suspend: an optional handler which will be called by the 32 - * runtime PM framework following a call to pm_runtime_put(). 33 - * Note that if pm_runtime_get() is called more than once in 34 - * succession this handler will only be called following the 35 - * final call to pm_runtime_put() that actually disables the 36 - * hardware. 37 27 */ 38 28 struct arm_pmu_platdata { 39 29 irqreturn_t (*handle_irq)(int irq, void *dev, 40 30 irq_handler_t pmu_handler); 41 - int (*runtime_resume)(struct device *dev); 42 - int (*runtime_suspend)(struct device *dev); 43 31 }; 44 32 45 33 #ifdef CONFIG_HW_PERF_EVENTS ··· 80 92 struct arm_pmu { 81 93 struct pmu pmu; 82 94 cpumask_t active_irqs; 95 + cpumask_t supported_cpus; 83 96 int *irq_affinity; 84 97 char *name; 85 98 irqreturn_t (*handle_irq)(int irq_num, void *dev); ··· 110 121 }; 111 122 112 123 #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) 113 - 114 - extern const struct dev_pm_ops armpmu_dev_pm_ops; 115 124 116 125 int armpmu_register(struct arm_pmu *armpmu, int type); 117 126 ··· 144 157 145 158 #define XSCALE_PMU_PROBE(_version, _fn) \ 146 159 PMU_PROBE(ARM_CPU_IMP_INTEL << 24 | _version, ARM_PMU_XSCALE_MASK, _fn) 160 + 161 + int arm_pmu_device_probe(struct platform_device *pdev, 162 + const struct of_device_id *of_table, 163 + const struct pmu_probe_info *probe_table); 147 164 148 165 #endif /* CONFIG_HW_PERF_EVENTS */ 149 166
+3 -1
arch/arm/kernel/Makefile
··· 70 70 obj-$(CONFIG_CPU_PJ4B) += pj4-cp0.o 71 71 obj-$(CONFIG_IWMMXT) += iwmmxt.o 72 72 obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o 73 - obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o 73 + obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o \ 74 + perf_event_xscale.o perf_event_v6.o \ 75 + perf_event_v7.o 74 76 CFLAGS_pj4-cp0.o := -marm 75 77 AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt 76 78 obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
+376 -34
arch/arm/kernel/perf_event.c
··· 11 11 */ 12 12 #define pr_fmt(fmt) "hw perfevents: " fmt 13 13 14 + #include <linux/bitmap.h> 15 + #include <linux/cpumask.h> 16 + #include <linux/export.h> 14 17 #include <linux/kernel.h> 18 + #include <linux/of.h> 15 19 #include <linux/platform_device.h> 16 - #include <linux/pm_runtime.h> 20 + #include <linux/slab.h> 21 + #include <linux/spinlock.h> 17 22 #include <linux/irq.h> 18 23 #include <linux/irqdesc.h> 19 24 25 + #include <asm/cputype.h> 20 26 #include <asm/irq_regs.h> 21 27 #include <asm/pmu.h> 22 28 ··· 235 229 int idx; 236 230 int err = 0; 237 231 232 + /* An event following a process won't be stopped earlier */ 233 + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus)) 234 + return -ENOENT; 235 + 238 236 perf_pmu_disable(event->pmu); 239 237 240 238 /* If we don't have a space for the counter then finish early. */ ··· 354 344 armpmu_release_hardware(struct arm_pmu *armpmu) 355 345 { 356 346 armpmu->free_irq(armpmu); 357 - pm_runtime_put_sync(&armpmu->plat_device->dev); 358 347 } 359 348 360 349 static int 361 350 armpmu_reserve_hardware(struct arm_pmu *armpmu) 362 351 { 363 - int err; 364 - struct platform_device *pmu_device = armpmu->plat_device; 365 - 366 - if (!pmu_device) 367 - return -ENODEV; 368 - 369 - pm_runtime_get_sync(&pmu_device->dev); 370 - err = armpmu->request_irq(armpmu, armpmu_dispatch_irq); 352 + int err = armpmu->request_irq(armpmu, armpmu_dispatch_irq); 371 353 if (err) { 372 354 armpmu_release_hardware(armpmu); 373 355 return err; ··· 456 454 int err = 0; 457 455 atomic_t *active_events = &armpmu->active_events; 458 456 457 + /* 458 + * Reject CPU-affine events for CPUs that are of a different class to 459 + * that which this PMU handles. Process-following events (where 460 + * event->cpu == -1) can be migrated between CPUs, and thus we have to 461 + * reject them later (in armpmu_add) if they're scheduled on a 462 + * different class of CPU. 463 + */ 464 + if (event->cpu != -1 && 465 + !cpumask_test_cpu(event->cpu, &armpmu->supported_cpus)) 466 + return -ENOENT; 467 + 459 468 /* does not support taken branch sampling */ 460 469 if (has_branch_stack(event)) 461 470 return -EOPNOTSUPP; ··· 502 489 struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events); 503 490 int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events); 504 491 492 + /* For task-bound events we may be called on other CPUs */ 493 + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus)) 494 + return; 495 + 505 496 if (enabled) 506 497 armpmu->start(armpmu); 507 498 } ··· 513 496 static void armpmu_disable(struct pmu *pmu) 514 497 { 515 498 struct arm_pmu *armpmu = to_arm_pmu(pmu); 499 + 500 + /* For task-bound events we may be called on other CPUs */ 501 + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus)) 502 + return; 503 + 516 504 armpmu->stop(armpmu); 517 505 } 518 506 519 - #ifdef CONFIG_PM 520 - static int armpmu_runtime_resume(struct device *dev) 507 + /* 508 + * In heterogeneous systems, events are specific to a particular 509 + * microarchitecture, and aren't suitable for another. Thus, only match CPUs of 510 + * the same microarchitecture. 511 + */ 512 + static int armpmu_filter_match(struct perf_event *event) 521 513 { 522 - struct arm_pmu_platdata *plat = dev_get_platdata(dev); 523 - 524 - if (plat && plat->runtime_resume) 525 - return plat->runtime_resume(dev); 526 - 527 - return 0; 514 + struct arm_pmu *armpmu = to_arm_pmu(event->pmu); 515 + unsigned int cpu = smp_processor_id(); 516 + return cpumask_test_cpu(cpu, &armpmu->supported_cpus); 528 517 } 529 - 530 - static int armpmu_runtime_suspend(struct device *dev) 531 - { 532 - struct arm_pmu_platdata *plat = dev_get_platdata(dev); 533 - 534 - if (plat && plat->runtime_suspend) 535 - return plat->runtime_suspend(dev); 536 - 537 - return 0; 538 - } 539 - #endif 540 - 541 - const struct dev_pm_ops armpmu_dev_pm_ops = { 542 - SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL) 543 - }; 544 518 545 519 static void armpmu_init(struct arm_pmu *armpmu) 546 520 { ··· 547 539 .start = armpmu_start, 548 540 .stop = armpmu_stop, 549 541 .read = armpmu_read, 542 + .filter_match = armpmu_filter_match, 550 543 }; 551 544 } 552 545 553 546 int armpmu_register(struct arm_pmu *armpmu, int type) 554 547 { 555 548 armpmu_init(armpmu); 556 - pm_runtime_enable(&armpmu->plat_device->dev); 557 549 pr_info("enabled with %s PMU driver, %d counters available\n", 558 550 armpmu->name, armpmu->num_events); 559 551 return perf_pmu_register(&armpmu->pmu, armpmu->name, type); 560 552 } 561 553 554 + /* Set at runtime when we know what CPU type we are. */ 555 + static struct arm_pmu *__oprofile_cpu_pmu; 556 + 557 + /* 558 + * Despite the names, these two functions are CPU-specific and are used 559 + * by the OProfile/perf code. 560 + */ 561 + const char *perf_pmu_name(void) 562 + { 563 + if (!__oprofile_cpu_pmu) 564 + return NULL; 565 + 566 + return __oprofile_cpu_pmu->name; 567 + } 568 + EXPORT_SYMBOL_GPL(perf_pmu_name); 569 + 570 + int perf_num_counters(void) 571 + { 572 + int max_events = 0; 573 + 574 + if (__oprofile_cpu_pmu != NULL) 575 + max_events = __oprofile_cpu_pmu->num_events; 576 + 577 + return max_events; 578 + } 579 + EXPORT_SYMBOL_GPL(perf_num_counters); 580 + 581 + static void cpu_pmu_enable_percpu_irq(void *data) 582 + { 583 + int irq = *(int *)data; 584 + 585 + enable_percpu_irq(irq, IRQ_TYPE_NONE); 586 + } 587 + 588 + static void cpu_pmu_disable_percpu_irq(void *data) 589 + { 590 + int irq = *(int *)data; 591 + 592 + disable_percpu_irq(irq); 593 + } 594 + 595 + static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu) 596 + { 597 + int i, irq, irqs; 598 + struct platform_device *pmu_device = cpu_pmu->plat_device; 599 + struct pmu_hw_events __percpu *hw_events = cpu_pmu->hw_events; 600 + 601 + irqs = min(pmu_device->num_resources, num_possible_cpus()); 602 + 603 + irq = platform_get_irq(pmu_device, 0); 604 + if (irq >= 0 && irq_is_percpu(irq)) { 605 + on_each_cpu(cpu_pmu_disable_percpu_irq, &irq, 1); 606 + free_percpu_irq(irq, &hw_events->percpu_pmu); 607 + } else { 608 + for (i = 0; i < irqs; ++i) { 609 + int cpu = i; 610 + 611 + if (cpu_pmu->irq_affinity) 612 + cpu = cpu_pmu->irq_affinity[i]; 613 + 614 + if (!cpumask_test_and_clear_cpu(cpu, &cpu_pmu->active_irqs)) 615 + continue; 616 + irq = platform_get_irq(pmu_device, i); 617 + if (irq >= 0) 618 + free_irq(irq, per_cpu_ptr(&hw_events->percpu_pmu, cpu)); 619 + } 620 + } 621 + } 622 + 623 + static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler) 624 + { 625 + int i, err, irq, irqs; 626 + struct platform_device *pmu_device = cpu_pmu->plat_device; 627 + struct pmu_hw_events __percpu *hw_events = cpu_pmu->hw_events; 628 + 629 + if (!pmu_device) 630 + return -ENODEV; 631 + 632 + irqs = min(pmu_device->num_resources, num_possible_cpus()); 633 + if (irqs < 1) { 634 + pr_warn_once("perf/ARM: No irqs for PMU defined, sampling events not supported\n"); 635 + return 0; 636 + } 637 + 638 + irq = platform_get_irq(pmu_device, 0); 639 + if (irq >= 0 && irq_is_percpu(irq)) { 640 + err = request_percpu_irq(irq, handler, "arm-pmu", 641 + &hw_events->percpu_pmu); 642 + if (err) { 643 + pr_err("unable to request IRQ%d for ARM PMU counters\n", 644 + irq); 645 + return err; 646 + } 647 + on_each_cpu(cpu_pmu_enable_percpu_irq, &irq, 1); 648 + } else { 649 + for (i = 0; i < irqs; ++i) { 650 + int cpu = i; 651 + 652 + err = 0; 653 + irq = platform_get_irq(pmu_device, i); 654 + if (irq < 0) 655 + continue; 656 + 657 + if (cpu_pmu->irq_affinity) 658 + cpu = cpu_pmu->irq_affinity[i]; 659 + 660 + /* 661 + * If we have a single PMU interrupt that we can't shift, 662 + * assume that we're running on a uniprocessor machine and 663 + * continue. Otherwise, continue without this interrupt. 664 + */ 665 + if (irq_set_affinity(irq, cpumask_of(cpu)) && irqs > 1) { 666 + pr_warn("unable to set irq affinity (irq=%d, cpu=%u)\n", 667 + irq, cpu); 668 + continue; 669 + } 670 + 671 + err = request_irq(irq, handler, 672 + IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu", 673 + per_cpu_ptr(&hw_events->percpu_pmu, cpu)); 674 + if (err) { 675 + pr_err("unable to request IRQ%d for ARM PMU counters\n", 676 + irq); 677 + return err; 678 + } 679 + 680 + cpumask_set_cpu(cpu, &cpu_pmu->active_irqs); 681 + } 682 + } 683 + 684 + return 0; 685 + } 686 + 687 + /* 688 + * PMU hardware loses all context when a CPU goes offline. 689 + * When a CPU is hotplugged back in, since some hardware registers are 690 + * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading 691 + * junk values out of them. 692 + */ 693 + static int cpu_pmu_notify(struct notifier_block *b, unsigned long action, 694 + void *hcpu) 695 + { 696 + int cpu = (unsigned long)hcpu; 697 + struct arm_pmu *pmu = container_of(b, struct arm_pmu, hotplug_nb); 698 + 699 + if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING) 700 + return NOTIFY_DONE; 701 + 702 + if (!cpumask_test_cpu(cpu, &pmu->supported_cpus)) 703 + return NOTIFY_DONE; 704 + 705 + if (pmu->reset) 706 + pmu->reset(pmu); 707 + else 708 + return NOTIFY_DONE; 709 + 710 + return NOTIFY_OK; 711 + } 712 + 713 + static int cpu_pmu_init(struct arm_pmu *cpu_pmu) 714 + { 715 + int err; 716 + int cpu; 717 + struct pmu_hw_events __percpu *cpu_hw_events; 718 + 719 + cpu_hw_events = alloc_percpu(struct pmu_hw_events); 720 + if (!cpu_hw_events) 721 + return -ENOMEM; 722 + 723 + cpu_pmu->hotplug_nb.notifier_call = cpu_pmu_notify; 724 + err = register_cpu_notifier(&cpu_pmu->hotplug_nb); 725 + if (err) 726 + goto out_hw_events; 727 + 728 + for_each_possible_cpu(cpu) { 729 + struct pmu_hw_events *events = per_cpu_ptr(cpu_hw_events, cpu); 730 + raw_spin_lock_init(&events->pmu_lock); 731 + events->percpu_pmu = cpu_pmu; 732 + } 733 + 734 + cpu_pmu->hw_events = cpu_hw_events; 735 + cpu_pmu->request_irq = cpu_pmu_request_irq; 736 + cpu_pmu->free_irq = cpu_pmu_free_irq; 737 + 738 + /* Ensure the PMU has sane values out of reset. */ 739 + if (cpu_pmu->reset) 740 + on_each_cpu_mask(&cpu_pmu->supported_cpus, cpu_pmu->reset, 741 + cpu_pmu, 1); 742 + 743 + /* If no interrupts available, set the corresponding capability flag */ 744 + if (!platform_get_irq(cpu_pmu->plat_device, 0)) 745 + cpu_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; 746 + 747 + return 0; 748 + 749 + out_hw_events: 750 + free_percpu(cpu_hw_events); 751 + return err; 752 + } 753 + 754 + static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu) 755 + { 756 + unregister_cpu_notifier(&cpu_pmu->hotplug_nb); 757 + free_percpu(cpu_pmu->hw_events); 758 + } 759 + 760 + /* 761 + * CPU PMU identification and probing. 762 + */ 763 + static int probe_current_pmu(struct arm_pmu *pmu, 764 + const struct pmu_probe_info *info) 765 + { 766 + int cpu = get_cpu(); 767 + unsigned int cpuid = read_cpuid_id(); 768 + int ret = -ENODEV; 769 + 770 + pr_info("probing PMU on CPU %d\n", cpu); 771 + 772 + for (; info->init != NULL; info++) { 773 + if ((cpuid & info->mask) != info->cpuid) 774 + continue; 775 + ret = info->init(pmu); 776 + break; 777 + } 778 + 779 + put_cpu(); 780 + return ret; 781 + } 782 + 783 + static int of_pmu_irq_cfg(struct arm_pmu *pmu) 784 + { 785 + int i, irq, *irqs; 786 + struct platform_device *pdev = pmu->plat_device; 787 + 788 + /* Don't bother with PPIs; they're already affine */ 789 + irq = platform_get_irq(pdev, 0); 790 + if (irq >= 0 && irq_is_percpu(irq)) 791 + return 0; 792 + 793 + irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL); 794 + if (!irqs) 795 + return -ENOMEM; 796 + 797 + for (i = 0; i < pdev->num_resources; ++i) { 798 + struct device_node *dn; 799 + int cpu; 800 + 801 + dn = of_parse_phandle(pdev->dev.of_node, "interrupt-affinity", 802 + i); 803 + if (!dn) { 804 + pr_warn("Failed to parse %s/interrupt-affinity[%d]\n", 805 + of_node_full_name(pdev->dev.of_node), i); 806 + break; 807 + } 808 + 809 + for_each_possible_cpu(cpu) 810 + if (arch_find_n_match_cpu_physical_id(dn, cpu, NULL)) 811 + break; 812 + 813 + of_node_put(dn); 814 + if (cpu >= nr_cpu_ids) { 815 + pr_warn("Failed to find logical CPU for %s\n", 816 + dn->name); 817 + break; 818 + } 819 + 820 + irqs[i] = cpu; 821 + cpumask_set_cpu(cpu, &pmu->supported_cpus); 822 + } 823 + 824 + if (i == pdev->num_resources) { 825 + pmu->irq_affinity = irqs; 826 + } else { 827 + kfree(irqs); 828 + cpumask_setall(&pmu->supported_cpus); 829 + } 830 + 831 + return 0; 832 + } 833 + 834 + int arm_pmu_device_probe(struct platform_device *pdev, 835 + const struct of_device_id *of_table, 836 + const struct pmu_probe_info *probe_table) 837 + { 838 + const struct of_device_id *of_id; 839 + const int (*init_fn)(struct arm_pmu *); 840 + struct device_node *node = pdev->dev.of_node; 841 + struct arm_pmu *pmu; 842 + int ret = -ENODEV; 843 + 844 + pmu = kzalloc(sizeof(struct arm_pmu), GFP_KERNEL); 845 + if (!pmu) { 846 + pr_info("failed to allocate PMU device!\n"); 847 + return -ENOMEM; 848 + } 849 + 850 + if (!__oprofile_cpu_pmu) 851 + __oprofile_cpu_pmu = pmu; 852 + 853 + pmu->plat_device = pdev; 854 + 855 + if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) { 856 + init_fn = of_id->data; 857 + 858 + ret = of_pmu_irq_cfg(pmu); 859 + if (!ret) 860 + ret = init_fn(pmu); 861 + } else { 862 + ret = probe_current_pmu(pmu, probe_table); 863 + cpumask_setall(&pmu->supported_cpus); 864 + } 865 + 866 + if (ret) { 867 + pr_info("failed to probe PMU!\n"); 868 + goto out_free; 869 + } 870 + 871 + ret = cpu_pmu_init(pmu); 872 + if (ret) 873 + goto out_free; 874 + 875 + ret = armpmu_register(pmu, -1); 876 + if (ret) 877 + goto out_destroy; 878 + 879 + return 0; 880 + 881 + out_destroy: 882 + cpu_pmu_destroy(pmu); 883 + out_free: 884 + pr_info("failed to register PMU devices!\n"); 885 + kfree(pmu); 886 + return ret; 887 + }
-415
arch/arm/kernel/perf_event_cpu.c
··· 1 - /* 2 - * This program is free software; you can redistribute it and/or modify 3 - * it under the terms of the GNU General Public License version 2 as 4 - * published by the Free Software Foundation. 5 - * 6 - * This program is distributed in the hope that it will be useful, 7 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 - * GNU General Public License for more details. 10 - * 11 - * You should have received a copy of the GNU General Public License 12 - * along with this program; if not, write to the Free Software 13 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 14 - * 15 - * Copyright (C) 2012 ARM Limited 16 - * 17 - * Author: Will Deacon <will.deacon@arm.com> 18 - */ 19 - #define pr_fmt(fmt) "CPU PMU: " fmt 20 - 21 - #include <linux/bitmap.h> 22 - #include <linux/export.h> 23 - #include <linux/kernel.h> 24 - #include <linux/of.h> 25 - #include <linux/platform_device.h> 26 - #include <linux/slab.h> 27 - #include <linux/spinlock.h> 28 - #include <linux/irq.h> 29 - #include <linux/irqdesc.h> 30 - 31 - #include <asm/cputype.h> 32 - #include <asm/irq_regs.h> 33 - #include <asm/pmu.h> 34 - 35 - /* Set at runtime when we know what CPU type we are. */ 36 - static struct arm_pmu *cpu_pmu; 37 - 38 - /* 39 - * Despite the names, these two functions are CPU-specific and are used 40 - * by the OProfile/perf code. 41 - */ 42 - const char *perf_pmu_name(void) 43 - { 44 - if (!cpu_pmu) 45 - return NULL; 46 - 47 - return cpu_pmu->name; 48 - } 49 - EXPORT_SYMBOL_GPL(perf_pmu_name); 50 - 51 - int perf_num_counters(void) 52 - { 53 - int max_events = 0; 54 - 55 - if (cpu_pmu != NULL) 56 - max_events = cpu_pmu->num_events; 57 - 58 - return max_events; 59 - } 60 - EXPORT_SYMBOL_GPL(perf_num_counters); 61 - 62 - /* Include the PMU-specific implementations. */ 63 - #include "perf_event_xscale.c" 64 - #include "perf_event_v6.c" 65 - #include "perf_event_v7.c" 66 - 67 - static void cpu_pmu_enable_percpu_irq(void *data) 68 - { 69 - int irq = *(int *)data; 70 - 71 - enable_percpu_irq(irq, IRQ_TYPE_NONE); 72 - } 73 - 74 - static void cpu_pmu_disable_percpu_irq(void *data) 75 - { 76 - int irq = *(int *)data; 77 - 78 - disable_percpu_irq(irq); 79 - } 80 - 81 - static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu) 82 - { 83 - int i, irq, irqs; 84 - struct platform_device *pmu_device = cpu_pmu->plat_device; 85 - struct pmu_hw_events __percpu *hw_events = cpu_pmu->hw_events; 86 - 87 - irqs = min(pmu_device->num_resources, num_possible_cpus()); 88 - 89 - irq = platform_get_irq(pmu_device, 0); 90 - if (irq >= 0 && irq_is_percpu(irq)) { 91 - on_each_cpu(cpu_pmu_disable_percpu_irq, &irq, 1); 92 - free_percpu_irq(irq, &hw_events->percpu_pmu); 93 - } else { 94 - for (i = 0; i < irqs; ++i) { 95 - int cpu = i; 96 - 97 - if (cpu_pmu->irq_affinity) 98 - cpu = cpu_pmu->irq_affinity[i]; 99 - 100 - if (!cpumask_test_and_clear_cpu(cpu, &cpu_pmu->active_irqs)) 101 - continue; 102 - irq = platform_get_irq(pmu_device, i); 103 - if (irq >= 0) 104 - free_irq(irq, per_cpu_ptr(&hw_events->percpu_pmu, cpu)); 105 - } 106 - } 107 - } 108 - 109 - static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler) 110 - { 111 - int i, err, irq, irqs; 112 - struct platform_device *pmu_device = cpu_pmu->plat_device; 113 - struct pmu_hw_events __percpu *hw_events = cpu_pmu->hw_events; 114 - 115 - if (!pmu_device) 116 - return -ENODEV; 117 - 118 - irqs = min(pmu_device->num_resources, num_possible_cpus()); 119 - if (irqs < 1) { 120 - pr_warn_once("perf/ARM: No irqs for PMU defined, sampling events not supported\n"); 121 - return 0; 122 - } 123 - 124 - irq = platform_get_irq(pmu_device, 0); 125 - if (irq >= 0 && irq_is_percpu(irq)) { 126 - err = request_percpu_irq(irq, handler, "arm-pmu", 127 - &hw_events->percpu_pmu); 128 - if (err) { 129 - pr_err("unable to request IRQ%d for ARM PMU counters\n", 130 - irq); 131 - return err; 132 - } 133 - on_each_cpu(cpu_pmu_enable_percpu_irq, &irq, 1); 134 - } else { 135 - for (i = 0; i < irqs; ++i) { 136 - int cpu = i; 137 - 138 - err = 0; 139 - irq = platform_get_irq(pmu_device, i); 140 - if (irq < 0) 141 - continue; 142 - 143 - if (cpu_pmu->irq_affinity) 144 - cpu = cpu_pmu->irq_affinity[i]; 145 - 146 - /* 147 - * If we have a single PMU interrupt that we can't shift, 148 - * assume that we're running on a uniprocessor machine and 149 - * continue. Otherwise, continue without this interrupt. 150 - */ 151 - if (irq_set_affinity(irq, cpumask_of(cpu)) && irqs > 1) { 152 - pr_warn("unable to set irq affinity (irq=%d, cpu=%u)\n", 153 - irq, cpu); 154 - continue; 155 - } 156 - 157 - err = request_irq(irq, handler, 158 - IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu", 159 - per_cpu_ptr(&hw_events->percpu_pmu, cpu)); 160 - if (err) { 161 - pr_err("unable to request IRQ%d for ARM PMU counters\n", 162 - irq); 163 - return err; 164 - } 165 - 166 - cpumask_set_cpu(cpu, &cpu_pmu->active_irqs); 167 - } 168 - } 169 - 170 - return 0; 171 - } 172 - 173 - /* 174 - * PMU hardware loses all context when a CPU goes offline. 175 - * When a CPU is hotplugged back in, since some hardware registers are 176 - * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading 177 - * junk values out of them. 178 - */ 179 - static int cpu_pmu_notify(struct notifier_block *b, unsigned long action, 180 - void *hcpu) 181 - { 182 - struct arm_pmu *pmu = container_of(b, struct arm_pmu, hotplug_nb); 183 - 184 - if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING) 185 - return NOTIFY_DONE; 186 - 187 - if (pmu->reset) 188 - pmu->reset(pmu); 189 - else 190 - return NOTIFY_DONE; 191 - 192 - return NOTIFY_OK; 193 - } 194 - 195 - static int cpu_pmu_init(struct arm_pmu *cpu_pmu) 196 - { 197 - int err; 198 - int cpu; 199 - struct pmu_hw_events __percpu *cpu_hw_events; 200 - 201 - cpu_hw_events = alloc_percpu(struct pmu_hw_events); 202 - if (!cpu_hw_events) 203 - return -ENOMEM; 204 - 205 - cpu_pmu->hotplug_nb.notifier_call = cpu_pmu_notify; 206 - err = register_cpu_notifier(&cpu_pmu->hotplug_nb); 207 - if (err) 208 - goto out_hw_events; 209 - 210 - for_each_possible_cpu(cpu) { 211 - struct pmu_hw_events *events = per_cpu_ptr(cpu_hw_events, cpu); 212 - raw_spin_lock_init(&events->pmu_lock); 213 - events->percpu_pmu = cpu_pmu; 214 - } 215 - 216 - cpu_pmu->hw_events = cpu_hw_events; 217 - cpu_pmu->request_irq = cpu_pmu_request_irq; 218 - cpu_pmu->free_irq = cpu_pmu_free_irq; 219 - 220 - /* Ensure the PMU has sane values out of reset. */ 221 - if (cpu_pmu->reset) 222 - on_each_cpu(cpu_pmu->reset, cpu_pmu, 1); 223 - 224 - /* If no interrupts available, set the corresponding capability flag */ 225 - if (!platform_get_irq(cpu_pmu->plat_device, 0)) 226 - cpu_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; 227 - 228 - return 0; 229 - 230 - out_hw_events: 231 - free_percpu(cpu_hw_events); 232 - return err; 233 - } 234 - 235 - static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu) 236 - { 237 - unregister_cpu_notifier(&cpu_pmu->hotplug_nb); 238 - free_percpu(cpu_pmu->hw_events); 239 - } 240 - 241 - /* 242 - * PMU platform driver and devicetree bindings. 243 - */ 244 - static const struct of_device_id cpu_pmu_of_device_ids[] = { 245 - {.compatible = "arm,cortex-a17-pmu", .data = armv7_a17_pmu_init}, 246 - {.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init}, 247 - {.compatible = "arm,cortex-a12-pmu", .data = armv7_a12_pmu_init}, 248 - {.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init}, 249 - {.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init}, 250 - {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init}, 251 - {.compatible = "arm,cortex-a5-pmu", .data = armv7_a5_pmu_init}, 252 - {.compatible = "arm,arm11mpcore-pmu", .data = armv6mpcore_pmu_init}, 253 - {.compatible = "arm,arm1176-pmu", .data = armv6_1176_pmu_init}, 254 - {.compatible = "arm,arm1136-pmu", .data = armv6_1136_pmu_init}, 255 - {.compatible = "qcom,krait-pmu", .data = krait_pmu_init}, 256 - {.compatible = "qcom,scorpion-pmu", .data = scorpion_pmu_init}, 257 - {.compatible = "qcom,scorpion-mp-pmu", .data = scorpion_mp_pmu_init}, 258 - {}, 259 - }; 260 - 261 - static struct platform_device_id cpu_pmu_plat_device_ids[] = { 262 - {.name = "arm-pmu"}, 263 - {.name = "armv6-pmu"}, 264 - {.name = "armv7-pmu"}, 265 - {.name = "xscale-pmu"}, 266 - {}, 267 - }; 268 - 269 - static const struct pmu_probe_info pmu_probe_table[] = { 270 - ARM_PMU_PROBE(ARM_CPU_PART_ARM1136, armv6_1136_pmu_init), 271 - ARM_PMU_PROBE(ARM_CPU_PART_ARM1156, armv6_1156_pmu_init), 272 - ARM_PMU_PROBE(ARM_CPU_PART_ARM1176, armv6_1176_pmu_init), 273 - ARM_PMU_PROBE(ARM_CPU_PART_ARM11MPCORE, armv6mpcore_pmu_init), 274 - ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A8, armv7_a8_pmu_init), 275 - ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A9, armv7_a9_pmu_init), 276 - XSCALE_PMU_PROBE(ARM_CPU_XSCALE_ARCH_V1, xscale1pmu_init), 277 - XSCALE_PMU_PROBE(ARM_CPU_XSCALE_ARCH_V2, xscale2pmu_init), 278 - { /* sentinel value */ } 279 - }; 280 - 281 - /* 282 - * CPU PMU identification and probing. 283 - */ 284 - static int probe_current_pmu(struct arm_pmu *pmu) 285 - { 286 - int cpu = get_cpu(); 287 - unsigned int cpuid = read_cpuid_id(); 288 - int ret = -ENODEV; 289 - const struct pmu_probe_info *info; 290 - 291 - pr_info("probing PMU on CPU %d\n", cpu); 292 - 293 - for (info = pmu_probe_table; info->init != NULL; info++) { 294 - if ((cpuid & info->mask) != info->cpuid) 295 - continue; 296 - ret = info->init(pmu); 297 - break; 298 - } 299 - 300 - put_cpu(); 301 - return ret; 302 - } 303 - 304 - static int of_pmu_irq_cfg(struct platform_device *pdev) 305 - { 306 - int i; 307 - int *irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL); 308 - 309 - if (!irqs) 310 - return -ENOMEM; 311 - 312 - for (i = 0; i < pdev->num_resources; ++i) { 313 - struct device_node *dn; 314 - int cpu; 315 - 316 - dn = of_parse_phandle(pdev->dev.of_node, "interrupt-affinity", 317 - i); 318 - if (!dn) { 319 - pr_warn("Failed to parse %s/interrupt-affinity[%d]\n", 320 - of_node_full_name(dn), i); 321 - break; 322 - } 323 - 324 - for_each_possible_cpu(cpu) 325 - if (arch_find_n_match_cpu_physical_id(dn, cpu, NULL)) 326 - break; 327 - 328 - of_node_put(dn); 329 - if (cpu >= nr_cpu_ids) { 330 - pr_warn("Failed to find logical CPU for %s\n", 331 - dn->name); 332 - break; 333 - } 334 - 335 - irqs[i] = cpu; 336 - } 337 - 338 - if (i == pdev->num_resources) 339 - cpu_pmu->irq_affinity = irqs; 340 - else 341 - kfree(irqs); 342 - 343 - return 0; 344 - } 345 - 346 - static int cpu_pmu_device_probe(struct platform_device *pdev) 347 - { 348 - const struct of_device_id *of_id; 349 - const int (*init_fn)(struct arm_pmu *); 350 - struct device_node *node = pdev->dev.of_node; 351 - struct arm_pmu *pmu; 352 - int ret = -ENODEV; 353 - 354 - if (cpu_pmu) { 355 - pr_info("attempt to register multiple PMU devices!\n"); 356 - return -ENOSPC; 357 - } 358 - 359 - pmu = kzalloc(sizeof(struct arm_pmu), GFP_KERNEL); 360 - if (!pmu) { 361 - pr_info("failed to allocate PMU device!\n"); 362 - return -ENOMEM; 363 - } 364 - 365 - cpu_pmu = pmu; 366 - cpu_pmu->plat_device = pdev; 367 - 368 - if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) { 369 - init_fn = of_id->data; 370 - 371 - ret = of_pmu_irq_cfg(pdev); 372 - if (!ret) 373 - ret = init_fn(pmu); 374 - } else { 375 - ret = probe_current_pmu(pmu); 376 - } 377 - 378 - if (ret) { 379 - pr_info("failed to probe PMU!\n"); 380 - goto out_free; 381 - } 382 - 383 - ret = cpu_pmu_init(cpu_pmu); 384 - if (ret) 385 - goto out_free; 386 - 387 - ret = armpmu_register(cpu_pmu, -1); 388 - if (ret) 389 - goto out_destroy; 390 - 391 - return 0; 392 - 393 - out_destroy: 394 - cpu_pmu_destroy(cpu_pmu); 395 - out_free: 396 - pr_info("failed to register PMU devices!\n"); 397 - kfree(pmu); 398 - return ret; 399 - } 400 - 401 - static struct platform_driver cpu_pmu_driver = { 402 - .driver = { 403 - .name = "arm-pmu", 404 - .pm = &armpmu_dev_pm_ops, 405 - .of_match_table = cpu_pmu_of_device_ids, 406 - }, 407 - .probe = cpu_pmu_device_probe, 408 - .id_table = cpu_pmu_plat_device_ids, 409 - }; 410 - 411 - static int __init register_pmu_driver(void) 412 - { 413 - return platform_driver_register(&cpu_pmu_driver); 414 - } 415 - device_initcall(register_pmu_driver);
+37 -14
arch/arm/kernel/perf_event_v6.c
··· 31 31 */ 32 32 33 33 #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) 34 + 35 + #include <asm/cputype.h> 36 + #include <asm/irq_regs.h> 37 + #include <asm/pmu.h> 38 + 39 + #include <linux/of.h> 40 + #include <linux/platform_device.h> 41 + 34 42 enum armv6_perf_types { 35 43 ARMV6_PERFCTR_ICACHE_MISS = 0x0, 36 44 ARMV6_PERFCTR_IBUF_STALL = 0x1, ··· 551 543 552 544 return 0; 553 545 } 554 - #else 555 - static int armv6_1136_pmu_init(struct arm_pmu *cpu_pmu) 546 + 547 + static struct of_device_id armv6_pmu_of_device_ids[] = { 548 + {.compatible = "arm,arm11mpcore-pmu", .data = armv6mpcore_pmu_init}, 549 + {.compatible = "arm,arm1176-pmu", .data = armv6_1176_pmu_init}, 550 + {.compatible = "arm,arm1136-pmu", .data = armv6_1136_pmu_init}, 551 + { /* sentinel value */ } 552 + }; 553 + 554 + static const struct pmu_probe_info armv6_pmu_probe_table[] = { 555 + ARM_PMU_PROBE(ARM_CPU_PART_ARM1136, armv6_1136_pmu_init), 556 + ARM_PMU_PROBE(ARM_CPU_PART_ARM1156, armv6_1156_pmu_init), 557 + ARM_PMU_PROBE(ARM_CPU_PART_ARM1176, armv6_1176_pmu_init), 558 + ARM_PMU_PROBE(ARM_CPU_PART_ARM11MPCORE, armv6mpcore_pmu_init), 559 + { /* sentinel value */ } 560 + }; 561 + 562 + static int armv6_pmu_device_probe(struct platform_device *pdev) 556 563 { 557 - return -ENODEV; 564 + return arm_pmu_device_probe(pdev, armv6_pmu_of_device_ids, 565 + armv6_pmu_probe_table); 558 566 } 559 567 560 - static int armv6_1156_pmu_init(struct arm_pmu *cpu_pmu) 561 - { 562 - return -ENODEV; 563 - } 568 + static struct platform_driver armv6_pmu_driver = { 569 + .driver = { 570 + .name = "armv6-pmu", 571 + .of_match_table = armv6_pmu_of_device_ids, 572 + }, 573 + .probe = armv6_pmu_device_probe, 574 + }; 564 575 565 - static int armv6_1176_pmu_init(struct arm_pmu *cpu_pmu) 576 + static int __init register_armv6_pmu_driver(void) 566 577 { 567 - return -ENODEV; 578 + return platform_driver_register(&armv6_pmu_driver); 568 579 } 569 - 570 - static int armv6mpcore_pmu_init(struct arm_pmu *cpu_pmu) 571 - { 572 - return -ENODEV; 573 - } 580 + device_initcall(register_armv6_pmu_driver); 574 581 #endif /* CONFIG_CPU_V6 || CONFIG_CPU_V6K */
+63 -68
arch/arm/kernel/perf_event_v7.c
··· 19 19 #ifdef CONFIG_CPU_V7 20 20 21 21 #include <asm/cp15.h> 22 + #include <asm/cputype.h> 23 + #include <asm/irq_regs.h> 24 + #include <asm/pmu.h> 22 25 #include <asm/vfp.h> 23 26 #include "../vfp/vfpinstr.h" 27 + 28 + #include <linux/of.h> 29 + #include <linux/platform_device.h> 24 30 25 31 /* 26 32 * Common ARMv7 event types ··· 1062 1056 cpu_pmu->max_period = (1LLU << 32) - 1; 1063 1057 }; 1064 1058 1065 - static u32 armv7_read_num_pmnc_events(void) 1059 + static void armv7_read_num_pmnc_events(void *info) 1066 1060 { 1067 - u32 nb_cnt; 1061 + int *nb_cnt = info; 1068 1062 1069 1063 /* Read the nb of CNTx counters supported from PMNC */ 1070 - nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; 1064 + *nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; 1071 1065 1072 - /* Add the CPU cycles counter and return */ 1073 - return nb_cnt + 1; 1066 + /* Add the CPU cycles counter */ 1067 + *nb_cnt += 1; 1068 + } 1069 + 1070 + static int armv7_probe_num_events(struct arm_pmu *arm_pmu) 1071 + { 1072 + return smp_call_function_any(&arm_pmu->supported_cpus, 1073 + armv7_read_num_pmnc_events, 1074 + &arm_pmu->num_events, 1); 1074 1075 } 1075 1076 1076 1077 static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu) ··· 1085 1072 armv7pmu_init(cpu_pmu); 1086 1073 cpu_pmu->name = "armv7_cortex_a8"; 1087 1074 cpu_pmu->map_event = armv7_a8_map_event; 1088 - cpu_pmu->num_events = armv7_read_num_pmnc_events(); 1089 - return 0; 1075 + return armv7_probe_num_events(cpu_pmu); 1090 1076 } 1091 1077 1092 1078 static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu) ··· 1093 1081 armv7pmu_init(cpu_pmu); 1094 1082 cpu_pmu->name = "armv7_cortex_a9"; 1095 1083 cpu_pmu->map_event = armv7_a9_map_event; 1096 - cpu_pmu->num_events = armv7_read_num_pmnc_events(); 1097 - return 0; 1084 + return armv7_probe_num_events(cpu_pmu); 1098 1085 } 1099 1086 1100 1087 static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu) ··· 1101 1090 armv7pmu_init(cpu_pmu); 1102 1091 cpu_pmu->name = "armv7_cortex_a5"; 1103 1092 cpu_pmu->map_event = armv7_a5_map_event; 1104 - cpu_pmu->num_events = armv7_read_num_pmnc_events(); 1105 - return 0; 1093 + return armv7_probe_num_events(cpu_pmu); 1106 1094 } 1107 1095 1108 1096 static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu) ··· 1109 1099 armv7pmu_init(cpu_pmu); 1110 1100 cpu_pmu->name = "armv7_cortex_a15"; 1111 1101 cpu_pmu->map_event = armv7_a15_map_event; 1112 - cpu_pmu->num_events = armv7_read_num_pmnc_events(); 1113 1102 cpu_pmu->set_event_filter = armv7pmu_set_event_filter; 1114 - return 0; 1103 + return armv7_probe_num_events(cpu_pmu); 1115 1104 } 1116 1105 1117 1106 static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu) ··· 1118 1109 armv7pmu_init(cpu_pmu); 1119 1110 cpu_pmu->name = "armv7_cortex_a7"; 1120 1111 cpu_pmu->map_event = armv7_a7_map_event; 1121 - cpu_pmu->num_events = armv7_read_num_pmnc_events(); 1122 1112 cpu_pmu->set_event_filter = armv7pmu_set_event_filter; 1123 - return 0; 1113 + return armv7_probe_num_events(cpu_pmu); 1124 1114 } 1125 1115 1126 1116 static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu) ··· 1127 1119 armv7pmu_init(cpu_pmu); 1128 1120 cpu_pmu->name = "armv7_cortex_a12"; 1129 1121 cpu_pmu->map_event = armv7_a12_map_event; 1130 - cpu_pmu->num_events = armv7_read_num_pmnc_events(); 1131 1122 cpu_pmu->set_event_filter = armv7pmu_set_event_filter; 1132 - return 0; 1123 + return armv7_probe_num_events(cpu_pmu); 1133 1124 } 1134 1125 1135 1126 static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu) 1136 1127 { 1137 - armv7_a12_pmu_init(cpu_pmu); 1128 + int ret = armv7_a12_pmu_init(cpu_pmu); 1138 1129 cpu_pmu->name = "armv7_cortex_a17"; 1139 - return 0; 1130 + return ret; 1140 1131 } 1141 1132 1142 1133 /* ··· 1515 1508 cpu_pmu->map_event = krait_map_event_no_branch; 1516 1509 else 1517 1510 cpu_pmu->map_event = krait_map_event; 1518 - cpu_pmu->num_events = armv7_read_num_pmnc_events(); 1519 1511 cpu_pmu->set_event_filter = armv7pmu_set_event_filter; 1520 1512 cpu_pmu->reset = krait_pmu_reset; 1521 1513 cpu_pmu->enable = krait_pmu_enable_event; 1522 1514 cpu_pmu->disable = krait_pmu_disable_event; 1523 1515 cpu_pmu->get_event_idx = krait_pmu_get_event_idx; 1524 1516 cpu_pmu->clear_event_idx = krait_pmu_clear_event_idx; 1525 - return 0; 1517 + return armv7_probe_num_events(cpu_pmu); 1526 1518 } 1527 1519 1528 1520 /* ··· 1839 1833 armv7pmu_init(cpu_pmu); 1840 1834 cpu_pmu->name = "armv7_scorpion"; 1841 1835 cpu_pmu->map_event = scorpion_map_event; 1842 - cpu_pmu->num_events = armv7_read_num_pmnc_events(); 1843 1836 cpu_pmu->reset = scorpion_pmu_reset; 1844 1837 cpu_pmu->enable = scorpion_pmu_enable_event; 1845 1838 cpu_pmu->disable = scorpion_pmu_disable_event; 1846 1839 cpu_pmu->get_event_idx = scorpion_pmu_get_event_idx; 1847 1840 cpu_pmu->clear_event_idx = scorpion_pmu_clear_event_idx; 1848 - return 0; 1841 + return armv7_probe_num_events(cpu_pmu); 1849 1842 } 1850 1843 1851 1844 static int scorpion_mp_pmu_init(struct arm_pmu *cpu_pmu) ··· 1852 1847 armv7pmu_init(cpu_pmu); 1853 1848 cpu_pmu->name = "armv7_scorpion_mp"; 1854 1849 cpu_pmu->map_event = scorpion_map_event; 1855 - cpu_pmu->num_events = armv7_read_num_pmnc_events(); 1856 1850 cpu_pmu->reset = scorpion_pmu_reset; 1857 1851 cpu_pmu->enable = scorpion_pmu_enable_event; 1858 1852 cpu_pmu->disable = scorpion_pmu_disable_event; 1859 1853 cpu_pmu->get_event_idx = scorpion_pmu_get_event_idx; 1860 1854 cpu_pmu->clear_event_idx = scorpion_pmu_clear_event_idx; 1861 - return 0; 1862 - } 1863 - #else 1864 - static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu) 1865 - { 1866 - return -ENODEV; 1855 + return armv7_probe_num_events(cpu_pmu); 1867 1856 } 1868 1857 1869 - static inline int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu) 1858 + static const struct of_device_id armv7_pmu_of_device_ids[] = { 1859 + {.compatible = "arm,cortex-a17-pmu", .data = armv7_a17_pmu_init}, 1860 + {.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init}, 1861 + {.compatible = "arm,cortex-a12-pmu", .data = armv7_a12_pmu_init}, 1862 + {.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init}, 1863 + {.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init}, 1864 + {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init}, 1865 + {.compatible = "arm,cortex-a5-pmu", .data = armv7_a5_pmu_init}, 1866 + {.compatible = "qcom,krait-pmu", .data = krait_pmu_init}, 1867 + {.compatible = "qcom,scorpion-pmu", .data = scorpion_pmu_init}, 1868 + {.compatible = "qcom,scorpion-mp-pmu", .data = scorpion_mp_pmu_init}, 1869 + {}, 1870 + }; 1871 + 1872 + static const struct pmu_probe_info armv7_pmu_probe_table[] = { 1873 + ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A8, armv7_a8_pmu_init), 1874 + ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A9, armv7_a9_pmu_init), 1875 + { /* sentinel value */ } 1876 + }; 1877 + 1878 + 1879 + static int armv7_pmu_device_probe(struct platform_device *pdev) 1870 1880 { 1871 - return -ENODEV; 1881 + return arm_pmu_device_probe(pdev, armv7_pmu_of_device_ids, 1882 + armv7_pmu_probe_table); 1872 1883 } 1873 1884 1874 - static inline int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu) 1875 - { 1876 - return -ENODEV; 1877 - } 1885 + static struct platform_driver armv7_pmu_driver = { 1886 + .driver = { 1887 + .name = "armv7-pmu", 1888 + .of_match_table = armv7_pmu_of_device_ids, 1889 + }, 1890 + .probe = armv7_pmu_device_probe, 1891 + }; 1878 1892 1879 - static inline int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu) 1893 + static int __init register_armv7_pmu_driver(void) 1880 1894 { 1881 - return -ENODEV; 1895 + return platform_driver_register(&armv7_pmu_driver); 1882 1896 } 1883 - 1884 - static inline int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu) 1885 - { 1886 - return -ENODEV; 1887 - } 1888 - 1889 - static inline int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu) 1890 - { 1891 - return -ENODEV; 1892 - } 1893 - 1894 - static inline int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu) 1895 - { 1896 - return -ENODEV; 1897 - } 1898 - 1899 - static inline int krait_pmu_init(struct arm_pmu *cpu_pmu) 1900 - { 1901 - return -ENODEV; 1902 - } 1903 - 1904 - static inline int scorpion_pmu_init(struct arm_pmu *cpu_pmu) 1905 - { 1906 - return -ENODEV; 1907 - } 1908 - 1909 - static inline int scorpion_mp_pmu_init(struct arm_pmu *cpu_pmu) 1910 - { 1911 - return -ENODEV; 1912 - } 1897 + device_initcall(register_armv7_pmu_driver); 1913 1898 #endif /* CONFIG_CPU_V7 */
+27 -5
arch/arm/kernel/perf_event_xscale.c
··· 13 13 */ 14 14 15 15 #ifdef CONFIG_CPU_XSCALE 16 + 17 + #include <asm/cputype.h> 18 + #include <asm/irq_regs.h> 19 + #include <asm/pmu.h> 20 + 21 + #include <linux/of.h> 22 + #include <linux/platform_device.h> 23 + 16 24 enum xscale_perf_types { 17 25 XSCALE_PERFCTR_ICACHE_MISS = 0x00, 18 26 XSCALE_PERFCTR_ICACHE_NO_DELIVER = 0x01, ··· 748 740 749 741 return 0; 750 742 } 751 - #else 752 - static inline int xscale1pmu_init(struct arm_pmu *cpu_pmu) 743 + 744 + static const struct pmu_probe_info xscale_pmu_probe_table[] = { 745 + XSCALE_PMU_PROBE(ARM_CPU_XSCALE_ARCH_V1, xscale1pmu_init), 746 + XSCALE_PMU_PROBE(ARM_CPU_XSCALE_ARCH_V2, xscale2pmu_init), 747 + { /* sentinel value */ } 748 + }; 749 + 750 + static int xscale_pmu_device_probe(struct platform_device *pdev) 753 751 { 754 - return -ENODEV; 752 + return arm_pmu_device_probe(pdev, NULL, xscale_pmu_probe_table); 755 753 } 756 754 757 - static inline int xscale2pmu_init(struct arm_pmu *cpu_pmu) 755 + static struct platform_driver xscale_pmu_driver = { 756 + .driver = { 757 + .name = "xscale-pmu", 758 + }, 759 + .probe = xscale_pmu_device_probe, 760 + }; 761 + 762 + static int __init register_xscale_pmu_driver(void) 758 763 { 759 - return -ENODEV; 764 + return platform_driver_register(&xscale_pmu_driver); 760 765 } 766 + device_initcall(register_xscale_pmu_driver); 761 767 #endif /* CONFIG_CPU_XSCALE */
+5
include/linux/perf_event.h
··· 304 304 * Free pmu-private AUX data structures 305 305 */ 306 306 void (*free_aux) (void *aux); /* optional */ 307 + 308 + /* 309 + * Filter events for PMU-specific reasons. 310 + */ 311 + int (*filter_match) (struct perf_event *event); /* optional */ 307 312 }; 308 313 309 314 /**
+7 -1
kernel/events/core.c
··· 1506 1506 1507 1507 core_initcall(perf_workqueue_init); 1508 1508 1509 + static inline int pmu_filter_match(struct perf_event *event) 1510 + { 1511 + struct pmu *pmu = event->pmu; 1512 + return pmu->filter_match ? pmu->filter_match(event) : 1; 1513 + } 1514 + 1509 1515 static inline int 1510 1516 event_filter_match(struct perf_event *event) 1511 1517 { 1512 1518 return (event->cpu == -1 || event->cpu == smp_processor_id()) 1513 - && perf_cgroup_match(event); 1519 + && perf_cgroup_match(event) && pmu_filter_match(event); 1514 1520 } 1515 1521 1516 1522 static void