perf/x86/intel/uncore: Enable I/O stacks to IIO PMON mapping on SNR

I/O stacks to PMON mapping on Skylake server relies on topology information
from CPU_BUS_NO MSR but this approach is not applicable for SNR and ICX.
Mapping on these platforms can be gotten by reading SAD_CONTROL_CFG CSR
from Mesh2IIO device with 0x09a2 DID.
SAD_CONTROL_CFG CSR contains stack IDs in its own notation which are
statically mapped on IDs in PMON notation.

The map for Snowridge:

Stack Name         | CBDMA/DMI | PCIe Gen 3 | DLB | NIS | QAT
SAD_CONTROL_CFG ID |     0     |      1     |  2  |  3  |  4
PMON ID            |     1     |      4     |  3  |  2  |  0

This patch enables I/O stacks to IIO PMON mapping on Snowridge.
Mapping is exposed through attributes /sys/devices/uncore_iio_<pmu_idx>/dieX,
where dieX is file which holds "Segment:Root Bus" for PCIe root port which
can be monitored by that IIO PMON block. Example for Snowridge:

==> /sys/devices/uncore_iio_0/die0 <==
0000:f3
==> /sys/devices/uncore_iio_1/die0 <==
0000:00
==> /sys/devices/uncore_iio_2/die0 <==
0000:eb
==> /sys/devices/uncore_iio_3/die0 <==
0000:e3
==> /sys/devices/uncore_iio_4/die0 <==
0000:14

Mapping for Icelake server will be enabled in the follow-up patch.

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://lkml.kernel.org/r/20210426131614.16205-3-alexander.antonov@linux.intel.com
This commit is contained in:
Alexander Antonov 2021-04-26 16:16:13 +03:00 committed by Peter Zijlstra
parent f471fac77b
commit c1777be364
1 changed files with 96 additions and 0 deletions

View File

@ -348,6 +348,13 @@
#define SKX_M2M_PCI_PMON_CTR0 0x200 #define SKX_M2M_PCI_PMON_CTR0 0x200
#define SKX_M2M_PCI_PMON_BOX_CTL 0x258 #define SKX_M2M_PCI_PMON_BOX_CTL 0x258
/* Memory Map registers device ID */
#define SNR_ICX_MESH2IIO_MMAP_DID 0x9a2
#define SNR_ICX_SAD_CONTROL_CFG 0x3f4
/* Getting I/O stack id in SAD_COTROL_CFG notation */
#define SAD_CONTROL_STACK_ID(data) (((data) >> 4) & 0x7)
/* SNR Ubox */ /* SNR Ubox */
#define SNR_U_MSR_PMON_CTR0 0x1f98 #define SNR_U_MSR_PMON_CTR0 0x1f98
#define SNR_U_MSR_PMON_CTL0 0x1f91 #define SNR_U_MSR_PMON_CTL0 0x1f91
@ -4405,6 +4412,91 @@ static const struct attribute_group snr_uncore_iio_format_group = {
.attrs = snr_uncore_iio_formats_attr, .attrs = snr_uncore_iio_formats_attr,
}; };
static umode_t
snr_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
{
/* Root bus 0x00 is valid only for pmu_idx = 1. */
return pmu_iio_mapping_visible(kobj, attr, die, 1);
}
static struct attribute_group snr_iio_mapping_group = {
.is_visible = snr_iio_mapping_visible,
};
static const struct attribute_group *snr_iio_attr_update[] = {
&snr_iio_mapping_group,
NULL,
};
static int sad_cfg_iio_topology(struct intel_uncore_type *type, u8 *sad_pmon_mapping)
{
u32 sad_cfg;
int die, stack_id, ret = -EPERM;
struct pci_dev *dev = NULL;
type->topology = kcalloc(uncore_max_dies(), sizeof(*type->topology),
GFP_KERNEL);
if (!type->topology)
return -ENOMEM;
while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, SNR_ICX_MESH2IIO_MMAP_DID, dev))) {
ret = pci_read_config_dword(dev, SNR_ICX_SAD_CONTROL_CFG, &sad_cfg);
if (ret) {
ret = pcibios_err_to_errno(ret);
break;
}
die = uncore_pcibus_to_dieid(dev->bus);
stack_id = SAD_CONTROL_STACK_ID(sad_cfg);
if (die < 0 || stack_id >= type->num_boxes) {
ret = -EPERM;
break;
}
/* Convert stack id from SAD_CONTROL to PMON notation. */
stack_id = sad_pmon_mapping[stack_id];
((u8 *)&(type->topology[die].configuration))[stack_id] = dev->bus->number;
type->topology[die].segment = pci_domain_nr(dev->bus);
}
if (ret) {
kfree(type->topology);
type->topology = NULL;
}
return ret;
}
/*
* SNR has a static mapping of stack IDs from SAD_CONTROL_CFG notation to PMON
*/
enum {
SNR_QAT_PMON_ID,
SNR_CBDMA_DMI_PMON_ID,
SNR_NIS_PMON_ID,
SNR_DLB_PMON_ID,
SNR_PCIE_GEN3_PMON_ID
};
static u8 snr_sad_pmon_mapping[] = {
SNR_CBDMA_DMI_PMON_ID,
SNR_PCIE_GEN3_PMON_ID,
SNR_DLB_PMON_ID,
SNR_NIS_PMON_ID,
SNR_QAT_PMON_ID
};
static int snr_iio_get_topology(struct intel_uncore_type *type)
{
return sad_cfg_iio_topology(type, snr_sad_pmon_mapping);
}
static int snr_iio_set_mapping(struct intel_uncore_type *type)
{
return pmu_iio_set_mapping(type, &snr_iio_mapping_group);
}
static struct intel_uncore_type snr_uncore_iio = { static struct intel_uncore_type snr_uncore_iio = {
.name = "iio", .name = "iio",
.num_counters = 4, .num_counters = 4,
@ -4418,6 +4510,10 @@ static struct intel_uncore_type snr_uncore_iio = {
.msr_offset = SNR_IIO_MSR_OFFSET, .msr_offset = SNR_IIO_MSR_OFFSET,
.ops = &ivbep_uncore_msr_ops, .ops = &ivbep_uncore_msr_ops,
.format_group = &snr_uncore_iio_format_group, .format_group = &snr_uncore_iio_format_group,
.attr_update = snr_iio_attr_update,
.get_topology = snr_iio_get_topology,
.set_mapping = snr_iio_set_mapping,
.cleanup_mapping = skx_iio_cleanup_mapping,
}; };
static struct intel_uncore_type snr_uncore_irp = { static struct intel_uncore_type snr_uncore_irp = {