未验证 提交 af481f24 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!1315 Intel: Backport mainline UPI uncore discovery warning fixes for SPR MCC to OLK-5.10

Merge Pull Request from: @yunyingsun 
 
Title:
Backport mainline UPI uncore discovery warning fixes for SPR MCC to OLK-5.10

Content:
The discovery table of UPI on SPR MCC is broken. The broken discovery table triggers a kernel warning message on SPR MCC: “WARNING: CPU: xx PID: xx at arch/x86/events/intel/uncore_discovery.c:184  intel_uncore_has_discovery_tables+  ……”, which is overkilled. 

The backported patch series is to mitigate the issue by providing a hardcode pre-defined table, and it also refines the error handling code.

Commits from mainline kernel v6.3-rc1:
5d515ee4 perf/x86/uncore: Don't WARN_ON_ONCE() for a broken discovery table
65248a9a perf/x86/uncore: Add a quirk for UPI on SPR
bd9514a4 perf/x86/uncore: Ignore broken units in discovery table
3af548f2 perf/x86/uncore: Fix potential NULL pointer in uncore_get_alias_name
dbf061b2 perf/x86/uncore: Factor out uncore_device_to_die()

It has been verified on our SPR MCC(spreec01) that with the backported patches, the uncore related kernel warning and the call trace are not seen anymore.

Kernel issue:
https://gitee.com/openeuler/kernel/issues/I7H29Y

Test:
1. Before backport, with OLK-5.10 kernel on SPR MCC, below warning and call trace are seen in dmesg(with "dmesg | grep uncore"):
"“WARNING: CPU: xx PID: xx at arch/x86/events/intel/uncore_discovery.c:184  intel_uncore_has_discovery_tables+".

After backport, above warning and call trace are gone. Instead new uncore information prints are seen:
"[    6.801611] intel_uncore: Duplicate uncore type 3 box ID 7 is detected, Drop the duplicate uncore unit.
[    6.801638] intel_uncore: Duplicate uncore type 1 box ID 7 is detected, Drop the duplicate uncore unit.
[    6.801663] intel_uncore: Duplicate uncore type 2 box ID 7 is detected, Drop the duplicate uncore unit."

2. Before backport, there's no uncore_m3upi_x devices under /sys/devices/.
After backport, there're uncore_m3upi_1/2 available under /sys/devices/.

Known issue:
N/A

Default config change:
N/A 
 
Link:https://gitee.com/openeuler/kernel/pulls/1315 

Reviewed-by: Jun Tian <jun.j.tian@intel.com> 
Reviewed-by: Jason Zeng <jason.zeng@intel.com> 
Reviewed-by: Aichun Shi <aichun.shi@intel.com> 
Signed-off-by: Jialin Zhang <zhangjialin11@huawei.com> 
...@@ -53,6 +53,21 @@ int uncore_pcibus_to_dieid(struct pci_bus *bus) ...@@ -53,6 +53,21 @@ int uncore_pcibus_to_dieid(struct pci_bus *bus)
return die_id; return die_id;
} }
int uncore_device_to_die(struct pci_dev *dev)
{
int node = pcibus_to_node(dev->bus);
int cpu;
for_each_cpu(cpu, cpumask_of_pcibus(dev->bus)) {
struct cpuinfo_x86 *c = &cpu_data(cpu);
if (c->initialized && cpu_to_node(cpu) == node)
return c->logical_die_id;
}
return -1;
}
static void uncore_free_pcibus_map(void) static void uncore_free_pcibus_map(void)
{ {
struct pci2phy_map *map, *tmp; struct pci2phy_map *map, *tmp;
...@@ -834,6 +849,12 @@ static const struct attribute_group uncore_pmu_attr_group = { ...@@ -834,6 +849,12 @@ static const struct attribute_group uncore_pmu_attr_group = {
.attrs = uncore_pmu_attrs, .attrs = uncore_pmu_attrs,
}; };
static inline int uncore_get_box_id(struct intel_uncore_type *type,
struct intel_uncore_pmu *pmu)
{
return type->box_ids ? type->box_ids[pmu->pmu_idx] : pmu->pmu_idx;
}
void uncore_get_alias_name(char *pmu_name, struct intel_uncore_pmu *pmu) void uncore_get_alias_name(char *pmu_name, struct intel_uncore_pmu *pmu)
{ {
struct intel_uncore_type *type = pmu->type; struct intel_uncore_type *type = pmu->type;
...@@ -842,7 +863,7 @@ void uncore_get_alias_name(char *pmu_name, struct intel_uncore_pmu *pmu) ...@@ -842,7 +863,7 @@ void uncore_get_alias_name(char *pmu_name, struct intel_uncore_pmu *pmu)
sprintf(pmu_name, "uncore_type_%u", type->type_id); sprintf(pmu_name, "uncore_type_%u", type->type_id);
else { else {
sprintf(pmu_name, "uncore_type_%u_%d", sprintf(pmu_name, "uncore_type_%u_%d",
type->type_id, type->box_ids[pmu->pmu_idx]); type->type_id, uncore_get_box_id(type, pmu));
} }
} }
...@@ -869,7 +890,7 @@ static void uncore_get_pmu_name(struct intel_uncore_pmu *pmu) ...@@ -869,7 +890,7 @@ static void uncore_get_pmu_name(struct intel_uncore_pmu *pmu)
* Use the box ID from the discovery table if applicable. * Use the box ID from the discovery table if applicable.
*/ */
sprintf(pmu->name, "uncore_%s_%d", type->name, sprintf(pmu->name, "uncore_%s_%d", type->name,
type->box_ids ? type->box_ids[pmu->pmu_idx] : pmu->pmu_idx); uncore_get_box_id(type, pmu));
} }
} }
...@@ -1666,7 +1687,10 @@ struct intel_uncore_init_fun { ...@@ -1666,7 +1687,10 @@ struct intel_uncore_init_fun {
void (*cpu_init)(void); void (*cpu_init)(void);
int (*pci_init)(void); int (*pci_init)(void);
void (*mmio_init)(void); void (*mmio_init)(void);
/* Discovery table is required */
bool use_discovery; bool use_discovery;
/* The units in the discovery table should be ignored. */
int *uncore_units_ignore;
}; };
static const struct intel_uncore_init_fun nhm_uncore_init __initconst = { static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
...@@ -1764,6 +1788,7 @@ static const struct intel_uncore_init_fun spr_uncore_init __initconst = { ...@@ -1764,6 +1788,7 @@ static const struct intel_uncore_init_fun spr_uncore_init __initconst = {
.pci_init = spr_uncore_pci_init, .pci_init = spr_uncore_pci_init,
.mmio_init = spr_uncore_mmio_init, .mmio_init = spr_uncore_mmio_init,
.use_discovery = true, .use_discovery = true,
.uncore_units_ignore = spr_uncore_units_ignore,
}; };
static const struct intel_uncore_init_fun generic_uncore_init __initconst = { static const struct intel_uncore_init_fun generic_uncore_init __initconst = {
...@@ -1828,7 +1853,7 @@ static int __init intel_uncore_init(void) ...@@ -1828,7 +1853,7 @@ static int __init intel_uncore_init(void)
id = x86_match_cpu(intel_uncore_match); id = x86_match_cpu(intel_uncore_match);
if (!id) { if (!id) {
if (!uncore_no_discover && intel_uncore_has_discovery_tables()) if (!uncore_no_discover && intel_uncore_has_discovery_tables(NULL))
uncore_init = (struct intel_uncore_init_fun *)&generic_uncore_init; uncore_init = (struct intel_uncore_init_fun *)&generic_uncore_init;
else else
return -ENODEV; return -ENODEV;
...@@ -1836,7 +1861,8 @@ static int __init intel_uncore_init(void) ...@@ -1836,7 +1861,8 @@ static int __init intel_uncore_init(void)
uncore_init = (struct intel_uncore_init_fun *)id->driver_data; uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
if (uncore_no_discover && uncore_init->use_discovery) if (uncore_no_discover && uncore_init->use_discovery)
return -ENODEV; return -ENODEV;
if (uncore_init->use_discovery && !intel_uncore_has_discovery_tables()) if (uncore_init->use_discovery &&
!intel_uncore_has_discovery_tables(uncore_init->uncore_units_ignore))
return -ENODEV; return -ENODEV;
} }
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) #define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
#define UNCORE_IGNORE_END -1
struct pci_extra_dev { struct pci_extra_dev {
struct pci_dev *dev[UNCORE_EXTRA_PCI_DEV_MAX]; struct pci_dev *dev[UNCORE_EXTRA_PCI_DEV_MAX];
}; };
...@@ -184,6 +186,7 @@ struct pci2phy_map { ...@@ -184,6 +186,7 @@ struct pci2phy_map {
struct pci2phy_map *__find_pci2phy_map(int segment); struct pci2phy_map *__find_pci2phy_map(int segment);
int uncore_pcibus_to_dieid(struct pci_bus *bus); int uncore_pcibus_to_dieid(struct pci_bus *bus);
int uncore_device_to_die(struct pci_dev *dev);
ssize_t uncore_event_show(struct device *dev, ssize_t uncore_event_show(struct device *dev,
struct device_attribute *attr, char *buf); struct device_attribute *attr, char *buf);
...@@ -565,6 +568,7 @@ extern raw_spinlock_t pci2phy_map_lock; ...@@ -565,6 +568,7 @@ extern raw_spinlock_t pci2phy_map_lock;
extern struct list_head pci2phy_map_head; extern struct list_head pci2phy_map_head;
extern struct pci_extra_dev *uncore_extra_pci_dev; extern struct pci_extra_dev *uncore_extra_pci_dev;
extern struct event_constraint uncore_constraint_empty; extern struct event_constraint uncore_constraint_empty;
extern int spr_uncore_units_ignore[];
/* uncore_snb.c */ /* uncore_snb.c */
int snb_uncore_pci_init(void); int snb_uncore_pci_init(void);
......
...@@ -33,7 +33,7 @@ static int logical_die_id; ...@@ -33,7 +33,7 @@ static int logical_die_id;
static int get_device_die_id(struct pci_dev *dev) static int get_device_die_id(struct pci_dev *dev)
{ {
int cpu, node = pcibus_to_node(dev->bus); int node = pcibus_to_node(dev->bus);
/* /*
* If the NUMA info is not available, assume that the logical die id is * If the NUMA info is not available, assume that the logical die id is
...@@ -43,19 +43,7 @@ static int get_device_die_id(struct pci_dev *dev) ...@@ -43,19 +43,7 @@ static int get_device_die_id(struct pci_dev *dev)
if (node < 0) if (node < 0)
return logical_die_id++; return logical_die_id++;
for_each_cpu(cpu, cpumask_of_node(node)) { return uncore_device_to_die(dev);
struct cpuinfo_x86 *c = &cpu_data(cpu);
if (c->initialized && cpu_to_node(cpu) == node)
return c->logical_die_id;
}
/*
* All CPUs of a node may be offlined. For this case,
* the PCI and MMIO type of uncore blocks which are
* enumerated by the device will be unavailable.
*/
return -1;
} }
#define __node_2_type(cur) \ #define __node_2_type(cur) \
...@@ -140,13 +128,21 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit, ...@@ -140,13 +128,21 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit,
unsigned int *box_offset, *ids; unsigned int *box_offset, *ids;
int i; int i;
if (WARN_ON_ONCE(!unit->ctl || !unit->ctl_offset || !unit->ctr_offset)) if (!unit->ctl || !unit->ctl_offset || !unit->ctr_offset) {
pr_info("Invalid address is detected for uncore type %d box %d, "
"Disable the uncore unit.\n",
unit->box_type, unit->box_id);
return; return;
}
if (parsed) { if (parsed) {
type = search_uncore_discovery_type(unit->box_type); type = search_uncore_discovery_type(unit->box_type);
if (WARN_ON_ONCE(!type)) if (!type) {
pr_info("A spurious uncore type %d is detected, "
"Disable the uncore type.\n",
unit->box_type);
return; return;
}
/* Store the first box of each die */ /* Store the first box of each die */
if (!type->box_ctrl_die[die]) if (!type->box_ctrl_die[die])
type->box_ctrl_die[die] = unit->ctl; type->box_ctrl_die[die] = unit->ctl;
...@@ -181,8 +177,12 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit, ...@@ -181,8 +177,12 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit,
ids[i] = type->ids[i]; ids[i] = type->ids[i];
box_offset[i] = type->box_offset[i]; box_offset[i] = type->box_offset[i];
if (WARN_ON_ONCE(unit->box_id == ids[i])) if (unit->box_id == ids[i]) {
pr_info("Duplicate uncore type %d box ID %d is detected, "
"Drop the duplicate uncore unit.\n",
unit->box_type, unit->box_id);
goto free_ids; goto free_ids;
}
} }
ids[i] = unit->box_id; ids[i] = unit->box_id;
box_offset[i] = unit->ctl - type->box_ctrl; box_offset[i] = unit->ctl - type->box_ctrl;
...@@ -202,8 +202,25 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit, ...@@ -202,8 +202,25 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit,
} }
static bool
uncore_ignore_unit(struct uncore_unit_discovery *unit, int *ignore)
{
int i;
if (!ignore)
return false;
for (i = 0; ignore[i] != UNCORE_IGNORE_END ; i++) {
if (unit->box_type == ignore[i])
return true;
}
return false;
}
static int parse_discovery_table(struct pci_dev *dev, int die, static int parse_discovery_table(struct pci_dev *dev, int die,
u32 bar_offset, bool *parsed) u32 bar_offset, bool *parsed,
int *ignore)
{ {
struct uncore_global_discovery global; struct uncore_global_discovery global;
struct uncore_unit_discovery unit; struct uncore_unit_discovery unit;
...@@ -250,6 +267,9 @@ static int parse_discovery_table(struct pci_dev *dev, int die, ...@@ -250,6 +267,9 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
if (unit.access_type >= UNCORE_ACCESS_MAX) if (unit.access_type >= UNCORE_ACCESS_MAX)
continue; continue;
if (uncore_ignore_unit(&unit, ignore))
continue;
uncore_insert_box_info(&unit, die, *parsed); uncore_insert_box_info(&unit, die, *parsed);
} }
...@@ -258,7 +278,7 @@ static int parse_discovery_table(struct pci_dev *dev, int die, ...@@ -258,7 +278,7 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
return 0; return 0;
} }
bool intel_uncore_has_discovery_tables(void) bool intel_uncore_has_discovery_tables(int *ignore)
{ {
u32 device, val, entry_id, bar_offset; u32 device, val, entry_id, bar_offset;
int die, dvsec = 0, ret = true; int die, dvsec = 0, ret = true;
...@@ -294,7 +314,7 @@ bool intel_uncore_has_discovery_tables(void) ...@@ -294,7 +314,7 @@ bool intel_uncore_has_discovery_tables(void)
if (die < 0) if (die < 0)
continue; continue;
parse_discovery_table(dev, die, bar_offset, &parsed); parse_discovery_table(dev, die, bar_offset, &parsed, ignore);
} }
} }
......
...@@ -23,9 +23,15 @@ ...@@ -23,9 +23,15 @@
/* Global discovery table size */ /* Global discovery table size */
#define UNCORE_DISCOVERY_GLOBAL_MAP_SIZE 0x20 #define UNCORE_DISCOVERY_GLOBAL_MAP_SIZE 0x20
#define UNCORE_DISCOVERY_PCI_DOMAIN(data) ((data >> 28) & 0x7) #define UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET 28
#define UNCORE_DISCOVERY_PCI_BUS(data) ((data >> 20) & 0xff) #define UNCORE_DISCOVERY_PCI_DOMAIN(data) \
#define UNCORE_DISCOVERY_PCI_DEVFN(data) ((data >> 12) & 0xff) ((data >> UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET) & 0x7)
#define UNCORE_DISCOVERY_PCI_BUS_OFFSET 20
#define UNCORE_DISCOVERY_PCI_BUS(data) \
((data >> UNCORE_DISCOVERY_PCI_BUS_OFFSET) & 0xff)
#define UNCORE_DISCOVERY_PCI_DEVFN_OFFSET 12
#define UNCORE_DISCOVERY_PCI_DEVFN(data) \
((data >> UNCORE_DISCOVERY_PCI_DEVFN_OFFSET) & 0xff)
#define UNCORE_DISCOVERY_PCI_BOX_CTRL(data) (data & 0xfff) #define UNCORE_DISCOVERY_PCI_BOX_CTRL(data) (data & 0xfff)
...@@ -124,7 +130,7 @@ struct intel_uncore_discovery_type { ...@@ -124,7 +130,7 @@ struct intel_uncore_discovery_type {
unsigned int *box_offset; /* Box offset */ unsigned int *box_offset; /* Box offset */
}; };
bool intel_uncore_has_discovery_tables(void); bool intel_uncore_has_discovery_tables(int *ignore);
void intel_uncore_clear_discovery_tables(void); void intel_uncore_clear_discovery_tables(void);
void intel_uncore_generic_uncore_cpu_init(void); void intel_uncore_generic_uncore_cpu_init(void);
int intel_uncore_generic_uncore_pci_init(void); int intel_uncore_generic_uncore_pci_init(void);
......
...@@ -1427,9 +1427,6 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool ...@@ -1427,9 +1427,6 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool
} }
raw_spin_unlock(&pci2phy_map_lock); raw_spin_unlock(&pci2phy_map_lock);
} else { } else {
int node = pcibus_to_node(ubox_dev->bus);
int cpu;
segment = pci_domain_nr(ubox_dev->bus); segment = pci_domain_nr(ubox_dev->bus);
raw_spin_lock(&pci2phy_map_lock); raw_spin_lock(&pci2phy_map_lock);
map = __find_pci2phy_map(segment); map = __find_pci2phy_map(segment);
...@@ -1439,15 +1436,8 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool ...@@ -1439,15 +1436,8 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool
break; break;
} }
die_id = -1; map->pbus_to_dieid[bus] = die_id = uncore_device_to_die(ubox_dev);
for_each_cpu(cpu, cpumask_of_pcibus(ubox_dev->bus)) {
struct cpuinfo_x86 *c = &cpu_data(cpu);
if (c->initialized && cpu_to_node(cpu) == node) {
map->pbus_to_dieid[bus] = die_id = c->logical_die_id;
break;
}
}
raw_spin_unlock(&pci2phy_map_lock); raw_spin_unlock(&pci2phy_map_lock);
if (WARN_ON_ONCE(die_id == -1)) { if (WARN_ON_ONCE(die_id == -1)) {
...@@ -5601,17 +5591,6 @@ static struct intel_uncore_type spr_uncore_m2m = { ...@@ -5601,17 +5591,6 @@ static struct intel_uncore_type spr_uncore_m2m = {
.name = "m2m", .name = "m2m",
}; };
static struct intel_uncore_type spr_uncore_upi = {
SPR_UNCORE_PCI_COMMON_FORMAT(),
.name = "upi",
};
static struct intel_uncore_type spr_uncore_m3upi = {
SPR_UNCORE_PCI_COMMON_FORMAT(),
.name = "m3upi",
.constraints = icx_uncore_m3upi_constraints,
};
static struct intel_uncore_type spr_uncore_mdf = { static struct intel_uncore_type spr_uncore_mdf = {
SPR_UNCORE_COMMON_FORMAT(), SPR_UNCORE_COMMON_FORMAT(),
.name = "mdf", .name = "mdf",
...@@ -5620,7 +5599,13 @@ static struct intel_uncore_type spr_uncore_mdf = { ...@@ -5620,7 +5599,13 @@ static struct intel_uncore_type spr_uncore_mdf = {
#define UNCORE_SPR_NUM_UNCORE_TYPES 12 #define UNCORE_SPR_NUM_UNCORE_TYPES 12
#define UNCORE_SPR_IIO 1 #define UNCORE_SPR_IIO 1
#define UNCORE_SPR_IMC 6 #define UNCORE_SPR_IMC 6
#define UNCORE_SPR_UPI 8
#define UNCORE_SPR_M3UPI 9
/*
* The uncore units, which are supported by the discovery table,
* are defined here.
*/
static struct intel_uncore_type *spr_uncores[UNCORE_SPR_NUM_UNCORE_TYPES] = { static struct intel_uncore_type *spr_uncores[UNCORE_SPR_NUM_UNCORE_TYPES] = {
&spr_uncore_chabox, &spr_uncore_chabox,
&spr_uncore_iio, &spr_uncore_iio,
...@@ -5630,12 +5615,49 @@ static struct intel_uncore_type *spr_uncores[UNCORE_SPR_NUM_UNCORE_TYPES] = { ...@@ -5630,12 +5615,49 @@ static struct intel_uncore_type *spr_uncores[UNCORE_SPR_NUM_UNCORE_TYPES] = {
NULL, NULL,
&spr_uncore_imc, &spr_uncore_imc,
&spr_uncore_m2m, &spr_uncore_m2m,
&spr_uncore_upi, NULL,
&spr_uncore_m3upi, NULL,
NULL, NULL,
&spr_uncore_mdf, &spr_uncore_mdf,
}; };
/*
* The uncore units, which are not supported by the discovery table,
* are implemented from here.
*/
#define SPR_UNCORE_UPI_NUM_BOXES 4
static unsigned int spr_upi_pci_offsets[SPR_UNCORE_UPI_NUM_BOXES] = {
0, 0x8000, 0x10000, 0x18000
};
static struct intel_uncore_type spr_uncore_upi = {
SPR_UNCORE_PCI_COMMON_FORMAT(),
.name = "upi",
.type_id = UNCORE_SPR_UPI,
.num_counters = 4,
.num_boxes = SPR_UNCORE_UPI_NUM_BOXES,
.perf_ctr_bits = 48,
.perf_ctr = ICX_UPI_PCI_PMON_CTR0,
.event_ctl = ICX_UPI_PCI_PMON_CTL0,
.box_ctl = ICX_UPI_PCI_PMON_BOX_CTL,
.pci_offsets = spr_upi_pci_offsets,
};
static struct intel_uncore_type spr_uncore_m3upi = {
SPR_UNCORE_PCI_COMMON_FORMAT(),
.name = "m3upi",
.type_id = UNCORE_SPR_M3UPI,
.num_counters = 4,
.num_boxes = SPR_UNCORE_UPI_NUM_BOXES,
.perf_ctr_bits = 48,
.perf_ctr = ICX_M3UPI_PCI_PMON_CTR0,
.event_ctl = ICX_M3UPI_PCI_PMON_CTL0,
.box_ctl = ICX_M3UPI_PCI_PMON_BOX_CTL,
.pci_offsets = spr_upi_pci_offsets,
.constraints = icx_uncore_m3upi_constraints,
};
enum perf_uncore_spr_iio_freerunning_type_id { enum perf_uncore_spr_iio_freerunning_type_id {
SPR_IIO_MSR_IOCLK, SPR_IIO_MSR_IOCLK,
SPR_IIO_MSR_BW_IN, SPR_IIO_MSR_BW_IN,
...@@ -5766,6 +5788,7 @@ static struct intel_uncore_type spr_uncore_imc_free_running = { ...@@ -5766,6 +5788,7 @@ static struct intel_uncore_type spr_uncore_imc_free_running = {
#define UNCORE_SPR_MSR_EXTRA_UNCORES 1 #define UNCORE_SPR_MSR_EXTRA_UNCORES 1
#define UNCORE_SPR_MMIO_EXTRA_UNCORES 1 #define UNCORE_SPR_MMIO_EXTRA_UNCORES 1
#define UNCORE_SPR_PCI_EXTRA_UNCORES 2
static struct intel_uncore_type *spr_msr_uncores[UNCORE_SPR_MSR_EXTRA_UNCORES] = { static struct intel_uncore_type *spr_msr_uncores[UNCORE_SPR_MSR_EXTRA_UNCORES] = {
&spr_uncore_iio_free_running, &spr_uncore_iio_free_running,
...@@ -5775,6 +5798,17 @@ static struct intel_uncore_type *spr_mmio_uncores[UNCORE_SPR_MMIO_EXTRA_UNCORES] ...@@ -5775,6 +5798,17 @@ static struct intel_uncore_type *spr_mmio_uncores[UNCORE_SPR_MMIO_EXTRA_UNCORES]
&spr_uncore_imc_free_running, &spr_uncore_imc_free_running,
}; };
static struct intel_uncore_type *spr_pci_uncores[UNCORE_SPR_PCI_EXTRA_UNCORES] = {
&spr_uncore_upi,
&spr_uncore_m3upi
};
int spr_uncore_units_ignore[] = {
UNCORE_SPR_UPI,
UNCORE_SPR_M3UPI,
UNCORE_IGNORE_END
};
static void uncore_type_customized_copy(struct intel_uncore_type *to_type, static void uncore_type_customized_copy(struct intel_uncore_type *to_type,
struct intel_uncore_type *from_type) struct intel_uncore_type *from_type)
{ {
...@@ -5869,9 +5903,69 @@ void spr_uncore_cpu_init(void) ...@@ -5869,9 +5903,69 @@ void spr_uncore_cpu_init(void)
spr_uncore_iio_free_running.num_boxes = uncore_type_max_boxes(uncore_msr_uncores, UNCORE_SPR_IIO); spr_uncore_iio_free_running.num_boxes = uncore_type_max_boxes(uncore_msr_uncores, UNCORE_SPR_IIO);
} }
#define SPR_UNCORE_UPI_PCIID 0x3241
#define SPR_UNCORE_UPI0_DEVFN 0x9
#define SPR_UNCORE_M3UPI_PCIID 0x3246
#define SPR_UNCORE_M3UPI0_DEVFN 0x29
static void spr_update_device_location(int type_id)
{
struct intel_uncore_type *type;
struct pci_dev *dev = NULL;
u32 device, devfn;
u64 *ctls;
int die;
if (type_id == UNCORE_SPR_UPI) {
type = &spr_uncore_upi;
device = SPR_UNCORE_UPI_PCIID;
devfn = SPR_UNCORE_UPI0_DEVFN;
} else if (type_id == UNCORE_SPR_M3UPI) {
type = &spr_uncore_m3upi;
device = SPR_UNCORE_M3UPI_PCIID;
devfn = SPR_UNCORE_M3UPI0_DEVFN;
} else
return;
ctls = kcalloc(__uncore_max_dies, sizeof(u64), GFP_KERNEL);
if (!ctls) {
type->num_boxes = 0;
return;
}
while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, dev)) != NULL) {
if (devfn != dev->devfn)
continue;
die = uncore_device_to_die(dev);
if (die < 0)
continue;
ctls[die] = pci_domain_nr(dev->bus) << UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET |
dev->bus->number << UNCORE_DISCOVERY_PCI_BUS_OFFSET |
devfn << UNCORE_DISCOVERY_PCI_DEVFN_OFFSET |
type->box_ctl;
}
type->box_ctls = ctls;
}
int spr_uncore_pci_init(void) int spr_uncore_pci_init(void)
{ {
uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL); /*
* The discovery table of UPI on some SPR variant is broken,
* which impacts the detection of both UPI and M3UPI uncore PMON.
* Use the pre-defined UPI and M3UPI table to replace.
*
* The accurate location, e.g., domain and BUS number,
* can only be retrieved at load time.
* Update the location of UPI and M3UPI.
*/
spr_update_device_location(UNCORE_SPR_UPI);
spr_update_device_location(UNCORE_SPR_M3UPI);
uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI,
UNCORE_SPR_PCI_EXTRA_UNCORES,
spr_pci_uncores);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册