diff mbox series

[kvm-unit-tests,v4,14/24] x86/pmu: Read cpuid(10) in the pmu_init() to reduce VM-Exit

Message ID 20221024091223.42631-15-likexu@tencent.com (mailing list archive)
State New, archived
Headers show
Series x86/pmu: Test case optimization, fixes and additions | expand

Commit Message

Like Xu Oct. 24, 2022, 9:12 a.m. UTC
From: Like Xu <likexu@tencent.com>

The type of CPUID accessors can also go in the common pmu. Re-reading
cpuid(10) each time when needed, adding the overhead of eimulating
CPUID isn't meaningless in the grand scheme of the test.

A common "PMU init" routine would allow the library to provide helpers
access to more PMU common information.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Like Xu <likexu@tencent.com>
---
 lib/x86/pmu.c |  7 +++++++
 lib/x86/pmu.h | 26 +++++++++++++-------------
 lib/x86/smp.c |  2 ++
 3 files changed, 22 insertions(+), 13 deletions(-)

Comments

Sean Christopherson Nov. 2, 2022, 5:45 p.m. UTC | #1
On Mon, Oct 24, 2022, Like Xu wrote:
> From: Like Xu <likexu@tencent.com>
> 
> The type of CPUID accessors can also go in the common pmu. Re-reading
> cpuid(10) each time when needed, adding the overhead of eimulating
> CPUID isn't meaningless in the grand scheme of the test.
> 
> A common "PMU init" routine would allow the library to provide helpers
> access to more PMU common information.
> 
> Suggested-by: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Like Xu <likexu@tencent.com>
> ---
>  lib/x86/pmu.c |  7 +++++++
>  lib/x86/pmu.h | 26 +++++++++++++-------------
>  lib/x86/smp.c |  2 ++
>  3 files changed, 22 insertions(+), 13 deletions(-)
> 
> diff --git a/lib/x86/pmu.c b/lib/x86/pmu.c
> index 9d048ab..e8b9ae9 100644
> --- a/lib/x86/pmu.c
> +++ b/lib/x86/pmu.c
> @@ -1 +1,8 @@
>  #include "pmu.h"
> +
> +struct cpuid cpuid_10;
> +
> +void pmu_init(void)
> +{
> +    cpuid_10 = cpuid(10);

Tabs, not spaces.

> +}
> \ No newline at end of file
> diff --git a/lib/x86/pmu.h b/lib/x86/pmu.h
> index 078a974..7f4e797 100644
> --- a/lib/x86/pmu.h
> +++ b/lib/x86/pmu.h
> @@ -33,9 +33,13 @@
>  #define EVNTSEL_INT	(1 << EVNTSEL_INT_SHIFT)
>  #define EVNTSEL_INV	(1 << EVNTSEL_INV_SHIF)
>  
> +extern struct cpuid cpuid_10;

Instead of taking a raw snapshot of CPUID.0xA, process the CPUID info during
pmu_init() and fill "struct pmu_cap pmu" directly.

> diff --git a/lib/x86/smp.c b/lib/x86/smp.c
> index b9b91c7..29197fc 100644
> --- a/lib/x86/smp.c
> +++ b/lib/x86/smp.c
> @@ -4,6 +4,7 @@
>  #include <asm/barrier.h>
>  
>  #include "processor.h"
> +#include "pmu.h"
>  #include "atomic.h"
>  #include "smp.h"
>  #include "apic.h"
> @@ -155,6 +156,7 @@ void smp_init(void)
>  		on_cpu(i, setup_smp_id, 0);
>  
>  	atomic_inc(&active_cpus);
> +	pmu_init();

Initializing the PMU has nothing to do with SMP initialization.  There's also an
opportunity for more cleanup: all paths call bringup_aps() => enable_x2apic() =>
smp_init(), providing a kitchen sink helper can consolidate that code and provide
a convenient location for PMU initialization.

void bsp_rest_init(void)
{
	bringup_aps();
	enable_x2apic();
	smp_init();
	pmu_init();
}
diff mbox series

Patch

diff --git a/lib/x86/pmu.c b/lib/x86/pmu.c
index 9d048ab..e8b9ae9 100644
--- a/lib/x86/pmu.c
+++ b/lib/x86/pmu.c
@@ -1 +1,8 @@ 
 #include "pmu.h"
+
+struct cpuid cpuid_10;
+
+void pmu_init(void)
+{
+    cpuid_10 = cpuid(10);
+}
\ No newline at end of file
diff --git a/lib/x86/pmu.h b/lib/x86/pmu.h
index 078a974..7f4e797 100644
--- a/lib/x86/pmu.h
+++ b/lib/x86/pmu.h
@@ -33,9 +33,13 @@ 
 #define EVNTSEL_INT	(1 << EVNTSEL_INT_SHIFT)
 #define EVNTSEL_INV	(1 << EVNTSEL_INV_SHIF)
 
+extern struct cpuid cpuid_10;
+
+void pmu_init(void);
+
 static inline u8 pmu_version(void)
 {
-	return cpuid(10).a & 0xff;
+	return cpuid_10.a & 0xff;
 }
 
 static inline bool this_cpu_has_pmu(void)
@@ -50,35 +54,31 @@  static inline bool this_cpu_has_perf_global_ctrl(void)
 
 static inline u8 pmu_nr_gp_counters(void)
 {
-	return (cpuid(10).a >> 8) & 0xff;
+	return (cpuid_10.a >> 8) & 0xff;
 }
 
 static inline u8 pmu_gp_counter_width(void)
 {
-	return (cpuid(10).a >> 16) & 0xff;
+	return (cpuid_10.a >> 16) & 0xff;
 }
 
 static inline u8 pmu_gp_counter_mask_length(void)
 {
-	return (cpuid(10).a >> 24) & 0xff;
+	return (cpuid_10.a >> 24) & 0xff;
 }
 
 static inline u8 pmu_nr_fixed_counters(void)
 {
-	struct cpuid id = cpuid(10);
-
-	if ((id.a & 0xff) > 1)
-		return id.d & 0x1f;
+	if ((cpuid_10.a & 0xff) > 1)
+		return cpuid_10.d & 0x1f;
 	else
 		return 0;
 }
 
 static inline u8 pmu_fixed_counter_width(void)
 {
-	struct cpuid id = cpuid(10);
-
-	if ((id.a & 0xff) > 1)
-		return (id.d >> 5) & 0xff;
+	if ((cpuid_10.a & 0xff) > 1)
+		return (cpuid_10.d >> 5) & 0xff;
 	else
 		return 0;
 }
@@ -86,7 +86,7 @@  static inline u8 pmu_fixed_counter_width(void)
 static inline bool pmu_gp_counter_is_available(int i)
 {
 	/* CPUID.0xA.EBX bit is '1 if they counter is NOT available. */
-	return !(cpuid(10).b & BIT(i));
+	return !(cpuid_10.b & BIT(i));
 }
 
 static inline u64 this_cpu_perf_capabilities(void)
diff --git a/lib/x86/smp.c b/lib/x86/smp.c
index b9b91c7..29197fc 100644
--- a/lib/x86/smp.c
+++ b/lib/x86/smp.c
@@ -4,6 +4,7 @@ 
 #include <asm/barrier.h>
 
 #include "processor.h"
+#include "pmu.h"
 #include "atomic.h"
 #include "smp.h"
 #include "apic.h"
@@ -155,6 +156,7 @@  void smp_init(void)
 		on_cpu(i, setup_smp_id, 0);
 
 	atomic_inc(&active_cpus);
+	pmu_init();
 }
 
 static void do_reset_apic(void *data)