Commit bd9514a4 authored by Kan Liang's avatar Kan Liang Committed by Peter Zijlstra

perf/x86/uncore: Ignore broken units in discovery table

Some units in a discovery table may be broken, e.g., UPI of SPR MCC.
A generic method is required to ignore the broken units.

Add uncore_units_ignore in the struct intel_uncore_init_fun, which
indicates the type ID of broken units. It will be assigned by the
platform-specific code later when the platform has a broken discovery
table.
Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: default avatarMichael Petlan <mpetlan@redhat.com>
Link: https://lore.kernel.org/r/20230112200105.733466-4-kan.liang@linux.intel.com
parent 3af548f2
...@@ -1695,7 +1695,10 @@ struct intel_uncore_init_fun { ...@@ -1695,7 +1695,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 = {
...@@ -1874,7 +1877,7 @@ static int __init intel_uncore_init(void) ...@@ -1874,7 +1877,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;
...@@ -1882,7 +1885,8 @@ static int __init intel_uncore_init(void) ...@@ -1882,7 +1885,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;
} }
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,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];
}; };
......
...@@ -190,8 +190,25 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit, ...@@ -190,8 +190,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;
...@@ -246,6 +263,9 @@ static int parse_discovery_table(struct pci_dev *dev, int die, ...@@ -246,6 +263,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);
} }
...@@ -254,7 +274,7 @@ static int parse_discovery_table(struct pci_dev *dev, int die, ...@@ -254,7 +274,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;
...@@ -290,7 +310,7 @@ bool intel_uncore_has_discovery_tables(void) ...@@ -290,7 +310,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);
} }
} }
......
...@@ -122,7 +122,7 @@ struct intel_uncore_discovery_type { ...@@ -122,7 +122,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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment