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: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Michael Petlan <mpetlan@redhat.com> Link: https://lore.kernel.org/r/20230112200105.733466-4-kan.liang@linux.intel.com
This commit is contained in:
parent
3af548f236
commit
bd9514a4d5
|
@ -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)
|
||||||
|
|
||||||
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)
|
||||||
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 @@
|
||||||
|
|
||||||
#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 @@ free_box_offset:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
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,
|
||||||
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)
|
||||||
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 {
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue