diff mbox series

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

Message ID 1536233456-12173-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. 6, 2018, 11:30 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

Andi Kleen Sept. 7, 2018, 3:28 a.m. UTC | #1
> +int perf_get_lbr_stack(struct perf_lbr_stack *stack)
> +{
> +	stack->lbr_nr = x86_pmu.lbr_nr;
> +	stack->lbr_tos = x86_pmu.lbr_tos;
> +	stack->lbr_from = x86_pmu.lbr_from;
> +	stack->lbr_to = x86_pmu.lbr_to;
> +
> +	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
> +		stack->lbr_info = MSR_LBR_INFO_0;
> +	else
> +		stack->lbr_info = 0;

Seems weird to export the enum value if the enum isn't exported.
How can it be used?

-Andi
Wang, Wei W Sept. 7, 2018, 6:45 a.m. UTC | #2
On 09/07/2018 11:28 AM, Andi Kleen wrote:
>> +int perf_get_lbr_stack(struct perf_lbr_stack *stack)
>> +{
>> +	stack->lbr_nr = x86_pmu.lbr_nr;
>> +	stack->lbr_tos = x86_pmu.lbr_tos;
>> +	stack->lbr_from = x86_pmu.lbr_from;
>> +	stack->lbr_to = x86_pmu.lbr_to;
>> +
>> +	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
>> +		stack->lbr_info = MSR_LBR_INFO_0;
>> +	else
>> +		stack->lbr_info = 0;
> Seems weird to export the enum value if the enum isn't exported.
> How can it be used?
>

I'm not sure about the issue. The caller gets the value of 
MSR_LBR_INFO_0 (not the enum, LBR_FORMAT_INFO) only when the hardware 
supports it. If hardware doesn't support it, just sets it to 0, and 
there will be no lbr info msr to be passed through.

Best,
Wei
diff mbox series

Patch

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index f3e006b..7c3958e 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1273,3 +1273,26 @@  void intel_pmu_lbr_init_knl(void)
 	x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
 	x86_pmu.lbr_sel_map  = snb_lbr_sel_map;
 }
+
+/**
+ * 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->lbr_nr = x86_pmu.lbr_nr;
+	stack->lbr_tos = x86_pmu.lbr_tos;
+	stack->lbr_from = x86_pmu.lbr_from;
+	stack->lbr_to = x86_pmu.lbr_to;
+
+	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+		stack->lbr_info = MSR_LBR_INFO_0;
+	else
+		stack->lbr_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..f40e80a 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		lbr_nr;
+	unsigned long	lbr_tos;
+	unsigned long	lbr_from;
+	unsigned long	lbr_to;
+	unsigned long	lbr_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));