diff mbox series

[6/7] perf: x86/core: Add interface to query perfmon_event_map[] directly

Message ID 20211112095139.21775-7-likexu@tencent.com (mailing list archive)
State New, archived
Headers show
Series KVM: x86/pmu: Four functional fixes | expand

Commit Message

Like Xu Nov. 12, 2021, 9:51 a.m. UTC
From: Like Xu <likexu@tencent.com>

Currently, we have [intel|knc|p4|p6]_perfmon_event_map on the Intel
platforms and amd_[f17h]_perfmon_event_map on the AMD platforms.

Early clumsy KVM code or other potential perf_event users may have
hard-coded these perfmon_maps (e.g., arch/x86/kvm/svm/pmu.c), so
it would not make sense to program a common hardware event based
on the generic "enum perf_hw_id" once the two tables do not match.

Let's provide an interface for callers outside the perf subsystem to get
the counter config based on the perfmon_event_map currently in use,
and it also helps to save bytes.

Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Like Xu <likexu@tencent.com>
---
 arch/x86/events/core.c            | 9 +++++++++
 arch/x86/include/asm/perf_event.h | 5 +++++
 2 files changed, 14 insertions(+)

Comments

kernel test robot Nov. 17, 2021, 11:21 p.m. UTC | #1
Hi Like,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kvm/queue]
[also build test ERROR on tip/perf/core mst-vhost/linux-next linus/master v5.16-rc1 next-20211117]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Like-Xu/KVM-x86-pmu-Four-functional-fixes/20211112-175332
base:   https://git.kernel.org/pub/scm/virt/kvm/kvm.git queue
config: x86_64-randconfig-c022-20211115 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/43c9d66955e7ece2fd8f6c03cc606cf72be8e8d4
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Like-Xu/KVM-x86-pmu-Four-functional-fixes/20211112-175332
        git checkout 43c9d66955e7ece2fd8f6c03cc606cf72be8e8d4
        # save the attached .config to linux build tree
        mkdir build_dir
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from include/linux/perf_event.h:25,
                    from include/linux/trace_events.h:10,
                    from include/trace/trace_events.h:21,
                    from include/trace/define_trace.h:102,
                    from drivers/base/regmap/trace.h:257,
                    from drivers/base/regmap/regmap.c:23:
