perf/x86/intel/uncore: Support MMIO type uncore blocks
A new MMIO type uncore box is introduced on Snow Ridge server. The counters of MMIO type uncore box can only be accessed by MMIO. Add a new uncore type, uncore_mmio_uncores, for MMIO type uncore blocks. Support MMIO type uncore blocks in CPU hot plug. The MMIO space has to be map/unmap for the first/last CPU. The context also need to be migrated if the bind CPU changes. Add mmio_init() to init and register PMUs for MMIO type uncore blocks. Add a helper to calculate the box_ctl address. The helpers which calculate ctl/ctr can be shared with PCI type uncore blocks. Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: acme@kernel.org Cc: eranian@google.com Link: https://lkml.kernel.org/r/1556672028-119221-5-git-send-email-kan.liang@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Родитель
c8872d90e0
Коммит
3da04b8a00
|
@ -8,6 +8,7 @@
|
|||
static struct intel_uncore_type *empty_uncore[] = { NULL, };
|
||||
struct intel_uncore_type **uncore_msr_uncores = empty_uncore;
|
||||
struct intel_uncore_type **uncore_pci_uncores = empty_uncore;
|
||||
struct intel_uncore_type **uncore_mmio_uncores = empty_uncore;
|
||||
|
||||
static bool pcidrv_registered;
|
||||
struct pci_driver *uncore_pci_driver;
|
||||
|
@ -1178,12 +1179,14 @@ static int uncore_event_cpu_offline(unsigned int cpu)
|
|||
target = -1;
|
||||
|
||||
uncore_change_context(uncore_msr_uncores, cpu, target);
|
||||
uncore_change_context(uncore_mmio_uncores, cpu, target);
|
||||
uncore_change_context(uncore_pci_uncores, cpu, target);
|
||||
|
||||
unref:
|
||||
/* Clear the references */
|
||||
die = topology_logical_die_id(cpu);
|
||||
uncore_box_unref(uncore_msr_uncores, die);
|
||||
uncore_box_unref(uncore_mmio_uncores, die);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1252,12 +1255,13 @@ static int uncore_box_ref(struct intel_uncore_type **types,
|
|||
|
||||
static int uncore_event_cpu_online(unsigned int cpu)
|
||||
{
|
||||
int ret, die, target;
|
||||
int die, target, msr_ret, mmio_ret;
|
||||
|
||||
die = topology_logical_die_id(cpu);
|
||||
ret = uncore_box_ref(uncore_msr_uncores, die, cpu);
|
||||
if (ret)
|
||||
return ret;
|
||||
msr_ret = uncore_box_ref(uncore_msr_uncores, die, cpu);
|
||||
mmio_ret = uncore_box_ref(uncore_mmio_uncores, die, cpu);
|
||||
if (msr_ret && mmio_ret)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Check if there is an online cpu in the package
|
||||
|
@ -1269,7 +1273,10 @@ static int uncore_event_cpu_online(unsigned int cpu)
|
|||
|
||||
cpumask_set_cpu(cpu, &uncore_cpu_mask);
|
||||
|
||||
if (!msr_ret)
|
||||
uncore_change_context(uncore_msr_uncores, -1, cpu);
|
||||
if (!mmio_ret)
|
||||
uncore_change_context(uncore_mmio_uncores, -1, cpu);
|
||||
uncore_change_context(uncore_pci_uncores, -1, cpu);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1317,12 +1324,35 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int __init uncore_mmio_init(void)
|
||||
{
|
||||
struct intel_uncore_type **types = uncore_mmio_uncores;
|
||||
int ret;
|
||||
|
||||
ret = uncore_types_init(types, true);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
for (; *types; types++) {
|
||||
ret = type_pmu_register(*types);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
err:
|
||||
uncore_types_exit(uncore_mmio_uncores);
|
||||
uncore_mmio_uncores = empty_uncore;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#define X86_UNCORE_MODEL_MATCH(model, init) \
|
||||
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&init }
|
||||
|
||||
struct intel_uncore_init_fun {
|
||||
void (*cpu_init)(void);
|
||||
int (*pci_init)(void);
|
||||
void (*mmio_init)(void);
|
||||
};
|
||||
|
||||
static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
|
||||
|
@ -1437,7 +1467,7 @@ static int __init intel_uncore_init(void)
|
|||
{
|
||||
const struct x86_cpu_id *id;
|
||||
struct intel_uncore_init_fun *uncore_init;
|
||||
int pret = 0, cret = 0, ret;
|
||||
int pret = 0, cret = 0, mret = 0, ret;
|
||||
|
||||
id = x86_match_cpu(intel_uncore_match);
|
||||
if (!id)
|
||||
|
@ -1460,7 +1490,12 @@ static int __init intel_uncore_init(void)
|
|||
cret = uncore_cpu_init();
|
||||
}
|
||||
|
||||
if (cret && pret)
|
||||
if (uncore_init->mmio_init) {
|
||||
uncore_init->mmio_init();
|
||||
mret = uncore_mmio_init();
|
||||
}
|
||||
|
||||
if (cret && pret && mret)
|
||||
return -ENODEV;
|
||||
|
||||
/* Install hotplug callbacks to setup the targets for each package */
|
||||
|
@ -1474,6 +1509,7 @@ static int __init intel_uncore_init(void)
|
|||
|
||||
err:
|
||||
uncore_types_exit(uncore_msr_uncores);
|
||||
uncore_types_exit(uncore_mmio_uncores);
|
||||
uncore_pci_exit();
|
||||
return ret;
|
||||
}
|
||||
|
@ -1483,6 +1519,7 @@ static void __exit intel_uncore_exit(void)
|
|||
{
|
||||
cpuhp_remove_state(CPUHP_AP_PERF_X86_UNCORE_ONLINE);
|
||||
uncore_types_exit(uncore_msr_uncores);
|
||||
uncore_types_exit(uncore_mmio_uncores);
|
||||
uncore_pci_exit();
|
||||
}
|
||||
module_exit(intel_uncore_exit);
|
||||
|
|
|
@ -56,7 +56,10 @@ struct intel_uncore_type {
|
|||
unsigned fixed_ctr;
|
||||
unsigned fixed_ctl;
|
||||
unsigned box_ctl;
|
||||
union {
|
||||
unsigned msr_offset;
|
||||
unsigned mmio_offset;
|
||||
};
|
||||
unsigned num_shared_regs:8;
|
||||
unsigned single_fixed:1;
|
||||
unsigned pair_ctr_ctl:1;
|
||||
|
@ -190,6 +193,13 @@ static inline bool uncore_pmc_freerunning(int idx)
|
|||
return idx == UNCORE_PMC_IDX_FREERUNNING;
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned int uncore_mmio_box_ctl(struct intel_uncore_box *box)
|
||||
{
|
||||
return box->pmu->type->box_ctl +
|
||||
box->pmu->type->mmio_offset * box->pmu->pmu_idx;
|
||||
}
|
||||
|
||||
static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box)
|
||||
{
|
||||
return box->pmu->type->box_ctl;
|
||||
|
@ -330,7 +340,7 @@ unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
|
|||
static inline
|
||||
unsigned uncore_fixed_ctl(struct intel_uncore_box *box)
|
||||
{
|
||||
if (box->pci_dev)
|
||||
if (box->pci_dev || box->io_addr)
|
||||
return uncore_pci_fixed_ctl(box);
|
||||
else
|
||||
return uncore_msr_fixed_ctl(box);
|
||||
|
@ -339,7 +349,7 @@ unsigned uncore_fixed_ctl(struct intel_uncore_box *box)
|
|||
static inline
|
||||
unsigned uncore_fixed_ctr(struct intel_uncore_box *box)
|
||||
{
|
||||
if (box->pci_dev)
|
||||
if (box->pci_dev || box->io_addr)
|
||||
return uncore_pci_fixed_ctr(box);
|
||||
else
|
||||
return uncore_msr_fixed_ctr(box);
|
||||
|
@ -348,7 +358,7 @@ unsigned uncore_fixed_ctr(struct intel_uncore_box *box)
|
|||
static inline
|
||||
unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx)
|
||||
{
|
||||
if (box->pci_dev)
|
||||
if (box->pci_dev || box->io_addr)
|
||||
return uncore_pci_event_ctl(box, idx);
|
||||
else
|
||||
return uncore_msr_event_ctl(box, idx);
|
||||
|
@ -357,7 +367,7 @@ unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx)
|
|||
static inline
|
||||
unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx)
|
||||
{
|
||||
if (box->pci_dev)
|
||||
if (box->pci_dev || box->io_addr)
|
||||
return uncore_pci_perf_ctr(box, idx);
|
||||
else
|
||||
return uncore_msr_perf_ctr(box, idx);
|
||||
|
@ -507,6 +517,7 @@ u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx);
|
|||
|
||||
extern struct intel_uncore_type **uncore_msr_uncores;
|
||||
extern struct intel_uncore_type **uncore_pci_uncores;
|
||||
extern struct intel_uncore_type **uncore_mmio_uncores;
|
||||
extern struct pci_driver *uncore_pci_driver;
|
||||
extern raw_spinlock_t pci2phy_map_lock;
|
||||
extern struct list_head pci2phy_map_head;
|
||||
|
|
Загрузка…
Ссылка в новой задаче