aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKan Liang <kan.liang@intel.com>2016-03-20 04:33:36 -0400
committerIngo Molnar <mingo@kernel.org>2016-03-31 04:30:34 -0400
commite633c65a1d5859da170a83d537d9762c07d12213 (patch)
tree73310d311d977f374f23aab743f4a5baa50816d2
parent84c48d8d01b74a2b98c164513ca5e37c73166825 (diff)
x86/perf/intel/uncore: Make the Intel uncore PMU driver modular
By default, the uncore driver will be built into the kernel. If it is configured as a module, the supported CPU model can be auto loaded. This patch also cleans up the code of uncore_cpu_init() and uncore_pci_init(). Based-on-a-patch-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Kan Liang <kan.liang@intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> 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/1458462817-2475-1-git-send-email-kan.liang@intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/Kconfig6
-rw-r--r--arch/x86/Kconfig.perf11
-rw-r--r--arch/x86/events/Makefile9
-rw-r--r--arch/x86/events/intel/Makefile6
-rw-r--r--arch/x86/events/intel/uncore.c216
5 files changed, 148 insertions, 100 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index a313c0e7e165..496218b8236b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -160,10 +160,6 @@ config INSTRUCTION_DECODER
160 def_bool y 160 def_bool y
161 depends on KPROBES || PERF_EVENTS || UPROBES 161 depends on KPROBES || PERF_EVENTS || UPROBES
162 162
163config PERF_EVENTS_INTEL_UNCORE
164 def_bool y
165 depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
166
167config OUTPUT_FORMAT 163config OUTPUT_FORMAT
168 string 164 string
169 default "elf32-i386" if X86_32 165 default "elf32-i386" if X86_32
@@ -1042,6 +1038,8 @@ config X86_THERMAL_VECTOR
1042 def_bool y 1038 def_bool y
1043 depends on X86_MCE_INTEL 1039 depends on X86_MCE_INTEL
1044 1040
1041source "arch/x86/Kconfig.perf"
1042
1045config X86_LEGACY_VM86 1043config X86_LEGACY_VM86
1046 bool "Legacy VM86 support" 1044 bool "Legacy VM86 support"
1047 default n 1045 default n
diff --git a/arch/x86/Kconfig.perf b/arch/x86/Kconfig.perf
new file mode 100644
index 000000000000..90b7f5878c96
--- /dev/null
+++ b/arch/x86/Kconfig.perf
@@ -0,0 +1,11 @@
1menu "Performance monitoring"
2
3config PERF_EVENTS_INTEL_UNCORE
4 tristate "Intel uncore performance events"
5 depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
6 default y
7 ---help---
8 Include support for Intel uncore performance events. These are
9 available on NehalemEX and more modern processors.
10
11endmenu
diff --git a/arch/x86/events/Makefile b/arch/x86/events/Makefile
index f59618a39990..1d392c39fe56 100644
--- a/arch/x86/events/Makefile
+++ b/arch/x86/events/Makefile
@@ -6,9 +6,6 @@ obj-$(CONFIG_X86_LOCAL_APIC) += amd/ibs.o msr.o
6ifdef CONFIG_AMD_IOMMU 6ifdef CONFIG_AMD_IOMMU
7obj-$(CONFIG_CPU_SUP_AMD) += amd/iommu.o 7obj-$(CONFIG_CPU_SUP_AMD) += amd/iommu.o
8endif 8endif
9obj-$(CONFIG_CPU_SUP_INTEL) += intel/core.o intel/bts.o intel/cqm.o 9
10obj-$(CONFIG_CPU_SUP_INTEL) += intel/cstate.o intel/ds.o intel/knc.o 10obj-$(CONFIG_CPU_SUP_INTEL) += msr.o
11obj-$(CONFIG_CPU_SUP_INTEL) += intel/lbr.o intel/p4.o intel/p6.o intel/pt.o 11obj-$(CONFIG_CPU_SUP_INTEL) += intel/
12obj-$(CONFIG_CPU_SUP_INTEL) += intel/rapl.o msr.o
13obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel/uncore.o intel/uncore_nhmex.o
14obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel/uncore_snb.o intel/uncore_snbep.o
diff --git a/arch/x86/events/intel/Makefile b/arch/x86/events/intel/Makefile
new file mode 100644
index 000000000000..a6c744871a73
--- /dev/null
+++ b/arch/x86/events/intel/Makefile
@@ -0,0 +1,6 @@
1obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o cqm.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
4obj-$(CONFIG_CPU_SUP_INTEL) += rapl.o
5obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel-uncore.o
6intel-uncore-objs := uncore.o uncore_nhmex.o uncore_snb.o uncore_snbep.o
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 7012d18bb293..17734a6ef474 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1,3 +1,4 @@
1#include <asm/cpu_device_id.h>
1#include "uncore.h" 2#include "uncore.h"
2 3
3static struct intel_uncore_type *empty_uncore[] = { NULL, }; 4static struct intel_uncore_type *empty_uncore[] = { NULL, };
@@ -21,6 +22,8 @@ static struct event_constraint uncore_constraint_fixed =
21struct event_constraint uncore_constraint_empty = 22struct event_constraint uncore_constraint_empty =
22 EVENT_CONSTRAINT(0, 0, 0); 23 EVENT_CONSTRAINT(0, 0, 0);
23 24
25MODULE_LICENSE("GPL");
26
24static int uncore_pcibus_to_physid(struct pci_bus *bus) 27static int uncore_pcibus_to_physid(struct pci_bus *bus)
25{ 28{
26 struct pci2phy_map *map; 29 struct pci2phy_map *map;
@@ -754,7 +757,7 @@ static void uncore_pmu_unregister(struct intel_uncore_pmu *pmu)
754 pmu->registered = false; 757 pmu->registered = false;
755} 758}
756 759
757static void __init __uncore_exit_boxes(struct intel_uncore_type *type, int cpu) 760static void __uncore_exit_boxes(struct intel_uncore_type *type, int cpu)
758{ 761{
759 struct intel_uncore_pmu *pmu = type->pmus; 762 struct intel_uncore_pmu *pmu = type->pmus;
760 struct intel_uncore_box *box; 763 struct intel_uncore_box *box;
@@ -770,7 +773,7 @@ static void __init __uncore_exit_boxes(struct intel_uncore_type *type, int cpu)
770 } 773 }
771} 774}
772 775
773static void __init uncore_exit_boxes(void *dummy) 776static void uncore_exit_boxes(void *dummy)
774{ 777{
775 struct intel_uncore_type **types; 778 struct intel_uncore_type **types;
776 779
@@ -787,7 +790,7 @@ static void uncore_free_boxes(struct intel_uncore_pmu *pmu)
787 kfree(pmu->boxes); 790 kfree(pmu->boxes);
788} 791}
789 792
790static void __init uncore_type_exit(struct intel_uncore_type *type) 793static void uncore_type_exit(struct intel_uncore_type *type)
791{ 794{
792 struct intel_uncore_pmu *pmu = type->pmus; 795 struct intel_uncore_pmu *pmu = type->pmus;
793 int i; 796 int i;
@@ -804,7 +807,7 @@ static void __init uncore_type_exit(struct intel_uncore_type *type)
804 type->events_group = NULL; 807 type->events_group = NULL;
805} 808}
806 809
807static void __init uncore_types_exit(struct intel_uncore_type **types) 810static void uncore_types_exit(struct intel_uncore_type **types)
808{ 811{
809 for (; *types; types++) 812 for (; *types; types++)
810 uncore_type_exit(*types); 813 uncore_type_exit(*types);
@@ -989,46 +992,6 @@ static int __init uncore_pci_init(void)
989 size_t size; 992 size_t size;
990 int ret; 993 int ret;
991 994
992 switch (boot_cpu_data.x86_model) {
993 case 45: /* Sandy Bridge-EP */
994 ret = snbep_uncore_pci_init();
995 break;
996 case 62: /* Ivy Bridge-EP */
997 ret = ivbep_uncore_pci_init();
998 break;
999 case 63: /* Haswell-EP */
1000 ret = hswep_uncore_pci_init();
1001 break;
1002 case 79: /* BDX-EP */
1003 case 86: /* BDX-DE */
1004 ret = bdx_uncore_pci_init();
1005 break;
1006 case 42: /* Sandy Bridge */
1007 ret = snb_uncore_pci_init();
1008 break;
1009 case 58: /* Ivy Bridge */
1010 ret = ivb_uncore_pci_init();
1011 break;
1012 case 60: /* Haswell */
1013 case 69: /* Haswell Celeron */
1014 ret = hsw_uncore_pci_init();
1015 break;
1016 case 61: /* Broadwell */
1017 ret = bdw_uncore_pci_init();
1018 break;
1019 case 87: /* Knights Landing */
1020 ret = knl_uncore_pci_init();
1021 break;
1022 case 94: /* SkyLake */
1023 ret = skl_uncore_pci_init();
1024 break;
1025 default:
1026 return -ENODEV;
1027 }
1028
1029 if (ret)
1030 return ret;
1031
1032 size = max_packages * sizeof(struct pci_extra_dev); 995 size = max_packages * sizeof(struct pci_extra_dev);
1033 uncore_extra_pci_dev = kzalloc(size, GFP_KERNEL); 996 uncore_extra_pci_dev = kzalloc(size, GFP_KERNEL);
1034 if (!uncore_extra_pci_dev) { 997 if (!uncore_extra_pci_dev) {
@@ -1060,7 +1023,7 @@ err:
1060 return ret; 1023 return ret;
1061} 1024}
1062 1025
1063static void __init uncore_pci_exit(void) 1026static void uncore_pci_exit(void)
1064{ 1027{
1065 if (pcidrv_registered) { 1028 if (pcidrv_registered) {
1066 pcidrv_registered = false; 1029 pcidrv_registered = false;
@@ -1287,46 +1250,6 @@ static int __init uncore_cpu_init(void)
1287{ 1250{
1288 int ret; 1251 int ret;
1289 1252
1290 switch (boot_cpu_data.x86_model) {
1291 case 26: /* Nehalem */
1292 case 30:
1293 case 37: /* Westmere */
1294 case 44:
1295 nhm_uncore_cpu_init();
1296 break;
1297 case 42: /* Sandy Bridge */
1298 case 58: /* Ivy Bridge */
1299 case 60: /* Haswell */
1300 case 69: /* Haswell */
1301 case 70: /* Haswell */
1302 case 61: /* Broadwell */
1303 case 71: /* Broadwell */
1304 snb_uncore_cpu_init();
1305 break;
1306 case 45: /* Sandy Bridge-EP */
1307 snbep_uncore_cpu_init();
1308 break;
1309 case 46: /* Nehalem-EX */
1310 case 47: /* Westmere-EX aka. Xeon E7 */
1311 nhmex_uncore_cpu_init();
1312 break;
1313 case 62: /* Ivy Bridge-EP */
1314 ivbep_uncore_cpu_init();
1315 break;
1316 case 63: /* Haswell-EP */
1317 hswep_uncore_cpu_init();
1318 break;
1319 case 79: /* BDX-EP */
1320 case 86: /* BDX-DE */
1321 bdx_uncore_cpu_init();
1322 break;
1323 case 87: /* Knights Landing */
1324 knl_uncore_cpu_init();
1325 break;
1326 default:
1327 return -ENODEV;
1328 }
1329
1330 ret = uncore_types_init(uncore_msr_uncores, true); 1253 ret = uncore_types_init(uncore_msr_uncores, true);
1331 if (ret) 1254 if (ret)
1332 goto err; 1255 goto err;
@@ -1376,11 +1299,105 @@ static int __init uncore_cpumask_init(bool msr)
1376 return 0; 1299 return 0;
1377} 1300}
1378 1301
1302#define X86_UNCORE_MODEL_MATCH(model, init) \
1303 { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&init }
1304
1305struct intel_uncore_init_fun {
1306 void (*cpu_init)(void);
1307 int (*pci_init)(void);
1308};
1309
1310static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
1311 .cpu_init = nhm_uncore_cpu_init,
1312};
1313
1314static const struct intel_uncore_init_fun snb_uncore_init __initconst = {
1315 .cpu_init = snb_uncore_cpu_init,
1316 .pci_init = snb_uncore_pci_init,
1317};
1318
1319static const struct intel_uncore_init_fun ivb_uncore_init __initconst = {
1320 .cpu_init = snb_uncore_cpu_init,
1321 .pci_init = ivb_uncore_pci_init,
1322};
1323
1324static const struct intel_uncore_init_fun hsw_uncore_init __initconst = {
1325 .cpu_init = snb_uncore_cpu_init,
1326 .pci_init = hsw_uncore_pci_init,
1327};
1328
1329static const struct intel_uncore_init_fun bdw_uncore_init __initconst = {
1330 .cpu_init = snb_uncore_cpu_init,
1331 .pci_init = bdw_uncore_pci_init,
1332};
1333
1334static const struct intel_uncore_init_fun snbep_uncore_init __initconst = {
1335 .cpu_init = snbep_uncore_cpu_init,
1336 .pci_init = snbep_uncore_pci_init,
1337};
1338
1339static const struct intel_uncore_init_fun nhmex_uncore_init __initconst = {
1340 .cpu_init = nhmex_uncore_cpu_init,
1341};
1342
1343static const struct intel_uncore_init_fun ivbep_uncore_init __initconst = {
1344 .cpu_init = ivbep_uncore_cpu_init,
1345 .pci_init = ivbep_uncore_pci_init,
1346};
1347
1348static const struct intel_uncore_init_fun hswep_uncore_init __initconst = {
1349 .cpu_init = hswep_uncore_cpu_init,
1350 .pci_init = hswep_uncore_pci_init,
1351};
1352
1353static const struct intel_uncore_init_fun bdx_uncore_init __initconst = {
1354 .cpu_init = bdx_uncore_cpu_init,
1355 .pci_init = bdx_uncore_pci_init,
1356};
1357
1358static const struct intel_uncore_init_fun knl_uncore_init __initconst = {
1359 .cpu_init = knl_uncore_cpu_init,
1360 .pci_init = knl_uncore_pci_init,
1361};
1362
1363static const struct intel_uncore_init_fun skl_uncore_init __initconst = {
1364 .pci_init = skl_uncore_pci_init,
1365};
1366
1367static const struct x86_cpu_id intel_uncore_match[] __initconst = {
1368 X86_UNCORE_MODEL_MATCH(26, nhm_uncore_init), /* Nehalem */
1369 X86_UNCORE_MODEL_MATCH(30, nhm_uncore_init),
1370 X86_UNCORE_MODEL_MATCH(37, nhm_uncore_init), /* Westmere */
1371 X86_UNCORE_MODEL_MATCH(44, nhm_uncore_init),
1372 X86_UNCORE_MODEL_MATCH(42, snb_uncore_init), /* Sandy Bridge */
1373 X86_UNCORE_MODEL_MATCH(58, ivb_uncore_init), /* Ivy Bridge */
1374 X86_UNCORE_MODEL_MATCH(60, hsw_uncore_init), /* Haswell */
1375 X86_UNCORE_MODEL_MATCH(69, hsw_uncore_init), /* Haswell Celeron */
1376 X86_UNCORE_MODEL_MATCH(70, hsw_uncore_init), /* Haswell */
1377 X86_UNCORE_MODEL_MATCH(61, bdw_uncore_init), /* Broadwell */
1378 X86_UNCORE_MODEL_MATCH(71, bdw_uncore_init), /* Broadwell */
1379 X86_UNCORE_MODEL_MATCH(45, snbep_uncore_init), /* Sandy Bridge-EP */
1380 X86_UNCORE_MODEL_MATCH(46, nhmex_uncore_init), /* Nehalem-EX */
1381 X86_UNCORE_MODEL_MATCH(47, nhmex_uncore_init), /* Westmere-EX aka. Xeon E7 */
1382 X86_UNCORE_MODEL_MATCH(62, ivbep_uncore_init), /* Ivy Bridge-EP */
1383 X86_UNCORE_MODEL_MATCH(63, hswep_uncore_init), /* Haswell-EP */
1384 X86_UNCORE_MODEL_MATCH(79, bdx_uncore_init), /* BDX-EP */
1385 X86_UNCORE_MODEL_MATCH(86, bdx_uncore_init), /* BDX-DE */
1386 X86_UNCORE_MODEL_MATCH(87, knl_uncore_init), /* Knights Landing */
1387 X86_UNCORE_MODEL_MATCH(94, skl_uncore_init), /* SkyLake */
1388 {},
1389};
1390
1391MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
1392
1379static int __init intel_uncore_init(void) 1393static int __init intel_uncore_init(void)
1380{ 1394{
1381 int pret, cret, ret; 1395 const struct x86_cpu_id *id;
1396 struct intel_uncore_init_fun *uncore_init;
1397 int pret = 0, cret = 0, ret;
1382 1398
1383 if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) 1399 id = x86_match_cpu(intel_uncore_match);
1400 if (!id)
1384 return -ENODEV; 1401 return -ENODEV;
1385 1402
1386 if (cpu_has_hypervisor) 1403 if (cpu_has_hypervisor)
@@ -1388,8 +1405,17 @@ static int __init intel_uncore_init(void)
1388 1405
1389 max_packages = topology_max_packages(); 1406 max_packages = topology_max_packages();
1390 1407
1391 pret = uncore_pci_init(); 1408 uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
1392 cret = uncore_cpu_init(); 1409 if (uncore_init->pci_init) {
1410 pret = uncore_init->pci_init();
1411 if (!pret)
1412 pret = uncore_pci_init();
1413 }
1414
1415 if (uncore_init->cpu_init) {
1416 uncore_init->cpu_init();
1417 cret = uncore_cpu_init();
1418 }
1393 1419
1394 if (cret && pret) 1420 if (cret && pret)
1395 return -ENODEV; 1421 return -ENODEV;
@@ -1409,4 +1435,14 @@ err:
1409 cpu_notifier_register_done(); 1435 cpu_notifier_register_done();
1410 return ret; 1436 return ret;
1411} 1437}
1412device_initcall(intel_uncore_init); 1438module_init(intel_uncore_init);
1439
1440static void __exit intel_uncore_exit(void)
1441{
1442 cpu_notifier_register_begin();
1443 __unregister_cpu_notifier(&uncore_cpu_nb);
1444 uncore_types_exit(uncore_msr_uncores);
1445 uncore_pci_exit();
1446 cpu_notifier_register_done();
1447}
1448module_exit(intel_uncore_exit);