>> arch/x86/include/asm/perf_event.h:500:1: error: expected identifier or '(' before '{' token
     500 | {
         | ^
--
   In file included from include/linux/perf_event.h:25,
                    from include/linux/trace_events.h:10,
                    from include/trace/syscall.h:7,
                    from include/linux/syscalls.h:87,
                    from init/main.c:21:
>> arch/x86/include/asm/perf_event.h:500:1: error: expected identifier or '(' before '{' token
     500 | {
         | ^
   init/main.c:788:20: warning: no previous prototype for 'mem_encrypt_init' [-Wmissing-prototypes]
     788 | void __init __weak mem_encrypt_init(void) { }
         |                    ^~~~~~~~~~~~~~~~
--
   In file included from include/linux/perf_event.h:25,
                    from include/linux/trace_events.h:10,
                    from include/trace/syscall.h:7,
                    from include/linux/syscalls.h:87,
                    from include/linux/entry-common.h:7,
                    from arch/x86/include/asm/idtentry.h:9,
                    from arch/x86/include/asm/traps.h:9,
                    from arch/x86/mm/extable.c:9:
>> arch/x86/include/asm/perf_event.h:500:1: error: expected identifier or '(' before '{' token
     500 | {
         | ^
   arch/x86/mm/extable.c:27:16: warning: no previous prototype for 'ex_handler_default' [-Wmissing-prototypes]
      27 | __visible bool ex_handler_default(const struct exception_table_entry *fixup,
         |                ^~~~~~~~~~~~~~~~~~
   arch/x86/mm/extable.c:37:16: warning: no previous prototype for 'ex_handler_fault' [-Wmissing-prototypes]
      37 | __visible bool ex_handler_fault(const struct exception_table_entry *fixup,
         |                ^~~~~~~~~~~~~~~~
   arch/x86/mm/extable.c:58:16: warning: no previous prototype for 'ex_handler_fprestore' [-Wmissing-prototypes]
      58 | __visible bool ex_handler_fprestore(const struct exception_table_entry *fixup,
         |                ^~~~~~~~~~~~~~~~~~~~
   arch/x86/mm/extable.c:73:16: warning: no previous prototype for 'ex_handler_uaccess' [-Wmissing-prototypes]
      73 | __visible bool ex_handler_uaccess(const struct exception_table_entry *fixup,
         |                ^~~~~~~~~~~~~~~~~~
   arch/x86/mm/extable.c:84:16: warning: no previous prototype for 'ex_handler_copy' [-Wmissing-prototypes]
      84 | __visible bool ex_handler_copy(const struct exception_table_entry *fixup,
         |                ^~~~~~~~~~~~~~~
   arch/x86/mm/extable.c:96:16: warning: no previous prototype for 'ex_handler_rdmsr_unsafe' [-Wmissing-prototypes]
      96 | __visible bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup,
         |                ^~~~~~~~~~~~~~~~~~~~~~~
   arch/x86/mm/extable.c:113:16: warning: no previous prototype for 'ex_handler_wrmsr_unsafe' [-Wmissing-prototypes]
     113 | __visible bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup,
         |                ^~~~~~~~~~~~~~~~~~~~~~~
   arch/x86/mm/extable.c:129:16: warning: no previous prototype for 'ex_handler_clear_fs' [-Wmissing-prototypes]
     129 | __visible bool ex_handler_clear_fs(const struct exception_table_entry *fixup,
         |                ^~~~~~~~~~~~~~~~~~~
--
   In file included from include/linux/perf_event.h:25,
                    from include/linux/trace_events.h:10,
                    from include/trace/syscall.h:7,
                    from include/linux/syscalls.h:87,
                    from kernel/exit.c:42:
>> arch/x86/include/asm/perf_event.h:500:1: error: expected identifier or '(' before '{' token
     500 | {
         | ^
   kernel/exit.c:1810:13: warning: no previous prototype for 'abort' [-Wmissing-prototypes]
    1810 | __weak void abort(void)
         |             ^~~~~
--
   In file included from include/linux/perf_event.h:25,
                    from include/linux/trace_events.h:10,
                    from include/trace/trace_events.h:21,
                    from include/trace/define_trace.h:102,
                    from include/trace/events/vmscan.h:460,
                    from mm/vmscan.c:63:
>> arch/x86/include/asm/perf_event.h:500:1: error: expected identifier or '(' before '{' token
     500 | {
         | ^
   mm/vmscan.c: In function 'demote_page_list':
   mm/vmscan.c:1340:6: warning: variable 'err' set but not used [-Wunused-but-set-variable]
    1340 |  int err;
         |      ^~~
--
   In file included from include/linux/perf_event.h:25,
                    from include/linux/trace_events.h:10,
                    from include/trace/syscall.h:7,
                    from include/linux/syscalls.h:87,
                    from fs/pipe.c:24:
>> arch/x86/include/asm/perf_event.h:500:1: error: expected identifier or '(' before '{' token
     500 | {
         | ^
   fs/pipe.c:755:15: warning: no previous prototype for 'account_pipe_buffers' [-Wmissing-prototypes]
     755 | unsigned long account_pipe_buffers(struct user_struct *user,
         |               ^~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:761:6: warning: no previous prototype for 'too_many_pipe_buffers_soft' [-Wmissing-prototypes]
     761 | bool too_many_pipe_buffers_soft(unsigned long user_bufs)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:768:6: warning: no previous prototype for 'too_many_pipe_buffers_hard' [-Wmissing-prototypes]
     768 | bool too_many_pipe_buffers_hard(unsigned long user_bufs)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:775:6: warning: no previous prototype for 'pipe_is_unprivileged_user' [-Wmissing-prototypes]
     775 | bool pipe_is_unprivileged_user(void)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:1245:5: warning: no previous prototype for 'pipe_resize_ring' [-Wmissing-prototypes]
    1245 | int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
         |     ^~~~~~~~~~~~~~~~
--
   In file included from include/linux/perf_event.h:25,
                    from include/linux/trace_events.h:10,
                    from include/trace/syscall.h:7,
                    from include/linux/syscalls.h:87,
                    from fs/d_path.c:2:
>> arch/x86/include/asm/perf_event.h:500:1: error: expected identifier or '(' before '{' token
     500 | {
         | ^
   fs/d_path.c:320:7: warning: no previous prototype for 'simple_dname' [-Wmissing-prototypes]
     320 | char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
         |       ^~~~~~~~~~~~
--
   In file included from include/linux/perf_event.h:25,
                    from include/linux/hw_breakpoint.h:5,
                    from kernel/trace/trace.h:15,
                    from kernel/trace/trace_output.h:6,
                    from kernel/trace/ftrace.c:45:
>> arch/x86/include/asm/perf_event.h:500:1: error: expected identifier or '(' before '{' token
     500 | {
         | ^
   kernel/trace/ftrace.c:302:5: warning: no previous prototype for '__register_ftrace_function' [-Wmissing-prototypes]
     302 | int __register_ftrace_function(struct ftrace_ops *ops)
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
   kernel/trace/ftrace.c:345:5: warning: no previous prototype for '__unregister_ftrace_function' [-Wmissing-prototypes]
     345 | int __unregister_ftrace_function(struct ftrace_ops *ops)
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   kernel/trace/ftrace.c:3876:15: warning: no previous prototype for 'arch_ftrace_match_adjust' [-Wmissing-prototypes]
    3876 | char * __weak arch_ftrace_match_adjust(char *str, const char *search)
         |               ^~~~~~~~~~~~~~~~~~~~~~~~
--
   In file included from include/linux/perf_event.h:25,
                    from include/linux/hw_breakpoint.h:5,
                    from kernel/trace/trace.h:15,
                    from kernel/trace/trace.c:53:
>> arch/x86/include/asm/perf_event.h:500:1: error: expected identifier or '(' before '{' token
     500 | {
         | ^
   kernel/trace/trace.c: In function 'trace_check_vprintf':
   kernel/trace/trace.c:3837:3: warning: function 'trace_check_vprintf' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
    3837 |   trace_seq_vprintf(&iter->seq, iter->fmt, ap);
         |   ^~~~~~~~~~~~~~~~~
   kernel/trace/trace.c:3892:3: warning: function 'trace_check_vprintf' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
    3892 |   trace_seq_vprintf(&iter->seq, p, ap);
         |   ^~~~~~~~~~~~~~~~~
--
   In file included from include/linux/perf_event.h:25,
                    from include/linux/hw_breakpoint.h:5,
                    from kernel/trace/trace.h:15,
                    from kernel/trace/trace_output.h:6,
                    from kernel/trace/trace_output.c:14:
>> arch/x86/include/asm/perf_event.h:500:1: error: expected identifier or '(' before '{' token
     500 | {
         | ^
   kernel/trace/trace_output.c: In function 'trace_output_raw':
   kernel/trace/trace_output.c:331:2: warning: function 'trace_output_raw' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
     331 |  trace_seq_vprintf(s, trace_event_format(iter, fmt), ap);
         |  ^~~~~~~~~~~~~~~~~
--
   In file included from include/linux/perf_event.h:25,
                    from include/linux/hw_breakpoint.h:5,
                    from kernel/trace/trace.h:15,
                    from kernel/trace/trace_preemptirq.c:13:
>> arch/x86/include/asm/perf_event.h:500:1: error: expected identifier or '(' before '{' token
     500 | {
         | ^
   kernel/trace/trace_preemptirq.c:88:16: warning: no previous prototype for 'trace_hardirqs_on_caller' [-Wmissing-prototypes]
      88 | __visible void trace_hardirqs_on_caller(unsigned long caller_addr)
         |                ^~~~~~~~~~~~~~~~~~~~~~~~
   kernel/trace/trace_preemptirq.c:103:16: warning: no previous prototype for 'trace_hardirqs_off_caller' [-Wmissing-prototypes]
     103 | __visible void trace_hardirqs_off_caller(unsigned long caller_addr)
         |                ^~~~~~~~~~~~~~~~~~~~~~~~~
..


vim +500 arch/x86/include/asm/perf_event.h

   492	
   493	#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
   494	extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
   495	extern u64 perf_get_hw_event_config(int perf_hw_id);
   496	extern int x86_perf_get_lbr(struct x86_pmu_lbr *lbr);
   497	#else
   498	struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
   499	u64 perf_get_hw_event_config(int perf_hw_id);
 > 500	{
   501		return 0;
   502	}
   503	static inline int x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
   504	{
   505		return -1;
   506	}
   507	#endif
   508	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Like Xu Nov. 18, 2021, 8:06 a.m. UTC | #2
On 18/11/2021 7:21 am, kernel test robot wrote:
> Hi Like,
> 
> Thank you for the patch! Yet something to improve:
> 
> [auto build test ERROR on kvm/queue]
> [also build test ERROR on tip/perf/core mst-vhost/linux-next linus/master v5.16-rc1 next-20211117]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 

...

> vim +500 arch/x86/include/asm/perf_event.h
> 
>     492	
>     493	#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
>     494	extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
>     495	extern u64 perf_get_hw_event_config(int perf_hw_id);
>     496	extern int x86_perf_get_lbr(struct x86_pmu_lbr *lbr);
>     497	#else
>     498	struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
>     499	u64 perf_get_hw_event_config(int perf_hw_id);

Thanks to the robot, I should have removed the ";" from this line.

Awaiting further review comments.

>   > 500	{
>     501		return 0;
>     502	}
>     503	static inline int x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
>     504	{
>     505		return -1;
>     506	}
>     507	#endif
>     508	
> 
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
>
Like Xu Nov. 18, 2021, 1:36 p.m. UTC | #3
On 18/11/2021 4:06 pm, Like Xu wrote:
> On 18/11/2021 7:21 am, kernel test robot wrote:
>> Hi Like,
>>
>> Thank you for the patch! Yet something to improve:
>>
>> [auto build test ERROR on kvm/queue]
>> [also build test ERROR on tip/perf/core mst-vhost/linux-next linus/master 
>> v5.16-rc1 next-20211117]
>> [If your patch is applied to the wrong git tree, kindly drop us a note.
>> And when submitting patch, we suggest to use '--base' as documented in
>> https://git-scm.com/docs/git-format-patch]
>>
> 
> ...
> 
>> vim +500 arch/x86/include/asm/perf_event.h
>>
>>     492
>>     493    #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
>>     494    extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
>>     495    extern u64 perf_get_hw_event_config(int perf_hw_id);
>>     496    extern int x86_perf_get_lbr(struct x86_pmu_lbr *lbr);
>>     497    #else
>>     498    struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
>>     499    u64 perf_get_hw_event_config(int perf_hw_id);
> 
> Thanks to the robot, I should have removed the ";" from this line.
> 

Sorry, my bot is shouting at me again. This part should be:

diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 8fc1b5003713..85fd768d49d7 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -492,9 +492,11 @@ static inline void perf_check_microcode(void) { }

  #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
  extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
+extern u64 perf_get_hw_event_config(int perf_hw_id);
  extern int x86_perf_get_lbr(struct x86_pmu_lbr *lbr);
  #else
  struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
+static u64 perf_get_hw_event_config(int perf_hw_id);
  static inline int x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
  {
         return -1;

> Awaiting further review comments.
> 
>>   > 500    {
>>     501        return 0;
>>     502    }
>>     503    static inline int x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
>>     504    {
>>     505        return -1;
>>     506    }
>>     507    #endif
>>     508
>>
>> ---
>> 0-DAY CI Kernel Test Service, Intel Corporation
>> https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
>>
diff mbox series

Patch

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 2a57dbed4894..dc88d39cec1b 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -691,6 +691,15 @@  void x86_pmu_disable_all(void)
 	}
 }
 
+u64 perf_get_hw_event_config(int perf_hw_id)
+{
+	if (perf_hw_id < x86_pmu.max_events)
+		return x86_pmu.event_map(perf_hw_id);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(perf_get_hw_event_config);
+
 struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
 {
 	return static_call(x86_pmu_guest_get_msrs)(nr);
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 8fc1b5003713..11a93cb1198b 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -492,9 +492,14 @@  static inline void perf_check_microcode(void) { }
 
 #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
 extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
+extern u64 perf_get_hw_event_config(int perf_hw_id);
 extern int x86_perf_get_lbr(struct x86_pmu_lbr *lbr);
 #else
 struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
+u64 perf_get_hw_event_config(int perf_hw_id);
+{
+	return 0;
+}
 static inline int x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
 {
 	return -1;