Skip to content

Commit

Permalink
Merge tag 'perf-core-2021-08-30' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/tip/tip

Pull x86 perf event updates from Ingo Molnar:

 - Add support for Intel Sapphire Rapids server CPU uncore events

 - Allow the AMD uncore driver to be built as a module

 - Misc cleanups and fixes

* tag 'perf-core-2021-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits)
  perf/x86/amd/ibs: Add bitfield definitions in new <asm/amd-ibs.h> header
  perf/amd/uncore: Allow the driver to be built as a module
  x86/cpu: Add get_llc_id() helper function
  perf/amd/uncore: Clean up header use, use <linux/ include paths instead of <asm/
  perf/amd/uncore: Simplify code, use free_percpu()'s built-in check for NULL
  perf/hw_breakpoint: Replace deprecated CPU-hotplug functions
  perf/x86/intel: Replace deprecated CPU-hotplug functions
  perf/x86: Remove unused assignment to pointer 'e'
  perf/x86/intel/uncore: Fix IIO cleanup mapping procedure for SNR/ICX
  perf/x86/intel/uncore: Support IMC free-running counters on Sapphire Rapids server
  perf/x86/intel/uncore: Support IIO free-running counters on Sapphire Rapids server
  perf/x86/intel/uncore: Factor out snr_uncore_mmio_map()
  perf/x86/intel/uncore: Add alias PMU name
  perf/x86/intel/uncore: Add Sapphire Rapids server MDF support
  perf/x86/intel/uncore: Add Sapphire Rapids server M3UPI support
  perf/x86/intel/uncore: Add Sapphire Rapids server UPI support
  perf/x86/intel/uncore: Add Sapphire Rapids server M2M support
  perf/x86/intel/uncore: Add Sapphire Rapids server IMC support
  perf/x86/intel/uncore: Add Sapphire Rapids server PCU support
  perf/x86/intel/uncore: Add Sapphire Rapids server M2PCIe support
  ...
  • Loading branch information
torvalds committed Aug 30, 2021
2 parents 5d3c0db + 6a371ba commit 4a2b88e
Show file tree
Hide file tree
Showing 18 changed files with 858 additions and 90 deletions.
13 changes: 13 additions & 0 deletions Documentation/ABI/testing/sysfs-bus-event_source-devices-uncore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
What: /sys/bus/event_source/devices/uncore_*/alias
Date: June 2021
KernelVersion: 5.15
Contact: Linux kernel mailing list <[email protected]>
Description: Read-only. An attribute to describe the alias name of
the uncore PMU if an alias exists on some platforms.
The 'perf(1)' tool should treat both names the same.
They both can be used to access the uncore PMU.

Example:

$ cat /sys/devices/uncore_cha_2/alias
uncore_type_0_2
10 changes: 10 additions & 0 deletions arch/x86/events/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,14 @@ config PERF_EVENTS_AMD_POWER
(CPUID Fn8000_0007_EDX[12]) interface to calculate the
average power consumption on Family 15h processors.

config PERF_EVENTS_AMD_UNCORE
tristate "AMD Uncore performance events"
depends on PERF_EVENTS && CPU_SUP_AMD
default y
help
Include support for AMD uncore performance events for use with
e.g., perf stat -e amd_l3/.../,amd_df/.../.

To compile this driver as a module, choose M here: the
module will be called 'amd-uncore'.
endmenu
5 changes: 3 additions & 2 deletions arch/x86/events/amd/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_CPU_SUP_AMD) += core.o uncore.o
obj-$(CONFIG_CPU_SUP_AMD) += core.o
obj-$(CONFIG_PERF_EVENTS_AMD_POWER) += power.o
obj-$(CONFIG_X86_LOCAL_APIC) += ibs.o
obj-$(CONFIG_PERF_EVENTS_AMD_UNCORE) += amd-uncore.o
amd-uncore-objs := uncore.o
ifdef CONFIG_AMD_IOMMU
obj-$(CONFIG_CPU_SUP_AMD) += iommu.o
endif

23 changes: 9 additions & 14 deletions arch/x86/events/amd/ibs.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static u32 ibs_caps;
#include <linux/hardirq.h>

#include <asm/nmi.h>
#include <asm/amd-ibs.h>

