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 [thread overview]
Message-ID: <20230808063111.1870070-9-dapeng1.mi@linux.intel.com> (raw)
In-Reply-To: <20230808063111.1870070-1-dapeng1.mi@linux.intel.com>
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(+)
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)
--
2.34.1
next prev parent reply other threads:[~2023-08-08 19:02 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-08 6:30 [PATCH RFV v2 00/13] Enable fixed counter 3 and topdown perf metrics for vPMU Dapeng Mi
2023-08-08 6:30 ` [PATCH RFV v2 01/13] KVM: x86/pmu: Add Intel CPUID-hinted TopDown slots event Dapeng Mi
2023-08-08 6:31 ` [PATCH RFV v2 02/13] KVM: x86/pmu: Support PMU fixed counter 3 Dapeng Mi
2023-08-08 6:31 ` [PATCH RFV v2 03/13] perf/core: Add function perf_event_group_leader_check() Dapeng Mi
2023-08-08 6:31 ` [PATCH RFV v2 04/13] perf/core: Add function perf_event_move_group() Dapeng Mi
2023-08-08 6:31 ` [PATCH RFV v2 05/13] perf/core: Add function perf_event_create_group_kernel_counters() Dapeng Mi
2023-08-08 10:21 ` Peter Zijlstra
2023-08-09 8:44 ` Dapeng Mi
2023-08-08 6:31 ` [PATCH RFV v2 06/13] perf/x86: Fix typos and inconsistent indents in perf_event header Dapeng Mi
2023-08-08 6:31 ` [PATCH RFV v2 07/13] perf/x86: Add constraint for guest perf metrics event Dapeng Mi
2023-08-08 6:31 ` Dapeng Mi [this message]
2023-08-08 20:16 ` [PATCH RFV v2 08/13] perf/core: Add new function perf_event_topdown_metrics() kernel test robot
2023-08-08 20:16 ` kernel test robot
2023-08-08 6:31 ` [PATCH RFV v2 09/13] perf/x86/intel: Handle KVM virtual metrics event in perf system Dapeng Mi
2023-08-08 6:31 ` [PATCH RFV v2 10/13] KVM: x86/pmu: Extend pmc_reprogram_counter() to create group events Dapeng Mi
2023-08-08 6:31 ` [PATCH RFV v2 11/13] KVM: x86/pmu: Support topdown perf metrics feature Dapeng Mi
2023-08-08 6:31 ` [PATCH RFV v2 12/13] KVM: x86/pmu: Handle PERF_METRICS overflow Dapeng Mi
2023-08-08 6:31 ` [PATCH RFV v2 13/13] KVM: x86/pmu: Expose Topdown in MSR_IA32_PERF_CAPABILITIES Dapeng Mi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230808063111.1870070-9-dapeng1.mi@linux.intel.com \
--to=dapeng1.mi@linux.intel.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=dapeng1.mi@intel.com \
--cc=irogers@google.com \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--cc=kvm@vger.kernel.org \
--cc=likexu@tencent.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=namhyung@kernel.org \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=seanjc@google.com \
--cc=weijiang.yang@intel.com \
--cc=xiong.y.zhang@intel.com \
--cc=zhenyuw@linux.intel.com \
--cc=zhiyuan.lv@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.