Skip to content

Commit

Permalink
perf/x86/intel/uncore: Add Sapphire Rapids server framework
Browse files Browse the repository at this point in the history
Intel Sapphire Rapids supports a discovery mechanism, that allows an
uncore driver to discover the different components ("boxes") of the
chip.

All the generic information of the uncore boxes should be retrieved from
the discovery tables. This has been enabled with the commit edae1f0
("perf/x86/intel/uncore: Parse uncore discovery tables"). Add
use_discovery to indicate the case. The uncore driver doesn't need to
hard code the generic information for each uncore box.
But we still need to enable various functionality that cannot be
directly discovered.

To support these functionalities, the Sapphire Rapids server framework
is introduced here. Each specific uncore unit will be added into the
framework in the following patches.

Add use_discovery to indicate that the discovery mechanism is required
for the platform. Currently, Intel Sapphire Rapids is one of the
platforms.

The box ID from the discovery table is the accurate index. Use it if
applicable.

All the undiscovered platform-specific features will be hard code in the
spr_uncores[]. Add uncore_type_customized_copy(), instead of the memcpy,
to only overwrite these features.

The specific uncore unit hasn't been added here. From user's
perspective, there is nothing changed for now.

Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Link: https://lore.kernel.org/r/1625087320-194204-2-git-send-email-kan.liang@linux.intel.com
  • Loading branch information
Kan Liang authored and Peter Zijlstra committed Jul 2, 2021
1 parent 012669c commit c54c53d
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 5 deletions.
26 changes: 22 additions & 4 deletions arch/x86/events/intel/uncore.c
Original file line number Diff line number Diff line change
Expand Up @@ -865,9 +865,13 @@ static void uncore_get_pmu_name(struct intel_uncore_pmu *pmu)
sprintf(pmu->name, "uncore_%s", type->name);
else
sprintf(pmu->name, "uncore");
} else
sprintf(pmu->name, "uncore_%s_%d", type->name, pmu->pmu_idx);

} else {
/*
* Use the box ID from the discovery table if applicable.
*/
sprintf(pmu->name, "uncore_%s_%d", type->name,
type->box_ids ? type->box_ids[pmu->pmu_idx] : pmu->pmu_idx);
}
}

static int uncore_pmu_register(struct intel_uncore_pmu *pmu)
Expand Down Expand Up @@ -1663,6 +1667,7 @@ struct intel_uncore_init_fun {
void (*cpu_init)(void);
int (*pci_init)(void);
void (*mmio_init)(void);
bool use_discovery;
};

static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
Expand Down Expand Up @@ -1765,6 +1770,13 @@ static const struct intel_uncore_init_fun snr_uncore_init __initconst = {
.mmio_init = snr_uncore_mmio_init,
};

static const struct intel_uncore_init_fun spr_uncore_init __initconst = {
.cpu_init = spr_uncore_cpu_init,
.pci_init = spr_uncore_pci_init,
.mmio_init = spr_uncore_mmio_init,
.use_discovery = true,
};

static const struct intel_uncore_init_fun generic_uncore_init __initconst = {
.cpu_init = intel_uncore_generic_uncore_cpu_init,
.pci_init = intel_uncore_generic_uncore_pci_init,
Expand Down Expand Up @@ -1809,6 +1821,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &rkl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &adl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &spr_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &snr_uncore_init),
{},
};
Expand All @@ -1832,8 +1845,13 @@ static int __init intel_uncore_init(void)
uncore_init = (struct intel_uncore_init_fun *)&generic_uncore_init;
else
return -ENODEV;
} else
} else {
uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
if (uncore_no_discover && uncore_init->use_discovery)
return -ENODEV;
if (uncore_init->use_discovery && !intel_uncore_has_discovery_tables())
return -ENODEV;
}

