Skip to contentSkip to conversation

x86/cpu/amd: Enable the fixed Instructions Retired counter IRPERF

PATCH Applied Kim Phillips 3 participants 5 messages Feb 14, 2020 – Feb 19, 2020

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH v3 1/1 x86/cpu/amd: Enable the fixed Instructions Retired counter IRPERF

Commit aaf248848db50 ("perf/x86/msr: Add AMD IRPERF (Instructions Retired) performance counter") added support for access to the free-running counter via 'perf -e msr/irperf/', but when exercised, we always get a 0 count:

BEFORE:

$ sudo perf stat -e instructions,msr/irperf/ true

Performance counter stats for 'true':

           624,833      instructions
                 0      msr/irperf/

Simply set its enable bit - HWCR bit 30 - to make it start counting.

Enablement is restricted to all machines advertising IRPERF capability, except those susceptible to an erratum that makes the IRPERF return bad values.

That erratum occurs in Family 17h models 00-1fh [1], but not in F17h models 20h and above [2].

AFTER (on a family 17h model 31h machine):

$ sudo perf stat -e instructions,msr/irperf/ true

Performance counter stats for 'true':

           621,690      instructions
           622,490      msr/irperf/

[1] Revision Guide for AMD Family 17h Models 00h-0Fh Processors
[2] Revision Guide for AMD Family 17h Models 30h-3Fh Processors

The revision guides are available from the bugzilla Link below.

Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Babu Moger <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Fenghua Yu <[email protected]>
Cc Frank van der Linden <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Huang Rui <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Janakarajan Natarajan <[email protected]>
Cc Jan Beulich <[email protected]>
Cc Jiaxun Yang <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Luwei Kang <[email protected]>
Cc Martin Liška <[email protected]>
Cc Matt Fleming <[email protected]>
Cc Michael Petlan <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paolo Bonzini <[email protected]>
Cc Pawan Gupta <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Suravee Suthikulpanit <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Tom Lendacky <[email protected]>
Fixes aaf248848db50 ("perf/x86/msr: Add AMD IRPERF (Instructions Retired) performance counter")

---
v3: Removed null stalled cycles per insn from perf example output,
since it got fixed, also address comments from Borislav Petkov:

https://lkml.org/lkml/2020/2/11/395

- rephrase commit text to not say "this patch".
- uploaded both rev. guides (and all public F17h PPRs) to a new "Add AMD x86 documents for future reference" bug, and reference that in a Link: tag.
- rename X86_BUG_AMD_E1054 -> X86_BUG_IRPERF
- add a full stop to a sentence in a comment

v2 got resent, adding Michael Petlan to cc. Original v2:

    https://lore.kernel.org/lkml/[email protected]/

v2: Based on Andi Kleen's review:

https://lore.kernel.org/lkml/[email protected]/

Add an amd_erratum_1054 and use cpu_has_bug infrastructure instead of open-coding the {family,model} check.

 arch/x86/include/asm/cpufeatures.h |  1 +
 arch/x86/include/asm/msr-index.h   |  2 ++
 arch/x86/kernel/cpu/amd.c          | 17 +++++++++++++++++
 3 files changed, 20 insertions(+)
arch/x86/include/asm/cpufeatures.h +1 -0
index f3327cb56edf..8979d6fcc79c 100644
@@ -404,5 +404,6 @@
 #define X86_BUG_SWAPGS			X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
 #define X86_BUG_TAA			X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */
 #define X86_BUG_ITLB_MULTIHIT		X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
+#define X86_BUG_IRPERF			X86_BUG(24) /* CPU is affected by Instructions Retired counter Erratum 1054 */
 
 #endif /* _ASM_X86_CPUFEATURES_H */
arch/x86/include/asm/msr-index.h +2 -0
index ebe1685e92dd..d5e517d1c3dd 100644
@@ -512,6 +512,8 @@
 #define MSR_K7_HWCR			0xc0010015
 #define MSR_K7_HWCR_SMMLOCK_BIT		0
 #define MSR_K7_HWCR_SMMLOCK		BIT_ULL(MSR_K7_HWCR_SMMLOCK_BIT)
+#define MSR_K7_HWCR_IRPERF_EN_BIT	30
+#define MSR_K7_HWCR_IRPERF_EN		BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT)
 #define MSR_K7_FID_VID_CTL		0xc0010041
 #define MSR_K7_FID_VID_STATUS		0xc0010042
 
arch/x86/kernel/cpu/amd.c +17 -0
index ac83a0fef628..deebc728e2aa 100644
@@ -28,6 +28,7 @@
 
 static const int amd_erratum_383[];
 static const int amd_erratum_400[];
+static const int amd_erratum_1054[];
 static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum);
 
 /*
@@ -694,6 +695,9 @@ static void early_init_amd(struct cpuinfo_x86 *c)
 	if (cpu_has_amd_erratum(c, amd_erratum_400))
 		set_cpu_bug(c, X86_BUG_AMD_E400);
 
+	if (cpu_has_amd_erratum(c, amd_erratum_1054))
+		set_cpu_bug(c, X86_BUG_IRPERF);
+
 	early_detect_mem_encrypt(c);
 
 	/* Re-enable TopologyExtensions if switched off by BIOS */
