aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKan Liang <kan.liang@intel.com>2016-03-19 03:20:50 -0400
committerIngo Molnar <mingo@kernel.org>2016-03-31 04:30:35 -0400
commit4b6e2571bf00019e016255ad62b56feb9f498db7 (patch)
treeb647da18853e23bd7013ae43e4ad5125e115875a
parente633c65a1d5859da170a83d537d9762c07d12213 (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.perf8
-rw-r--r--arch/x86/events/intel/Makefile3
-rw-r--r--arch/x86/events/intel/rapl.c121
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
11config 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
11endmenu 19endmenu
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 @@
1obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o cqm.o 1obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o cqm.o
2obj-$(CONFIG_CPU_SUP_INTEL) += cstate.o ds.o knc.o 2obj-$(CONFIG_CPU_SUP_INTEL) += cstate.o ds.o knc.o
3obj-$(CONFIG_CPU_SUP_INTEL) += lbr.o p4.o p6.o pt.o 3obj-$(CONFIG_CPU_SUP_INTEL) += lbr.o p4.o p6.o pt.o
4obj-$(CONFIG_CPU_SUP_INTEL) += rapl.o 4obj-$(CONFIG_PERF_EVENTS_INTEL_RAPL) += intel-rapl.o
5intel-rapl-objs := rapl.o
5obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel-uncore.o 6obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel-uncore.o
6intel-uncore-objs := uncore.o uncore_nhmex.o uncore_snb.o uncore_snbep.o 7intel-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
56MODULE_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
597static struct notifier_block rapl_cpu_nb = {
598 .notifier_call = rapl_cpu_notifier,
599 .priority = CPU_PRI_PERF + 1,
600};
601
595static int rapl_check_hw_unit(bool apply_quirk) 602static 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
663static void __init cleanup_rapl_pmus(void) 670static 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
704struct intel_rapl_init_fun {
705 bool apply_quirk;
706 int cntr_mask;
707 struct attribute **attrs;
708};
709
710static 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
716static 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
722static 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
728static 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
734static 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
694static const struct x86_cpu_id rapl_cpu_match[] __initconst = { 740static 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
755MODULE_DEVICE_TABLE(x86cpu, rapl_cpu_match);
756
699static int __init rapl_pmu_init(void) 757static 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}
769device_initcall(rapl_pmu_init); 802module_init(rapl_pmu_init);
803
804static 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}
812module_exit(intel_rapl_exit);