Message ID | 20230808063111.1870070-9-dapeng1.mi@linux.intel.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp2373998vqr; Tue, 8 Aug 2023 13:21:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHu0Kac6ecKpK6foogEqT80TezzeL6UXmkkbD7PzvIHezHGimFa2Ttz8GueflxglQ5YHfla X-Received: by 2002:a17:902:d50a:b0:1bb:f11a:d372 with SMTP id b10-20020a170902d50a00b001bbf11ad372mr645285plg.40.1691526097526; Tue, 08 Aug 2023 13:21:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691526097; cv=none; d=google.com; s=arc-20160816; b=xP8m8jarcptOmqUOpfrn926PwntANMYwzKcAR8WQBGCSeeqZDbgyC6AA+kBn0VyDL4 nnyANJouxghGY96XBSVhKTqTYOMoL78PFOJ/kRRc5/pEHlv2nklphzA40SfLYH+ulmtf RuXYqkzSRapwJ5aELXGkirbQ6Q+7Dqua6H0d/M8pGkhczste87LJIjw7nZNrztViXZeY 4YjAHLbettB0WFPT+73va0WP4otN5ell/aQXgR27rnKg+UGUjxY+pUE5tMixIyrGk/ux lUmWE0llnE7sRTmKZoTeZjLqRd8e0GLWFa5QwY3Ua6sjXNSR2N5xVjYCU5rV2WaF7MVs 95gw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=uq4spfQtXkEYSPLR4c2euzYWR5pjmGsJjhgjWaBeNPo=; fh=UPwqiesAqvJCK7JcrgEpVEdaX86ysnZ9K1cUIusTBBs=; b=nuj+cCKXJe4x0ahHUSIWmwfP3rivHpJlRcX9lGIl7zLX6n+DF5F5S8jp1seG/T5Lbz ZdlaBMKmYDVnv7PPqwI7JlRNHcSpNErR4RalOoElJoeHg45xVHuY59KbEM4kTZr6retE VvjlZkzu3RchQ3Sp14IFKAC0o5vk9XdvAK41KRo4ABZrGX+ZSnUhccka0fNIZ9MKFsy+ CweRafJgi9LRpBChIoPzU5zT0iPIIMQT+jK0fh+mNV7Efsz08Z30MzgccM7RjcOngJER +Y6GcsFHpAGQpprAHsy+KbfDLCgWM5mEyN9vbVQqUQu8/s085ZqpHty/y/C4siTPsqRk ehpQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=YUBgdSEN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id f2-20020a170902ce8200b001b85ab48092si8116223plg.499.2023.08.08.13.21.23; Tue, 08 Aug 2023 13:21:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=YUBgdSEN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232094AbjHHTCk (ORCPT <rfc822;aaronkmseo@gmail.com> + 99 others); Tue, 8 Aug 2023 15:02:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40626 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230124AbjHHTBz (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 8 Aug 2023 15:01:55 -0400 Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF693187EB3; Tue, 8 Aug 2023 10:31:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1691515901; x=1723051901; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QlboPx30hLAI4mLeYCjPSJRK7AOUQDBHz0Gu5Bov8K4=; b=YUBgdSENlP7XHM8csFYO+jgGIrYZUyCFDDLLeBEle+qmUCwabVWyHOT0 t8zVbISwiX/3JtJh7kKxLpoTKEdFH8V2h2N9//5tL4rFir+f1P7wc1gLb kkV2+n7QPjuUO6cVs2w7L5p2H96gwdu6Olr2J3diKBCYC8oML6E7B+w1U EmgzS5GYlUwS3wC1xIVxXfbxQyVkCpuow1sHho5KMLkHRo4d8AYuYGx0a OpEYDOtuyMMQp6DyK4PN74wTHiucbgbX2cZ36FYXRw/Ixnq1YjCS+/0n2 O5R0KId3CY9tglsPFuMWBWMt8h8vIt0TraB3GGtYUJGkFe9g9dUFkYTG2 A==; X-IronPort-AV: E=McAfee;i="6600,9927,10795"; a="434582123" X-IronPort-AV: E=Sophos;i="6.01,263,1684825200"; d="scan'208";a="434582123" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Aug 2023 23:27:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10795"; a="734377784" X-IronPort-AV: E=Sophos;i="6.01,263,1684825200"; d="scan'208";a="734377784" Received: from dmi-pnp-i7.sh.intel.com ([10.239.159.155]) by fmsmga007.fm.intel.com with ESMTP; 07 Aug 2023 23:27:13 -0700 From: Dapeng Mi <dapeng1.mi@linux.intel.com> To: Sean Christopherson <seanjc@google.com>, Paolo Bonzini <pbonzini@redhat.com>, Peter Zijlstra <peterz@infradead.org>, Arnaldo Carvalho de Melo <acme@kernel.org>, Kan Liang <kan.liang@linux.intel.com>, Like Xu <likexu@tencent.com>, Mark Rutland <mark.rutland@arm.com>, Alexander Shishkin <alexander.shishkin@linux.intel.com>, Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>, Ian Rogers <irogers@google.com>, Adrian Hunter <adrian.hunter@intel.com> Cc: kvm@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zhenyu Wang <zhenyuw@linux.intel.com>, Zhang Xiong <xiong.y.zhang@intel.com>, Lv Zhiyuan <zhiyuan.lv@intel.com>, Yang Weijiang <weijiang.yang@intel.com>, Dapeng Mi <dapeng1.mi@intel.com>, Dapeng Mi <dapeng1.mi@linux.intel.com> Subject: [PATCH RFV v2 08/13] perf/core: Add new function perf_event_topdown_metrics() Date: Tue, 8 Aug 2023 14:31:06 +0800 Message-Id: <20230808063111.1870070-9-dapeng1.mi@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230808063111.1870070-1-dapeng1.mi@linux.intel.com> References: <20230808063111.1870070-1-dapeng1.mi@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773693669163452041 X-GMAIL-MSGID: 1773693669163452041 |
Series |
Enable fixed counter 3 and topdown perf metrics for vPMU
|
|
Commit Message
Mi, Dapeng
Aug. 8, 2023, 6:31 a.m. UTC
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(+)
Comments
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)