if (uncore_init->pci_init) {
pret = uncore_init->pci_init();
Expand Down
3 changes: 3 additions & 0 deletions arch/x86/events/intel/uncore.h
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,9 @@ void snr_uncore_mmio_init(void);
int icx_uncore_pci_init(void);
void icx_uncore_cpu_init(void);
void icx_uncore_mmio_init(void);
int spr_uncore_pci_init(void);
void spr_uncore_cpu_init(void);
void spr_uncore_mmio_init(void);

/* uncore_nhmex.c */
void nhmex_uncore_cpu_init(void);
2 changes: 1 addition & 1 deletion arch/x86/events/intel/uncore_discovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ static bool uncore_update_uncore_type(enum uncore_access_type type_id,
return true;
}

static struct intel_uncore_type **
struct intel_uncore_type **
intel_uncore_generic_init_uncores(enum uncore_access_type type_id)
{
struct intel_uncore_discovery_type *type;
Expand Down
3 changes: 3 additions & 0 deletions arch/x86/events/intel/uncore_discovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,6 @@ void intel_uncore_clear_discovery_tables(void);
void intel_uncore_generic_uncore_cpu_init(void);
int intel_uncore_generic_uncore_pci_init(void);
void intel_uncore_generic_uncore_mmio_init(void);

struct intel_uncore_type **
intel_uncore_generic_init_uncores(enum uncore_access_type type_id);
87 changes: 87 additions & 0 deletions arch/x86/events/intel/uncore_snbep.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/* SandyBridge-EP/IvyTown uncore support */
#include "uncore.h"
#include "uncore_discovery.h"

/* SNB-EP pci bus to socket mapping */
#define SNBEP_CPUNODEID 0x40
Expand Down Expand Up @@ -5504,3 +5505,89 @@ void icx_uncore_mmio_init(void)
}

/* end of ICX uncore support */

/* SPR uncore support */

#define UNCORE_SPR_NUM_UNCORE_TYPES 12

static struct intel_uncore_type *spr_uncores[UNCORE_SPR_NUM_UNCORE_TYPES] = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};

static void uncore_type_customized_copy(struct intel_uncore_type *to_type,
struct intel_uncore_type *from_type)
{
if (!to_type || !from_type)
return;

if (from_type->name)
to_type->name = from_type->name;
if (from_type->fixed_ctr_bits)
to_type->fixed_ctr_bits = from_type->fixed_ctr_bits;
if (from_type->event_mask)
to_type->event_mask = from_type->event_mask;
if (from_type->event_mask_ext)
to_type->event_mask_ext = from_type->event_mask_ext;
if (from_type->fixed_ctr)
to_type->fixed_ctr = from_type->fixed_ctr;
if (from_type->fixed_ctl)
to_type->fixed_ctl = from_type->fixed_ctl;
if (from_type->fixed_ctr_bits)
to_type->fixed_ctr_bits = from_type->fixed_ctr_bits;
if (from_type->num_shared_regs)
to_type->num_shared_regs = from_type->num_shared_regs;
if (from_type->constraints)
to_type->constraints = from_type->constraints;
if (from_type->ops)
to_type->ops = from_type->ops;
if (from_type->event_descs)
to_type->event_descs = from_type->event_descs;
if (from_type->format_group)
to_type->format_group = from_type->format_group;
}

static struct intel_uncore_type **
uncore_get_uncores(enum uncore_access_type type_id)
{
struct intel_uncore_type **types, **start_types;

start_types = types = intel_uncore_generic_init_uncores(type_id);

/* Only copy the customized features */
for (; *types; types++) {
if ((*types)->type_id >= UNCORE_SPR_NUM_UNCORE_TYPES)
continue;
uncore_type_customized_copy(*types, spr_uncores[(*types)->type_id]);
}

return start_types;
}

void spr_uncore_cpu_init(void)
{
uncore_msr_uncores = uncore_get_uncores(UNCORE_ACCESS_MSR);
}

int spr_uncore_pci_init(void)
{
uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI);
return 0;
}

void spr_uncore_mmio_init(void)
{
uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO);
}

/* end of SPR uncore support */

0 comments on commit c54c53d

Please sign in to comment.