@@ -972,6 +976,15 @@ static void init_amd(struct cpuinfo_x86 *c)
 	/* AMD CPUs don't reset SS attributes on SYSRET, Xen does. */
 	if (!cpu_has(c, X86_FEATURE_XENPV))
 		set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
+
+	/*
+	 * Turn on the Instructions Retired free counter on machines not
+	 * susceptible to erratum #1054 "Instructions Retired Performance
+	 * Counter May Be Inaccurate".
+	 */
+	if (cpu_has(c, X86_FEATURE_IRPERF) &&
+	    !cpu_has_bug(c, X86_BUG_IRPERF))
+		msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT);
 }
 
 #ifdef CONFIG_X86_32
@@ -1099,6 +1112,10 @@ static const int amd_erratum_400[] =
 static const int amd_erratum_383[] =
 	AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf));
 
+/* #1054: Instructions Retired Performance Counter May Be Inaccurate */
+static const int amd_erratum_1054[] =
+	AMD_OSVW_ERRATUM(0, AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf));
+
 
 static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
 {
Signature · 1 line
2.25.0
maintainer
#1 lore raw

arch/x86/include/asm/cpufeatures.h line 407

Quoted 9 lines · Kim Phillips
arch/x86/include/asm/cpufeatures.h +1 -0
index f3327cb56edf..8979d6fcc79c 100644
@@ -404,5 +404,6 @@
 #define X86_BUG_SWAPGS			X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
 #define X86_BUG_TAA			X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */
 #define X86_BUG_ITLB_MULTIHIT		X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
+#define X86_BUG_IRPERF			X86_BUG(24) /* CPU is affected by Instructions Retired counter Erratum 1054 */

Do you need this bug flag at all?

If the only reason for its existence is to check it before setting the MSR bit enabling IRPERF, then you don't need it. Or is there any particular reason why it should show in /proc/cpuinfo?

IOW, does this work too?

---

arch/x86/include/asm/msr-index.h +2 -0
index 8821697a7549..12c9684d59ba 100644
@@ -521,6 +521,8 @@
 #define MSR_K7_HWCR			0xc0010015
 #define MSR_K7_HWCR_SMMLOCK_BIT		0
 #define MSR_K7_HWCR_SMMLOCK		BIT_ULL(MSR_K7_HWCR_SMMLOCK_BIT)
+#define MSR_K7_HWCR_IRPERF_EN_BIT	30
+#define MSR_K7_HWCR_IRPERF_EN		BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT)
 #define MSR_K7_FID_VID_CTL		0xc0010041
 #define MSR_K7_FID_VID_STATUS		0xc0010042
 
arch/x86/kernel/cpu/amd.c +14 -0
index ac83a0fef628..1f875fbe1384 100644
@@ -28,6 +28,7 @@
 
 static const int amd_erratum_383[];
 static const int amd_erratum_400[];
+static const int amd_erratum_1054[];
 static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum);
 
 /*
@@ -972,6 +973,15 @@ static void init_amd(struct cpuinfo_x86 *c)
 	/* AMD CPUs don't reset SS attributes on SYSRET, Xen does. */
 	if (!cpu_has(c, X86_FEATURE_XENPV))
 		set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
+
+	/*
+	 * Turn on the Instructions Retired free counter on machines not
+	 * susceptible to erratum #1054 "Instructions Retired Performance
+	 * Counter May Be Inaccurate".
+	 */
+	if (cpu_has(c, X86_FEATURE_IRPERF) &&
+	    !cpu_has_amd_erratum(c, amd_erratum_1054))
+		msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT);
 }
 
 #ifdef CONFIG_X86_32
@@ -1099,6 +1109,10 @@ static const int amd_erratum_400[] =
 static const int amd_erratum_383[] =
 	AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf));
 
