diff options
author | Kan Liang <kan.liang@intel.com> | 2016-03-19 03:20:50 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-03-31 04:30:35 -0400 |
commit | 4b6e2571bf00019e016255ad62b56feb9f498db7 (patch) | |
tree | b647da18853e23bd7013ae43e4ad5125e115875a | |
parent | e633c65a1d5859da170a83d537d9762c07d12213 (diff) |
x86/perf/intel/rapl: Make the Intel RAPL PMU driver modular
By default, the RAPL driver will be built into the kernel. If it is
configured as a module, the supported CPU model can be auto loaded.
Also clean up the code of rapl_pmu_init().
Based-on-a-patch-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Kan Liang <kan.liang@intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Link: http://lkml.kernel.org/r/1458372050-2420-2-git-send-email-kan.liang@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/Kconfig.perf | 8 | ||||
-rw-r--r-- | arch/x86/events/intel/Makefile | 3 | ||||
-rw-r--r-- | arch/x86/events/intel/rapl.c | 121 |
3 files changed, 92 insertions, 40 deletions
diff --git a/arch/x86/Kconfig.perf b/arch/x86/Kconfig.perf index 90b7f5878c96..b239ad5d0a4e 100644 --- a/arch/x86/Kconfig.perf +++ b/arch/x86/Kconfig.perf | |||
@@ -8,4 +8,12 @@ config PERF_EVENTS_INTEL_UNCORE | |||
8 | Include support for Intel uncore performance events. These are | 8 | Include support for Intel uncore performance events. These are |
9 | available on NehalemEX and more modern processors. | 9 | available on NehalemEX and more modern processors. |
10 | 10 | ||
11 | config PERF_EVENTS_INTEL_RAPL | ||
12 | tristate "Intel rapl performance events" | ||
13 | depends on PERF_EVENTS && CPU_SUP_INTEL && PCI | ||
14 | default y | ||
15 | ---help--- | ||
16 | Include support for Intel rapl performance events for power | ||
17 | monitoring on modern processors. | ||
18 | |||
11 | endmenu | 19 | endmenu |
diff --git a/arch/x86/events/intel/Makefile b/arch/x86/events/intel/Makefile index a6c744871a73..27adbbab9910 100644 --- a/arch/x86/events/intel/Makefile +++ b/arch/x86/events/intel/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o cqm.o | 1 | obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o cqm.o |
2 | obj-$(CONFIG_CPU_SUP_INTEL) += cstate.o ds.o knc.o | 2 | obj-$(CONFIG_CPU_SUP_INTEL) += cstate.o ds.o knc.o |
3 | obj-$(CONFIG_CPU_SUP_INTEL) += lbr.o p4.o p6.o pt.o | 3 | obj-$(CONFIG_CPU_SUP_INTEL) += lbr.o p4.o p6.o pt.o |
4 | obj-$(CONFIG_CPU_SUP_INTEL) += rapl.o | 4 | obj-$(CONFIG_PERF_EVENTS_INTEL_RAPL) += intel-rapl.o |
5 | intel-rapl-objs := rapl.o | ||
5 | obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel-uncore.o | 6 | obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel-uncore.o |
6 | intel-uncore-objs := uncore.o uncore_nhmex.o uncore_snb.o uncore_snbep.o | 7 | intel-uncore-objs := uncore.o uncore_nhmex.o uncore_snb.o uncore_snbep.o |
diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c index 70c93f9b03ac..e657de1923c2 100644 --- a/arch/x86/events/intel/rapl.c +++ b/arch/x86/events/intel/rapl.c | |||
@@ -53,6 +53,8 @@ | |||
53 | #include <asm/cpu_device_id.h> | 53 | #include <asm/cpu_device_id.h> |
54 | #include "../perf_event.h" | 54 | #include "../perf_event.h" |
55 | 55 | ||
56 | MODULE_LICENSE("GPL"); | ||
57 | |||
56 | /* | 58 | /* |
57 | * RAPL energy status counters | 59 | * RAPL energy status counters |
58 | */ | 60 | */ |
@@ -592,6 +594,11 @@ static int rapl_cpu_notifier(struct notifier_block *self, | |||
592 | return NOTIFY_OK; | 594 | return NOTIFY_OK; |
593 | } | 595 | } |
594 | 596 | ||
597 | static struct notifier_block rapl_cpu_nb = { | ||
598 | .notifier_call = rapl_cpu_notifier, | ||
599 | .priority = CPU_PRI_PERF + 1, | ||
600 | }; | ||
601 | |||
595 | static int rapl_check_hw_unit(bool apply_quirk) | 602 | static int rapl_check_hw_unit(bool apply_quirk) |
596 | { | 603 | { |
597 | u64 msr_rapl_power_unit_bits; | 604 | u64 msr_rapl_power_unit_bits; |
@@ -660,7 +667,7 @@ static int __init rapl_prepare_cpus(void) | |||
660 | return 0; | 667 | return 0; |
661 | } | 668 | } |
662 | 669 | ||
663 | static void __init cleanup_rapl_pmus(void) | 670 | static void cleanup_rapl_pmus(void) |
664 | { | 671 | { |
665 | int i; | 672 | int i; |
666 | 673 | ||
@@ -691,51 +698,77 @@ static int __init init_rapl_pmus(void) | |||
691 | return 0; | 698 | return 0; |
692 | } | 699 | } |
693 | 700 | ||
701 | #define X86_RAPL_MODEL_MATCH(model, init) \ | ||
702 | { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&init } | ||
703 | |||
704 | struct intel_rapl_init_fun { | ||
705 | bool apply_quirk; | ||
706 | int cntr_mask; | ||
707 | struct attribute **attrs; | ||
708 | }; | ||
709 | |||
710 | static const struct intel_rapl_init_fun snb_rapl_init __initconst = { | ||
711 | .apply_quirk = false, | ||
712 | .cntr_mask = RAPL_IDX_CLN, | ||
713 | .attrs = rapl_events_cln_attr, | ||
714 | }; | ||
715 | |||
716 | static const struct intel_rapl_init_fun hsx_rapl_init __initconst = { | ||
717 | .apply_quirk = true, | ||
718 | .cntr_mask = RAPL_IDX_SRV, | ||
719 | .attrs = rapl_events_srv_attr, | ||
720 | }; | ||
721 | |||
722 | static const struct intel_rapl_init_fun hsw_rapl_init __initconst = { | ||
723 | .apply_quirk = false, | ||
724 | .cntr_mask = RAPL_IDX_HSW, | ||
725 | .attrs = rapl_events_hsw_attr, | ||
726 | }; | ||
727 | |||
728 | static const struct intel_rapl_init_fun snbep_rapl_init __initconst = { | ||
729 | .apply_quirk = false, | ||
730 | .cntr_mask = RAPL_IDX_SRV, | ||
731 | .attrs = rapl_events_srv_attr, | ||
732 | }; | ||
733 | |||
734 | static const struct intel_rapl_init_fun knl_rapl_init __initconst = { | ||
735 | .apply_quirk = true, | ||
736 | .cntr_mask = RAPL_IDX_KNL, | ||
737 | .attrs = rapl_events_knl_attr, | ||
738 | }; | ||
739 | |||
694 | static const struct x86_cpu_id rapl_cpu_match[] __initconst = { | 740 | static const struct x86_cpu_id rapl_cpu_match[] __initconst = { |
695 | [0] = { .vendor = X86_VENDOR_INTEL, .family = 6 }, | 741 | X86_RAPL_MODEL_MATCH(42, snb_rapl_init), /* Sandy Bridge */ |
696 | [1] = {}, | 742 | X86_RAPL_MODEL_MATCH(58, snb_rapl_init), /* Ivy Bridge */ |
743 | X86_RAPL_MODEL_MATCH(63, hsx_rapl_init), /* Haswell-Server */ | ||
744 | X86_RAPL_MODEL_MATCH(79, hsx_rapl_init), /* Broadwell-Server */ | ||
745 | X86_RAPL_MODEL_MATCH(60, hsw_rapl_init), /* Haswell */ | ||
746 | X86_RAPL_MODEL_MATCH(69, hsw_rapl_init), /* Haswell-Celeron */ | ||
747 | X86_RAPL_MODEL_MATCH(61, hsw_rapl_init), /* Broadwell */ | ||
748 | X86_RAPL_MODEL_MATCH(71, hsw_rapl_init), /* Broadwell-H */ | ||
749 | X86_RAPL_MODEL_MATCH(45, snbep_rapl_init), /* Sandy Bridge-EP */ | ||
750 | X86_RAPL_MODEL_MATCH(62, snbep_rapl_init), /* IvyTown */ | ||
751 | X86_RAPL_MODEL_MATCH(87, knl_rapl_init), /* Knights Landing */ | ||
752 | {}, | ||
697 | }; | 753 | }; |
698 | 754 | ||
755 | MODULE_DEVICE_TABLE(x86cpu, rapl_cpu_match); | ||
756 | |||
699 | static int __init rapl_pmu_init(void) | 757 | static int __init rapl_pmu_init(void) |
700 | { | 758 | { |
701 | bool apply_quirk = false; | 759 | const struct x86_cpu_id *id; |
760 | struct intel_rapl_init_fun *rapl_init; | ||
761 | bool apply_quirk; | ||
702 | int ret; | 762 | int ret; |
703 | 763 | ||
704 | if (!x86_match_cpu(rapl_cpu_match)) | 764 | id = x86_match_cpu(rapl_cpu_match); |
765 | if (!id) | ||
705 | return -ENODEV; | 766 | return -ENODEV; |
706 | 767 | ||
707 | switch (boot_cpu_data.x86_model) { | 768 | rapl_init = (struct intel_rapl_init_fun *)id->driver_data; |
708 | case 42: /* Sandy Bridge */ | 769 | apply_quirk = rapl_init->apply_quirk; |
709 | case 58: /* Ivy Bridge */ | 770 | rapl_cntr_mask = rapl_init->cntr_mask; |
710 | rapl_cntr_mask = RAPL_IDX_CLN; | 771 | rapl_pmu_events_group.attrs = rapl_init->attrs; |
711 | rapl_pmu_events_group.attrs = rapl_events_cln_attr; | ||
712 | break; | ||
713 | case 63: /* Haswell-Server */ | ||
714 | case 79: /* Broadwell-Server */ | ||
715 | apply_quirk = true; | ||
716 | rapl_cntr_mask = RAPL_IDX_SRV; | ||
717 | rapl_pmu_events_group.attrs = rapl_events_srv_attr; | ||
718 | break; | ||
719 | case 60: /* Haswell */ | ||
720 | case 69: /* Haswell-Celeron */ | ||
721 | case 61: /* Broadwell */ | ||
722 | case 71: /* Broadwell-H */ | ||
723 | rapl_cntr_mask = RAPL_IDX_HSW; | ||
724 | rapl_pmu_events_group.attrs = rapl_events_hsw_attr; | ||
725 | break; | ||
726 | case 45: /* Sandy Bridge-EP */ | ||
727 | case 62: /* IvyTown */ | ||
728 | rapl_cntr_mask = RAPL_IDX_SRV; | ||
729 | rapl_pmu_events_group.attrs = rapl_events_srv_attr; | ||
730 | break; | ||
731 | case 87: /* Knights Landing */ | ||
732 | apply_quirk = true; | ||
733 | rapl_cntr_mask = RAPL_IDX_KNL; | ||
734 | rapl_pmu_events_group.attrs = rapl_events_knl_attr; | ||
735 | break; | ||
736 | default: | ||
737 | return -ENODEV; | ||
738 | } | ||
739 | 772 | ||
740 | ret = rapl_check_hw_unit(apply_quirk); | 773 | ret = rapl_check_hw_unit(apply_quirk); |
741 | if (ret) | 774 | if (ret) |
@@ -755,7 +788,7 @@ static int __init rapl_pmu_init(void) | |||
755 | if (ret) | 788 | if (ret) |
756 | goto out; | 789 | goto out; |
757 | 790 | ||
758 | __perf_cpu_notifier(rapl_cpu_notifier); | 791 | __register_cpu_notifier(&rapl_cpu_nb); |
759 | cpu_notifier_register_done(); | 792 | cpu_notifier_register_done(); |
760 | rapl_advertise(); | 793 | rapl_advertise(); |
761 | return 0; | 794 | return 0; |
@@ -766,4 +799,14 @@ out: | |||
766 | cpu_notifier_register_done(); | 799 | cpu_notifier_register_done(); |
767 | return ret; | 800 | return ret; |
768 | } | 801 | } |
769 | device_initcall(rapl_pmu_init); | 802 | module_init(rapl_pmu_init); |
803 | |||
804 | static void __exit intel_rapl_exit(void) | ||
805 | { | ||
806 | cpu_notifier_register_begin(); | ||
807 | __unregister_cpu_notifier(&rapl_cpu_nb); | ||
808 | perf_pmu_unregister(&rapl_pmus->pmu); | ||
809 | cleanup_rapl_pmus(); | ||
810 | cpu_notifier_register_done(); | ||
811 | } | ||
812 | module_exit(intel_rapl_exit); | ||