Message ID | 20230808063111.1870070-9-dapeng1.mi@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Enable fixed counter 3 and topdown perf metrics for vPMU | expand |
Hi Dapeng, kernel test robot noticed the following build warnings: [auto build test WARNING on next-20230808] [cannot apply to kvm/queue acme/perf/core tip/perf/core kvm/linux-next v6.5-rc5 v6.5-rc4 v6.5-rc3 linus/master v6.5-rc5] [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#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Dapeng-Mi/KVM-x86-pmu-Support-PMU-fixed-counter-3/20230809-030457 base: next-20230808 patch link: https://lore.kernel.org/r/20230808063111.1870070-9-dapeng1.mi%40linux.intel.com patch subject: [PATCH RFV v2 08/13] perf/core: Add new function perf_event_topdown_metrics() config: loongarch-allnoconfig (https://download.01.org/0day-ci/archive/20230809/202308090447.HY139um6-lkp@intel.com/config) compiler: loongarch64-linux-gcc (GCC) 12.3.0 reproduce: (https://download.01.org/0day-ci/archive/20230809/202308090447.HY139um6-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202308090447.HY139um6-lkp@intel.com/ All warnings (new ones prefixed by >>): In file included from include/linux/trace_events.h:10, from include/trace/syscall.h:7, from include/linux/syscalls.h:90, from arch/loongarch/mm/cache.c:17: >> include/linux/perf_event.h:1793:53: warning: 'struct td_metrics' declared inside parameter list will not be visible outside of this definition or declaration 1793 | struct td_metrics *value) | ^~~~~~~~~~ -- In file included from include/linux/trace_events.h:10, from include/trace/syscall.h:7, from include/linux/syscalls.h:90, from include/linux/entry-common.h:7, from arch/loongarch/mm/fault.c:13: >> include/linux/perf_event.h:1793:53: warning: 'struct td_metrics' declared inside parameter list will not be visible outside of this definition or declaration 1793 | struct td_metrics *value) | ^~~~~~~~~~ arch/loongarch/mm/fault.c:256:27: warning: no previous prototype for 'do_page_fault' [-Wmissing-prototypes] 256 | asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | ^~~~~~~~~~~~~ vim +1793 include/linux/perf_event.h 1791 1792 static inline int perf_event_topdown_metrics(struct perf_event *event, > 1793 struct td_metrics *value) 1794 { 1795 return 0; 1796 } 1797 #endif 1798
Hi Dapeng, kernel test robot noticed the following build warnings: [auto build test WARNING on next-20230808] [cannot apply to kvm/queue acme/perf/core tip/perf/core kvm/linux-next v6.5-rc5 v6.5-rc4 v6.5-rc3 linus/master v6.5-rc5] [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#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Dapeng-Mi/KVM-x86-pmu-Support-PMU-fixed-counter-3/20230809-030457 base: next-20230808 patch link: https://lore.kernel.org/r/20230808063111.1870070-9-dapeng1.mi%40linux.intel.com patch subject: [PATCH RFV v2 08/13] perf/core: Add new function perf_event_topdown_metrics() config: arm-randconfig-r046-20230808 (https://download.01.org/0day-ci/archive/20230809/202308090418.vTakFy6e-lkp@intel.com/config) compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project.git f28c006a5895fc0e329fe15fead81e37457cb1d1) reproduce: (https://download.01.org/0day-ci/archive/20230809/202308090418.vTakFy6e-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202308090418.vTakFy6e-lkp@intel.com/ All warnings (new ones prefixed by >>): In file included from kernel/sched/build_policy.c:34: In file included from kernel/sched/sched.h:61: In file included from include/linux/syscalls_api.h:1: In file included from include/linux/syscalls.h:90: In file included from include/trace/syscall.h:7: In file included from include/linux/trace_events.h:10: >> include/linux/perf_event.h:1793:18: warning: declaration of 'struct td_metrics' will not be visible outside of this function [-Wvisibility] struct td_metrics *value) ^ 1 warning generated. -- In file included from kernel/sched/fair.c:56: In file included from kernel/sched/sched.h:61: In file included from include/linux/syscalls_api.h:1: In file included from include/linux/syscalls.h:90: In file included from include/trace/syscall.h:7: In file included from include/linux/trace_events.h:10: >> include/linux/perf_event.h:1793:18: warning: declaration of 'struct td_metrics' will not be visible outside of this function [-Wvisibility] struct td_metrics *value) ^ kernel/sched/fair.c:702:6: warning: no previous prototype for function 'update_entity_lag' [-Wmissing-prototypes] void update_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se) ^ kernel/sched/fair.c:702:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void update_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se) ^ static kernel/sched/fair.c:12732:6: warning: no previous prototype for function 'free_fair_sched_group' [-Wmissing-prototypes] void free_fair_sched_group(struct task_group *tg) { } ^ kernel/sched/fair.c:12732:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void free_fair_sched_group(struct task_group *tg) { } ^ static kernel/sched/fair.c:12734:5: warning: no previous prototype for function 'alloc_fair_sched_group' [-Wmissing-prototypes] int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent) ^ kernel/sched/fair.c:12734:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent) ^ static kernel/sched/fair.c:12739:6: warning: no previous prototype for function 'online_fair_sched_group' [-Wmissing-prototypes] void online_fair_sched_group(struct task_group *tg) { } ^ kernel/sched/fair.c:12739:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void online_fair_sched_group(struct task_group *tg) { } ^ static kernel/sched/fair.c:12741:6: warning: no previous prototype for function 'unregister_fair_sched_group' [-Wmissing-prototypes] void unregister_fair_sched_group(struct task_group *tg) { } ^ kernel/sched/fair.c:12741:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void unregister_fair_sched_group(struct task_group *tg) { } ^ static kernel/sched/fair.c:503:20: warning: unused function 'list_del_leaf_cfs_rq' [-Wunused-function] static inline void list_del_leaf_cfs_rq(struct cfs_rq *cfs_rq) ^ kernel/sched/fair.c:524:19: warning: unused function 'tg_is_idle' [-Wunused-function] static inline int tg_is_idle(struct task_group *tg) ^ kernel/sched/fair.c:548:19: warning: unused function 'max_vruntime' [-Wunused-function] static inline u64 max_vruntime(u64 max_vruntime, u64 vruntime) ^ kernel/sched/fair.c:1262:20: warning: unused function 'is_core_idle' [-Wunused-function] static inline bool is_core_idle(int cpu) ^ kernel/sched/fair.c:3452:20: warning: unused function 'account_numa_enqueue' [-Wunused-function] static inline void account_numa_enqueue(struct rq *rq, struct task_struct *p) ^ kernel/sched/fair.c:3456:20: warning: unused function 'account_numa_dequeue' [-Wunused-function] static inline void account_numa_dequeue(struct rq *rq, struct task_struct *p) ^ kernel/sched/fair.c:3460:20: warning: unused function 'update_scan_period' [-Wunused-function] static inline void update_scan_period(struct task_struct *p, int new_cpu) ^ kernel/sched/fair.c:4872:20: warning: unused function 'cfs_rq_is_decayed' [-Wunused-function] static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq) ^ kernel/sched/fair.c:4887:20: warning: unused function 'remove_entity_load_avg' [-Wunused-function] static inline void remove_entity_load_avg(struct sched_entity *se) {} ^ kernel/sched/fair.c:6259:20: warning: unused function 'cfs_bandwidth_used' [-Wunused-function] static inline bool cfs_bandwidth_used(void) ^ kernel/sched/fair.c:6267:20: warning: unused function 'sync_throttle' [-Wunused-function] static inline void sync_throttle(struct task_group *tg, int cpu) {} ^ kernel/sched/fair.c:6280:19: warning: unused function 'throttled_lb_pair' [-Wunused-function] static inline int throttled_lb_pair(struct task_group *tg, ^ kernel/sched/fair.c:6291:37: warning: unused function 'tg_cfs_bandwidth' [-Wunused-function] static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg) ^ kernel/sched/fair.c:6295:20: warning: unused function 'destroy_cfs_bandwidth' [-Wunused-function] static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {} ^ kernel/sched/fair.c:6296:20: warning: unused function 'update_runtime_enabled' [-Wunused-function] static inline void update_runtime_enabled(struct rq *rq) {} ^ kernel/sched/fair.c:6297:20: warning: unused function 'unthrottle_offline_cfs_rqs' [-Wunused-function] static inline void unthrottle_offline_cfs_rqs(struct rq *rq) {} ^ 22 warnings generated. -- In file included from kernel/sched/core.c:13: In file included from include/linux/syscalls_api.h:1: In file included from include/linux/syscalls.h:90: In file included from include/trace/syscall.h:7: In file included from include/linux/trace_events.h:10: >> include/linux/perf_event.h:1793:18: warning: declaration of 'struct td_metrics' will not be visible outside of this function [-Wvisibility] struct td_metrics *value) ^ kernel/sched/core.c:3695:20: warning: unused function 'rq_has_pinned_tasks' [-Wunused-function] static inline bool rq_has_pinned_tasks(struct rq *rq) ^ kernel/sched/core.c:5822:20: warning: unused function 'sched_tick_start' [-Wunused-function] static inline void sched_tick_start(int cpu) { } ^ kernel/sched/core.c:5823:20: warning: unused function 'sched_tick_stop' [-Wunused-function] static inline void sched_tick_stop(int cpu) { } ^ kernel/sched/core.c:6523:20: warning: unused function 'sched_core_cpu_starting' [-Wunused-function] static inline void sched_core_cpu_starting(unsigned int cpu) {} ^ kernel/sched/core.c:6524:20: warning: unused function 'sched_core_cpu_deactivate' [-Wunused-function] static inline void sched_core_cpu_deactivate(unsigned int cpu) {} ^ kernel/sched/core.c:6525:20: warning: unused function 'sched_core_cpu_dying' [-Wunused-function] static inline void sched_core_cpu_dying(unsigned int cpu) {} ^ 7 warnings generated. vim +1793 include/linux/perf_event.h 1791 1792 static inline int perf_event_topdown_metrics(struct perf_event *event, > 1793 struct td_metrics *value) 1794 { 1795 return 0; 1796 } 1797 #endif 1798
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index e95152531f4c..fe12a2ea10d9 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -1661,6 +1661,11 @@ perf_event_addr_filters(struct perf_event *event) return ifh; } +struct td_metrics { + u64 slots; + u64 metric; +}; + extern void perf_event_addr_filters_sync(struct perf_event *event); extern void perf_report_aux_output_id(struct perf_event *event, u64 hw_id); @@ -1695,6 +1700,8 @@ extern void perf_event_task_tick(void); extern int perf_event_account_interrupt(struct perf_event *event); extern int perf_event_period(struct perf_event *event, u64 value); extern u64 perf_event_pause(struct perf_event *event, bool reset); +extern int perf_event_topdown_metrics(struct perf_event *event, + struct td_metrics *value); #else /* !CONFIG_PERF_EVENTS: */ static inline void * perf_aux_output_begin(struct perf_output_handle *handle, @@ -1781,6 +1788,12 @@ static inline u64 perf_event_pause(struct perf_event *event, bool reset) { return 0; } + +static inline int perf_event_topdown_metrics(struct perf_event *event, + struct td_metrics *value) +{ + return 0; +} #endif #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL) diff --git a/kernel/events/core.c b/kernel/events/core.c index 1877171e9590..6fa86e8bfb89 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5776,6 +5776,68 @@ int perf_event_period(struct perf_event *event, u64 value) } EXPORT_SYMBOL_GPL(perf_event_period); +static void __perf_event_topdown_metrics(struct perf_event *event, + struct perf_cpu_context *cpuctx, + struct perf_event_context *ctx, + void *info) +{ + struct td_metrics *td_metrics = (struct td_metrics *)info; + bool active; + + active = (event->state == PERF_EVENT_STATE_ACTIVE); + if (active) { + perf_pmu_disable(event->pmu); + /* + * We could be throttled; unthrottle now to avoid the tick + * trying to unthrottle while we already re-started the event. + */ + if (event->hw.interrupts == MAX_INTERRUPTS) { + event->hw.interrupts = 0; + perf_log_throttle(event, 1); + } + event->pmu->stop(event, PERF_EF_UPDATE); + } + + event->hw.saved_slots = td_metrics->slots; + event->hw.saved_metric = td_metrics->metric; + + if (active) { + event->pmu->start(event, PERF_EF_RELOAD); + perf_pmu_enable(event->pmu); + } +} + +static int _perf_event_topdown_metrics(struct perf_event *event, + struct td_metrics *value) +{ + /* + * Slots event in topdown metrics scenario + * must be non-sampling event. + */ + if (is_sampling_event(event)) + return -EINVAL; + + if (!value) + return -EINVAL; + + event_function_call(event, __perf_event_topdown_metrics, value); + + return 0; +} + +int perf_event_topdown_metrics(struct perf_event *event, struct td_metrics *value) +{ + struct perf_event_context *ctx; + int ret; + + ctx = perf_event_ctx_lock(event); + ret = _perf_event_topdown_metrics(event, value); + perf_event_ctx_unlock(event, ctx); + + return ret; +} +EXPORT_SYMBOL_GPL(perf_event_topdown_metrics); + static const struct file_operations perf_fops; static inline int perf_fget_light(int fd, struct fd *p)
Add a new function perf_event_topdown_metrics(). This new function is quite familiar with function perf_event_period(), but it updates slots count and metrics raw data instead of sample period into perf system. When guest restores FIXED_CTR3 and PERF_METRICS MSRs in sched-in process, KVM needs to capture the MSR writing trap and set the MSR values of guest into corresponding perf events just like function perf_event_period() does. Initially we tried to reuse the function perf_event_period() to set the slots/metrics value, but we found it was quite hard. The function perf_event_period() only works on sampling events but unfortunately slots event and metric events in topdown mode are all non-sampling events. There are sampling event check and lots of sampling period related check and setting in the function perf_event_period() call-chain. If we want to reuse the function perf_event_period(), we have to add lots of if-else changes on the entire function-chain and even modify the function name. This would totally mess up the function perf_event_period(). Thus, we select to create a new function perf_event_topdown_metrics() to set the slots/metrics values. This makes logic and code both be clearer. Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com> --- include/linux/perf_event.h | 13 ++++++++ kernel/events/core.c | 62 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+)