#define IBS_FETCH_CONFIG_MASK (IBS_FETCH_RAND_EN | IBS_FETCH_MAX_CNT)
#define IBS_OP_CONFIG_MASK IBS_OP_MAX_CNT
Expand Down Expand Up @@ -100,15 +101,6 @@ struct perf_ibs {
u64 (*get_count)(u64 config);
};

struct perf_ibs_data {
u32 size;
union {
u32 data[0]; /* data buffer starts here */
u32 caps;
};
u64 regs[MSR_AMD64_IBS_REG_COUNT_MAX];
};

static int
perf_event_set_period(struct hw_perf_event *hwc, u64 min, u64 max, u64 *hw_period)
{
Expand Down Expand Up @@ -329,24 +321,27 @@ static int perf_ibs_set_period(struct perf_ibs *perf_ibs,

static u64 get_ibs_fetch_count(u64 config)
{
return (config & IBS_FETCH_CNT) >> 12;
union ibs_fetch_ctl fetch_ctl = (union ibs_fetch_ctl)config;

return fetch_ctl.fetch_cnt << 4;
}

static u64 get_ibs_op_count(u64 config)
{
union ibs_op_ctl op_ctl = (union ibs_op_ctl)config;
u64 count = 0;

/*
* If the internal 27-bit counter rolled over, the count is MaxCnt
* and the lower 7 bits of CurCnt are randomized.
* Otherwise CurCnt has the full 27-bit current counter value.
*/
if (config & IBS_OP_VAL) {
count = (config & IBS_OP_MAX_CNT) << 4;
if (op_ctl.op_val) {
count = op_ctl.opmaxcnt << 4;
if (ibs_caps & IBS_CAPS_OPCNTEXT)
count += config & IBS_OP_MAX_CNT_EXT_MASK;
count += op_ctl.opmaxcnt_ext << 20;
} else if (ibs_caps & IBS_CAPS_RDWROPCNT) {
count = (config & IBS_OP_CUR_CNT) >> 32;
count = op_ctl.opcurcnt;
}

return count;
Expand Down
40 changes: 32 additions & 8 deletions arch/x86/events/amd/uncore.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
#include <linux/init.h>
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/cpufeature.h>
#include <linux/smp.h>

#include <asm/cpufeature.h>
#include <asm/perf_event.h>
#include <asm/msr.h>
#include <asm/smp.h>

#define NUM_COUNTERS_NB 4
#define NUM_COUNTERS_L2 4
Expand Down Expand Up @@ -347,6 +347,7 @@ static struct pmu amd_nb_pmu = {
.stop = amd_uncore_stop,
.read = amd_uncore_read,
.capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
.module = THIS_MODULE,
};

static struct pmu amd_llc_pmu = {
Expand All @@ -360,6 +361,7 @@ static struct pmu amd_llc_pmu = {
.stop = amd_uncore_stop,
.read = amd_uncore_read,
.capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
.module = THIS_MODULE,
};

static struct amd_uncore *amd_uncore_alloc(unsigned int cpu)
Expand Down Expand Up @@ -452,7 +454,7 @@ static int amd_uncore_cpu_starting(unsigned int cpu)

if (amd_uncore_llc) {
uncore = *per_cpu_ptr(amd_uncore_llc, cpu);
uncore->id = per_cpu(cpu_llc_id, cpu);
uncore->id = get_llc_id(cpu);

uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_llc);
*per_cpu_ptr(amd_uncore_llc, cpu) = uncore;
Expand Down Expand Up @@ -659,12 +661,34 @@ static int __init amd_uncore_init(void)
fail_llc:
if (boot_cpu_has(X86_FEATURE_PERFCTR_NB))
perf_pmu_unregister(&amd_nb_pmu);
if (amd_uncore_llc)
free_percpu(amd_uncore_llc);
free_percpu(amd_uncore_llc);
fail_nb:
if (amd_uncore_nb)
free_percpu(amd_uncore_nb);
free_percpu(amd_uncore_nb);

return ret;
}
device_initcall(amd_uncore_init);

static void __exit amd_uncore_exit(void)
{
cpuhp_remove_state(CPUHP_AP_PERF_X86_AMD_UNCORE_ONLINE);
cpuhp_remove_state(CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING);
cpuhp_remove_state(CPUHP_PERF_X86_AMD_UNCORE_PREP);

if (boot_cpu_has(X86_FEATURE_PERFCTR_LLC)) {
perf_pmu_unregister(&amd_llc_pmu);
free_percpu(amd_uncore_llc);
amd_uncore_llc = NULL;
}

if (boot_cpu_has(X86_FEATURE_PERFCTR_NB)) {
perf_pmu_unregister(&amd_nb_pmu);
free_percpu(amd_uncore_nb);
amd_uncore_nb = NULL;
}
}

module_init(amd_uncore_init);
module_exit(amd_uncore_exit);

MODULE_DESCRIPTION("AMD Uncore Driver");
MODULE_LICENSE("GPL v2");
4 changes: 1 addition & 3 deletions arch/x86/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1087,10 +1087,8 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
* validate an event group (assign == NULL)
*/
if (!unsched && assign) {
for (i = 0; i < n; i++) {
e = cpuc->event_list[i];
for (i = 0; i < n; i++)
static_call_cond(x86_pmu_commit_scheduling)(cpuc, i, assign[i]);
}
} else {
for (i = n0; i < n; i++) {
e = cpuc->event_list[i];
Expand Down
8 changes: 4 additions & 4 deletions arch/x86/events/intel/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -5032,9 +5032,9 @@ static ssize_t freeze_on_smi_store(struct device *cdev,

x86_pmu.attr_freeze_on_smi = val;

get_online_cpus();
cpus_read_lock();
on_each_cpu(flip_smm_bit, &val, 1);
put_online_cpus();
cpus_read_unlock();
done:
mutex_unlock(&freeze_on_smi_mutex);

Expand Down Expand Up @@ -5077,9 +5077,9 @@ static ssize_t set_sysctl_tfa(struct device *cdev,

allow_tsx_force_abort = val;

get_online_cpus();
cpus_read_lock();
on_each_cpu(update_tfa_sched, NULL, 1);
put_online_cpus();
cpus_read_unlock();

return count;
}
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/events/intel/pt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1708,15 +1708,15 @@ static __init int pt_init(void)
if (!boot_cpu_has(X86_FEATURE_INTEL_PT))
return -ENODEV;

get_online_cpus();
cpus_read_lock();
for_each_online_cpu(cpu) {
u64 ctl;

ret = rdmsrl_safe_on_cpu(cpu, MSR_IA32_RTIT_CTL, &ctl);
if (!ret && (ctl & RTIT_CTL_TRACEEN))
prior_warn++;
}
put_online_cpus();
cpus_read_unlock();

if (prior_warn) {
x86_add_exclusive(x86_lbr_exclusive_pt);
Expand Down
45 changes: 35 additions & 10 deletions arch/x86/events/intel/uncore.c
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,18 @@ static const struct attribute_group uncore_pmu_attr_group = {
.attrs = uncore_pmu_attrs,
};

void uncore_get_alias_name(char *pmu_name, struct intel_uncore_pmu *pmu)
{
struct intel_uncore_type *type = pmu->type;

if (type->num_boxes == 1)
sprintf(pmu_name, "uncore_type_%u", type->type_id);
else {
sprintf(pmu_name, "uncore_type_%u_%d",
type->type_id, type->box_ids[pmu->pmu_idx]);
}
}

static void uncore_get_pmu_name(struct intel_uncore_pmu *pmu)
{
struct intel_uncore_type *type = pmu->type;
Expand All @@ -851,12 +863,7 @@ static void uncore_get_pmu_name(struct intel_uncore_pmu *pmu)
* Use uncore_type_&typeid_&boxid as name.
*/
if (!type->name) {
if (type->num_boxes == 1)
sprintf(pmu->name, "uncore_type_%u", type->type_id);
else {
sprintf(pmu->name, "uncore_type_%u_%d",
type->type_id, type->box_ids[pmu->pmu_idx]);
}
uncore_get_alias_name(pmu->name, pmu);
return;
}

Expand All @@ -865,9 +872,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 +1674,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 +1777,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 +1828,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 +1852,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
4 changes: 4 additions & 0 deletions arch/x86/events/intel/uncore.h
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ struct event_constraint *
uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event);
void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event);
u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx);
void uncore_get_alias_name(char *pmu_name, struct intel_uncore_pmu *pmu);

extern struct intel_uncore_type *empty_uncore[];
extern struct intel_uncore_type **uncore_msr_uncores;
Expand Down Expand Up @@ -608,6 +609,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);
Loading

0 comments on commit 4a2b88e

Please sign in to comment.