The topdown slots event counts the total number of available slots for
an unhalted logical processor. Software can use this event to calculate
the topdown metrics by collaborating with IA32_PERF_METRICS MSR.
Since Intel Icelake CPU starts, the topdown slots event can be
programmed both on GP counters or the exclusive fixed counter 3 but with
different event & umask code. The event with code (event=0xa4,umask=0x01)
is an architectural event which is represented in CPUID.0AH.EBX and can
be programed on any GP counter. Besides, Intel PMU from Icelake
introduces a new fixed counter (fixed counter 3) to count/sample
todpown slots event so the precious GP counters can be saved. The fixed
counter 3 uses an exclusive code (event=0x00,umask=0x04) to count/sample
the slots event.
Actually this patchset is a portion of the patchset "Enable fixed counter
3 and topdown perf metrics for vPMU"[1]. As this original patchset needs to
make some fundamental changes on perf code and cause big arguments, it
leads to the vPMU topdown metrics patchset is hard to be merged in current
vPMU emulation framework.
The patches of enabling topdown slots event is simple and doesn't
touch any perf code. Moreover topdown slots event as an independent
feature is still valuable even though in no topdown metrics cases, some
perf metrics depend on slots event and need to be derived from slots
event.
Thus the patches of enabling slots event is extracted as an independent
patchset and resend.
Ref:
1. https://lore.kernel.org/all/[email protected]/T/
Dapeng Mi (2):
KVM: x86/pmu: Add Intel CPUID-hinted TopDown slots event
KVM: x86/pmu: Support PMU fixed counter 3
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/kvm/vmx/pmu_intel.c | 12 ++++++++++++
arch/x86/kvm/x86.c | 4 ++--
3 files changed, 15 insertions(+), 3 deletions(-)
base-commit: 35dcbd9e47035f98f3910ae420bf10892c9bdc99
--
2.34.1
The TopDown slots event can be enabled on gp counter or fixed counter 3
and it does not differ from other fixed counters in terms of the use of
count and sampling modes (except for the hardware logic for event
accumulation).
According to commit 6017608936c1 ("perf/x86/intel: Add Icelake
support"), KVM or any perf in-kernel user needs to reprogram fixed
counter 3 via the kernel-defined TopDown slots event for real fixed
counter 3 on the host.
Co-developed-by: Like Xu <[email protected]>
Signed-off-by: Like Xu <[email protected]>
Signed-off-by: Dapeng Mi <[email protected]>
---
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/kvm/vmx/pmu_intel.c | 10 ++++++++++
arch/x86/kvm/x86.c | 4 ++--
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index d7036982332e..44b47950491a 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -517,7 +517,7 @@ struct kvm_pmc {
#define KVM_INTEL_PMC_MAX_GENERIC 8
#define MSR_ARCH_PERFMON_PERFCTR_MAX (MSR_ARCH_PERFMON_PERFCTR0 + KVM_INTEL_PMC_MAX_GENERIC - 1)
#define MSR_ARCH_PERFMON_EVENTSEL_MAX (MSR_ARCH_PERFMON_EVENTSEL0 + KVM_INTEL_PMC_MAX_GENERIC - 1)
-#define KVM_PMC_MAX_FIXED 3
+#define KVM_PMC_MAX_FIXED 4
#define MSR_ARCH_PERFMON_FIXED_CTR_MAX (MSR_ARCH_PERFMON_FIXED_CTR0 + KVM_PMC_MAX_FIXED - 1)
#define KVM_AMD_PMC_MAX_GENERIC 6
struct kvm_pmu {
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index e32353f1143f..d5af64b1ef69 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -45,6 +45,14 @@ enum intel_pmu_architectural_events {
* core crystal clock or the bus clock (yeah, "architectural").
*/
PSEUDO_ARCH_REFERENCE_CYCLES = NR_REAL_INTEL_ARCH_EVENTS,
+ /*
+ * Pseudo-architectural event used to implement IA32_FIXED_CTR3, a.k.a.
+ * topDown slots. The topdown slots event counts the total number of
+ * available slots for an unhalted logical processor. The topdwon slots
+ * event with PERF_METRICS MSR together provides support for topdown
+ * micro-architecture analysis method.
+ */
+ PSEUDO_ARCH_TOPDOWN_SLOTS,
NR_INTEL_ARCH_EVENTS,
};
@@ -61,6 +69,7 @@ static struct {
[INTEL_ARCH_BRANCHES_MISPREDICTED] = { 0xc5, 0x00 },
[INTEL_ARCH_TOPDOWN_SLOTS] = { 0xa4, 0x01 },
[PSEUDO_ARCH_REFERENCE_CYCLES] = { 0x00, 0x03 },
+ [PSEUDO_ARCH_TOPDOWN_SLOTS] = { 0x00, 0x04 },
};
/* mapping between fixed pmc index and intel_arch_events array */
@@ -68,6 +77,7 @@ static int fixed_pmc_events[] = {
[0] = INTEL_ARCH_INSTRUCTIONS_RETIRED,
[1] = INTEL_ARCH_CPU_CYCLES,
[2] = PSEUDO_ARCH_REFERENCE_CYCLES,
+ [3] = PSEUDO_ARCH_TOPDOWN_SLOTS,
};
static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2c924075f6f1..90c60b6899a5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1468,7 +1468,7 @@ static const u32 msrs_to_save_base[] = {
static const u32 msrs_to_save_pmu[] = {
MSR_ARCH_PERFMON_FIXED_CTR0, MSR_ARCH_PERFMON_FIXED_CTR1,
- MSR_ARCH_PERFMON_FIXED_CTR0 + 2,
+ MSR_ARCH_PERFMON_FIXED_CTR2, MSR_ARCH_PERFMON_FIXED_CTR3,
MSR_CORE_PERF_FIXED_CTR_CTRL, MSR_CORE_PERF_GLOBAL_STATUS,
MSR_CORE_PERF_GLOBAL_CTRL, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
MSR_IA32_PEBS_ENABLE, MSR_IA32_DS_AREA, MSR_PEBS_DATA_CFG,
@@ -7318,7 +7318,7 @@ static void kvm_init_msr_lists(void)
{
unsigned i;
- BUILD_BUG_ON_MSG(KVM_PMC_MAX_FIXED != 3,
+ BUILD_BUG_ON_MSG(KVM_PMC_MAX_FIXED != 4,
"Please update the fixed PMCs in msrs_to_save_pmu[]");
num_msrs_to_save = 0;
--
2.34.1