diff mbox series

[v3,1/5] perf/x86: add a function to get the lbr stack

Message ID 1537437959-8751-2-git-send-email-wei.w.wang@intel.com (mailing list archive)
State New, archived
Headers show
Series Guest LBR Enabling | expand

Commit Message

Wang, Wei W Sept. 20, 2018, 10:05 a.m. UTC
The LBR stack MSRs are architecturally specific. The perf subsystem has
already assigned the abstracted MSR values based on the CPU architecture.

This patch enables a caller outside the perf subsystem to get the LBR
stack info. This is useful for hyperviosrs to prepare the lbr feature
for the guest.

Signed-off-by: Like Xu <like.xu@intel.com>
Signed-off-by: Wei Wang <wei.w.wang@intel.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/events/intel/lbr.c       | 23 +++++++++++++++++++++++
 arch/x86/include/asm/perf_event.h | 14 ++++++++++++++
 2 files changed, 37 insertions(+)

Comments

Peter Zijlstra Sept. 20, 2018, 12:05 p.m. UTC | #1
On Thu, Sep 20, 2018 at 06:05:55PM +0800, Wei Wang wrote:
> diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
> index c88ed39..c81f160 100644
> --- a/arch/x86/events/intel/lbr.c
> +++ b/arch/x86/events/intel/lbr.c
> @@ -1277,3 +1277,26 @@ void intel_pmu_lbr_init_knl(void)
>  	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_LIP)
>  		x86_pmu.intel_cap.lbr_format = LBR_FORMAT_EIP_FLAGS;
>  }
> +
> +/**
> + * perf_get_lbr_stack - get the lbr stack related MSRs
> + *
> + * @stack: the caller's memory to get the lbr stack
> + *
> + * Returns: 0 indicates that the lbr stack has been successfully obtained.
> + */
> +int perf_get_lbr_stack(struct perf_lbr_stack *stack)
> +{
> +	stack->nr = x86_pmu.lbr_nr;
> +	stack->tos = x86_pmu.lbr_tos;
> +	stack->from = x86_pmu.lbr_from;
> +	stack->to = x86_pmu.lbr_to;
> +
> +	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
> +		stack->info = MSR_LBR_INFO_0;
> +	else
> +		stack->info = 0;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(perf_get_lbr_stack);

Blergh, I know KVM is a module but it really sucks having to export
everything :/

> diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
> index 12f5408..84cc8cb 100644
> --- a/arch/x86/include/asm/perf_event.h
> +++ b/arch/x86/include/asm/perf_event.h
> @@ -267,7 +267,16 @@ struct perf_guest_switch_msr {
>  	u64 host, guest;
>  };
>  
> +struct perf_lbr_stack {
> +	int		nr;

Do we need a negative number of LBR entries?

> +	unsigned long	tos;
> +	unsigned long	from;
> +	unsigned long	to;
> +	unsigned long	info;

These are all MSR values, that can be 'unsigned int', right? If so,
please also fix struct x86_pmu for that.

> +};
> +
>  extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
> +extern int perf_get_lbr_stack(struct perf_lbr_stack *stack);
>  extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap);
>  extern void perf_check_microcode(void);
>  #else

I would like to use the x86_perf namespace or something along those
lines, this is very much not a generic perf interface -- it is very much
x86 (or rather even Intel) specific.
Peter Zijlstra Sept. 20, 2018, 12:07 p.m. UTC | #2
On Thu, Sep 20, 2018 at 06:05:55PM +0800, Wei Wang wrote:
> The LBR stack MSRs are architecturally specific. The perf subsystem has
> already assigned the abstracted MSR values based on the CPU architecture.
> 
> This patch enables a caller outside the perf subsystem to get the LBR
> stack info. This is useful for hyperviosrs to prepare the lbr feature
> for the guest.
> 
> Signed-off-by: Like Xu <like.xu@intel.com>
> Signed-off-by: Wei Wang <wei.w.wang@intel.com>

Also, that SoB chain is broken. Since you're the author (per From), your
SoB should be first, also since you're the one sending it, your SoB
should also be last.

Nowhere did Like Xu handle the patch so he shouldn't be having a SoB at
all.
diff mbox series

Patch

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index c88ed39..c81f160 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1277,3 +1277,26 @@  void intel_pmu_lbr_init_knl(void)
 	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_LIP)
 		x86_pmu.intel_cap.lbr_format = LBR_FORMAT_EIP_FLAGS;
 }
+
+/**
+ * perf_get_lbr_stack - get the lbr stack related MSRs
+ *
+ * @stack: the caller's memory to get the lbr stack
+ *
+ * Returns: 0 indicates that the lbr stack has been successfully obtained.
+ */
+int perf_get_lbr_stack(struct perf_lbr_stack *stack)
+{
+	stack->nr = x86_pmu.lbr_nr;
+	stack->tos = x86_pmu.lbr_tos;
+	stack->from = x86_pmu.lbr_from;
+	stack->to = x86_pmu.lbr_to;
+
+	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+		stack->info = MSR_LBR_INFO_0;
+	else
+		stack->info = 0;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(perf_get_lbr_stack);
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 12f5408..84cc8cb 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -267,7 +267,16 @@  struct perf_guest_switch_msr {
 	u64 host, guest;
 };
 
+struct perf_lbr_stack {
+	int		nr;
+	unsigned long	tos;
+	unsigned long	from;
+	unsigned long	to;
+	unsigned long	info;
+};
+
 extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
+extern int perf_get_lbr_stack(struct perf_lbr_stack *stack);
 extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap);
 extern void perf_check_microcode(void);
 #else
@@ -277,6 +286,11 @@  static inline struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
 	return NULL;
 }
 
+static inline int perf_get_lbr_stack(struct perf_lbr_stack *stack)
+{
+	return -1;
+}
+
 static inline void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
 {
 	memset(cap, 0, sizeof(*cap));