Skip to content

Commit f680b6e

Browse files
Alexander AntonovPeter Zijlstra
authored andcommitted
perf/x86/intel/uncore: Enable UPI topology discovery for Icelake Server
UPI topology discovery relies on data from KTILP0 (offset 0x94) and KTIPCSTS (offset 0x120) as well as on SKX but on Icelake Server these registers reside under UBOX (Device ID 0x3450) bus. This patch enables /sys/devices/uncore_upi_*/die* attributes on Icelake Server. Signed-off-by: Alexander Antonov <alexander.antonov@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Kan Liang <kan.liang@linux.intel.com> Link: https://lore.kernel.org/r/20221117122833.3103580-9-alexander.antonov@linux.intel.com
1 parent c4aebdb commit f680b6e

1 file changed

Lines changed: 75 additions & 0 deletions

File tree

arch/x86/events/intel/uncore_snbep.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@
445445
#define ICX_UPI_PCI_PMON_CTR0 0x320
446446
#define ICX_UPI_PCI_PMON_BOX_CTL 0x318
447447
#define ICX_UPI_CTL_UMASK_EXT 0xffffff
448+
#define ICX_UBOX_DID 0x3450
448449

449450
/* ICX M3UPI*/
450451
#define ICX_M3UPI_PCI_PMON_CTL0 0xd8
@@ -5594,6 +5595,76 @@ static const struct attribute_group icx_upi_uncore_format_group = {
55945595
.attrs = icx_upi_uncore_formats_attr,
55955596
};
55965597

5598+
#define ICX_UPI_REGS_ADDR_DEVICE_LINK0 0x02
5599+
#define ICX_UPI_REGS_ADDR_FUNCTION 0x01
5600+
5601+
static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, int dev_link0)
5602+
{
5603+
struct pci_dev *ubox = NULL;
5604+
struct pci_dev *dev = NULL;
5605+
u32 nid, gid;
5606+
int i, idx, ret = -EPERM;
5607+
struct intel_uncore_topology *upi;
5608+
unsigned int devfn;
5609+
5610+
/* GIDNIDMAP method supports machines which have less than 8 sockets. */
5611+
if (uncore_max_dies() > 8)
5612+
goto err;
5613+
5614+
while ((ubox = pci_get_device(PCI_VENDOR_ID_INTEL, ubox_did, ubox))) {
5615+
ret = upi_nodeid_groupid(ubox, SKX_CPUNODEID, SKX_GIDNIDMAP, &nid, &gid);
5616+
if (ret) {
5617+
ret = pcibios_err_to_errno(ret);
5618+
break;
5619+
}
5620+
5621+
for (i = 0; i < 8; i++) {
5622+
if (nid != GIDNIDMAP(gid, i))
5623+
continue;
5624+
for (idx = 0; idx < type->num_boxes; idx++) {
5625+
upi = &type->topology[nid][idx];
5626+
devfn = PCI_DEVFN(dev_link0 + idx, ICX_UPI_REGS_ADDR_FUNCTION);
5627+
dev = pci_get_domain_bus_and_slot(pci_domain_nr(ubox->bus),
5628+
ubox->bus->number,
5629+
devfn);
5630+
if (dev) {
5631+
ret = upi_fill_topology(dev, upi, idx);
5632+
if (ret)
5633+
goto err;
5634+
}
5635+
}
5636+
}
5637+
}
5638+
err:
5639+
pci_dev_put(ubox);
5640+
pci_dev_put(dev);
5641+
return ret;
5642+
}
5643+
5644+
static int icx_upi_get_topology(struct intel_uncore_type *type)
5645+
{
5646+
return discover_upi_topology(type, ICX_UBOX_DID, ICX_UPI_REGS_ADDR_DEVICE_LINK0);
5647+
}
5648+
5649+
static struct attribute_group icx_upi_mapping_group = {
5650+
.is_visible = skx_upi_mapping_visible,
5651+
};
5652+
5653+
static const struct attribute_group *icx_upi_attr_update[] = {
5654+
&icx_upi_mapping_group,
5655+
NULL
5656+
};
5657+
5658+
static int icx_upi_set_mapping(struct intel_uncore_type *type)
5659+
{
5660+
return pmu_upi_set_mapping(type, &icx_upi_mapping_group);
5661+
}
5662+
5663+
static void icx_upi_cleanup_mapping(struct intel_uncore_type *type)
5664+
{
5665+
pmu_cleanup_mapping(type, &icx_upi_mapping_group);
5666+
}
5667+
55975668
static struct intel_uncore_type icx_uncore_upi = {
55985669
.name = "upi",
55995670
.num_counters = 4,
@@ -5606,6 +5677,10 @@ static struct intel_uncore_type icx_uncore_upi = {
56065677
.box_ctl = ICX_UPI_PCI_PMON_BOX_CTL,
56075678
.ops = &skx_upi_uncore_pci_ops,
56085679
.format_group = &icx_upi_uncore_format_group,
5680+
.attr_update = icx_upi_attr_update,
5681+
.get_topology = icx_upi_get_topology,
5682+
.set_mapping = icx_upi_set_mapping,
5683+
.cleanup_mapping = icx_upi_cleanup_mapping,
56095684
};
56105685

56115686
static struct event_constraint icx_uncore_m3upi_constraints[] = {

0 commit comments

Comments
 (0)