Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit edae1f0

Browse files
Kan LiangPeter Zijlstra
authored andcommitted
perf/x86/intel/uncore: Parse uncore discovery tables
A self-describing mechanism for the uncore PerfMon hardware has been introduced with the latest Intel platforms. By reading through an MMIO page worth of information, perf can 'discover' all the standard uncore PerfMon registers in a machine. The discovery mechanism relies on BIOS's support. With a proper BIOS, a PCI device with the unique capability ID 0x23 can be found on each die. Perf can retrieve the information of all available uncore PerfMons from the device via MMIO. The information is composed of one global discovery table and several unit discovery tables. - The global discovery table includes global uncore information of the die, e.g., the address of the global control register, the offset of the global status register, the number of uncore units, the offset of unit discovery tables, etc. - The unit discovery table includes generic uncore unit information, e.g., the access type, the counter width, the address of counters, the address of the counter control, the unit ID, the unit type, etc. The unit is also called "box" in the code. Perf can provide basic uncore support based on this information with the following patches. To locate the PCI device with the discovery tables, check the generic PCI ID first. If it doesn't match, go through the entire PCI device tree and locate the device with the unique capability ID. The uncore information is similar among dies. To save parsing time and space, only completely parse and store the discovery tables on the first die and the first box of each die. The parsed information is stored in an RB tree structure, intel_uncore_discovery_type. The size of the stored discovery tables varies among platforms. It's around 4KB for a Sapphire Rapids server. If a BIOS doesn't support the 'discovery' mechanism, the uncore driver will exit with -ENODEV. There is nothing changed. Add a module parameter to disable the discovery feature. If a BIOS gets the discovery tables wrong, users can have an option to disable the feature. For the current patchset, the uncore driver will exit with -ENODEV. In the future, it may fall back to the hardcode uncore driver on a known platform. Signed-off-by: Kan Liang <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 08ef1af commit edae1f0

File tree

4 files changed

+448
-8
lines changed

4 files changed

+448
-8
lines changed

arch/x86/events/intel/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o
33
obj-$(CONFIG_CPU_SUP_INTEL) += ds.o knc.o
44
obj-$(CONFIG_CPU_SUP_INTEL) += lbr.o p4.o p6.o pt.o
55
obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel-uncore.o
6-
intel-uncore-objs := uncore.o uncore_nhmex.o uncore_snb.o uncore_snbep.o
6+
intel-uncore-objs := uncore.o uncore_nhmex.o uncore_snb.o uncore_snbep.o uncore_discovery.o
77
obj-$(CONFIG_PERF_EVENTS_INTEL_CSTATE) += intel-cstate.o
88
intel-cstate-objs := cstate.o

arch/x86/events/intel/uncore.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
#include <asm/cpu_device_id.h>
55
#include <asm/intel-family.h>
66
#include "uncore.h"
7+
#include "uncore_discovery.h"
78

9+
static bool uncore_no_discover;
10+
module_param(uncore_no_discover, bool, 0);
11+
MODULE_PARM_DESC(uncore_no_discover, "Don't enable the Intel uncore PerfMon discovery mechanism "
12+
"(default: enable the discovery mechanism).");
813
static struct intel_uncore_type *empty_uncore[] = { NULL, };
914
struct intel_uncore_type **uncore_msr_uncores = empty_uncore;
1015
struct intel_uncore_type **uncore_pci_uncores = empty_uncore;
@@ -1637,6 +1642,9 @@ static const struct intel_uncore_init_fun snr_uncore_init __initconst = {
16371642
.mmio_init = snr_uncore_mmio_init,
16381643
};
16391644

1645+
static const struct intel_uncore_init_fun generic_uncore_init __initconst = {
1646+
};
1647+
16401648
static const struct x86_cpu_id intel_uncore_match[] __initconst = {
16411649
X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &nhm_uncore_init),
16421650
X86_MATCH_INTEL_FAM6_MODEL(NEHALEM, &nhm_uncore_init),
@@ -1684,17 +1692,21 @@ static int __init intel_uncore_init(void)
16841692
struct intel_uncore_init_fun *uncore_init;
16851693
int pret = 0, cret = 0, mret = 0, ret;
16861694

1687-
id = x86_match_cpu(intel_uncore_match);
1688-
if (!id)
1689-
return -ENODEV;
1690-
16911695
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
16921696
return -ENODEV;
16931697

16941698
__uncore_max_dies =
16951699
topology_max_packages() * topology_max_die_per_package();
16961700

1697-
uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
1701+
id = x86_match_cpu(intel_uncore_match);
1702+
if (!id) {
1703+
if (!uncore_no_discover && intel_uncore_has_discovery_tables())
1704+
uncore_init = (struct intel_uncore_init_fun *)&generic_uncore_init;
1705+
else
1706+
return -ENODEV;
1707+
} else
1708+
uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
1709+
16981710
if (uncore_init->pci_init) {
16991711
pret = uncore_init->pci_init();
17001712
if (!pret)
@@ -1711,8 +1723,10 @@ static int __init intel_uncore_init(void)
17111723
mret = uncore_mmio_init();
17121724
}
17131725

1714-
if (cret && pret && mret)
1715-
return -ENODEV;
1726+
if (cret && pret && mret) {
1727+
ret = -ENODEV;
1728+
goto free_discovery;
1729+
}
17161730

17171731
/* Install hotplug callbacks to setup the targets for each package */
17181732
ret = cpuhp_setup_state(CPUHP_AP_PERF_X86_UNCORE_ONLINE,
@@ -1727,6 +1741,8 @@ static int __init intel_uncore_init(void)
17271741
uncore_types_exit(uncore_msr_uncores);
17281742
uncore_types_exit(uncore_mmio_uncores);
17291743
uncore_pci_exit();
1744+
free_discovery:
1745+
intel_uncore_clear_discovery_tables();
17301746
return ret;
17311747
}
17321748
module_init(intel_uncore_init);
@@ -1737,5 +1753,6 @@ static void __exit intel_uncore_exit(void)
17371753
uncore_types_exit(uncore_msr_uncores);
17381754
uncore_types_exit(uncore_mmio_uncores);
17391755
uncore_pci_exit();
1756+
intel_uncore_clear_discovery_tables();
17401757
}
17411758
module_exit(intel_uncore_exit);

0 commit comments

Comments
 (0)