+/* #1054: Instructions Retired Performance Counter May Be Inaccurate */
+static const int amd_erratum_1054[] =
+	AMD_OSVW_ERRATUM(0, AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf));
+
 
 static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
 {
Signature · 4 lines
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
#2 lore raw

Hi Borislav,

Quoted 13 lines · Borislav Petkov

arch/x86/include/asm/cpufeatures.h line 407

Quoted 9 lines · Kim Phillips
arch/x86/include/asm/cpufeatures.h +1 -0
index f3327cb56edf..8979d6fcc79c 100644
@@ -404,5 +404,6 @@
 #define X86_BUG_SWAPGS			X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
 #define X86_BUG_TAA			X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */
 #define X86_BUG_ITLB_MULTIHIT		X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
+#define X86_BUG_IRPERF			X86_BUG(24) /* CPU is affected by Instructions Retired counter Erratum 1054 */

Do you need this bug flag at all?

Quoted 5 lines

If the only reason for its existence is to check it before setting the MSR bit enabling IRPERF, then you don't need it. Or is there any particular reason why it should show in /proc/cpuinfo?

IOW, does this work too?

Yes, that works quite nicely, and saves us a bug bit.

The only reason to have it show in /proc/cpuinfo is for userspace, but they can check for a nonzero count prior to using, instead.

Let me know if you'd like me to send a v4, or if you will just apply this version of yours.

Thanks,

Kim

maintainer
#3 lore raw
Quoted 2 lines · Kim Phillips

The only reason to have it show in /proc/cpuinfo is for userspace, but they can check for a nonzero count prior to using, instead.

How is userspace going to check it? perf tool or people *can* check it? If perf is going to check it then I'm fine with having the bug bit in /proc/cpuinfo along with a patch for perf adding usage for it.

If not and people in userspace can maybe check it but they probably won't then adding that bug bit would be a waste of bit.

Quoted 2 lines

Let me know if you'd like me to send a v4, or if you will just apply this version of yours.

I can take the simpler version for now. If you still want to have perf tool check the bit, you could submit a new patch adding that bug bit along with a perf tool patch using it...

Signature · 4 lines
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
merge bot Applied
#4 lore raw
In reply to Kim Phillips
The following commit has been merged into the x86/urgent branch of tip:

The following commit has been merged into the x86/urgent branch of tip:

Commit-ID:     21b5ee59ef18e27d85810584caf1f7ddc705ea83
Gitweb:        https://git.kernel.org/tip/21b5ee59ef18e27d85810584caf1f7ddc705ea83
Author:        Kim Phillips <[email protected]>
AuthorDate:    Wed, 19 Feb 2020 18:52:43 +01:00
Committer:     Borislav Petkov <[email protected]>
CommitterDate: Wed, 19 Feb 2020 20:01:54 +01:00

x86/cpu/amd: Enable the fixed Instructions Retired counter IRPERF

Commit

aaf248848db50 ("perf/x86/msr: Add AMD IRPERF (Instructions Retired)
performance counter")

added support for access to the free-running counter via 'perf -e msr/irperf/', but when exercised, it always returns a 0 count:

BEFORE:

  $ perf stat -e instructions,msr/irperf/ true

Performance counter stats for 'true':

             624,833      instructions
                   0      msr/irperf/

Simply set its enable bit - HWCR bit 30 - to make it start counting.

Enablement is restricted to all machines advertising IRPERF capability, except those susceptible to an erratum that makes the IRPERF return bad values.

That erratum occurs in Family 17h models 00-1fh [1], but not in F17h models 20h and above [2].

AFTER (on a family 17h model 31h machine):

  $ perf stat -e instructions,msr/irperf/ true

Performance counter stats for 'true':

             621,690      instructions
             622,490      msr/irperf/

[1] Revision Guide for AMD Family 17h Models 00h-0Fh Processors
[2] Revision Guide for AMD Family 17h Models 30h-3Fh Processors

The revision guides are available from the bugzilla Link below.

[ bp: Massage commit message. ]

Fixes aaf248848db50 ("perf/x86/msr: Add AMD IRPERF (Instructions Retired) performance counter")
Cc Peter Zijlstra <[email protected]>
---
 arch/x86/include/asm/msr-index.h |  2 ++
 arch/x86/kernel/cpu/amd.c        | 14 ++++++++++++++
 2 files changed, 16 insertions(+)
arch/x86/include/asm/msr-index.h +2 -0
index ebe1685..d5e517d 100644
@@ -512,6 +512,8 @@
 #define MSR_K7_HWCR			0xc0010015
 #define MSR_K7_HWCR_SMMLOCK_BIT		0
 #define MSR_K7_HWCR_SMMLOCK		BIT_ULL(MSR_K7_HWCR_SMMLOCK_BIT)
+#define MSR_K7_HWCR_IRPERF_EN_BIT	30
+#define MSR_K7_HWCR_IRPERF_EN		BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT)
 #define MSR_K7_FID_VID_CTL		0xc0010041
 #define MSR_K7_FID_VID_STATUS		0xc0010042
 
arch/x86/kernel/cpu/amd.c +14 -0
index ac83a0f..1f875fb 100644
@@ -28,6 +28,7 @@
 
 static const int amd_erratum_383[];
 static const int amd_erratum_400[];
+static const int amd_erratum_1054[];
 static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum);
 
 /*
@@ -972,6 +973,15 @@ static void init_amd(struct cpuinfo_x86 *c)
 	/* AMD CPUs don't reset SS attributes on SYSRET, Xen does. */
 	if (!cpu_has(c, X86_FEATURE_XENPV))
 		set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
+
+	/*
+	 * Turn on the Instructions Retired free counter on machines not
+	 * susceptible to erratum #1054 "Instructions Retired Performance
+	 * Counter May Be Inaccurate".
+	 */
+	if (cpu_has(c, X86_FEATURE_IRPERF) &&
+	    !cpu_has_amd_erratum(c, amd_erratum_1054))
+		msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT);
 }
 
 #ifdef CONFIG_X86_32
@@ -1099,6 +1109,10 @@ static const int amd_erratum_400[] =
 static const int amd_erratum_383[] =
 	AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf));
 
+/* #1054: Instructions Retired Performance Counter May Be Inaccurate */
+static const int amd_erratum_1054[] =
+	AMD_OSVW_ERRATUM(0, AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf));
+
 
 static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
 {