public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
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>,
	Marc Zyngier <maz@kernel.org>
Subject: [PATCH RFV v2 05/13] perf/core: Add function perf_event_create_group_kernel_counters()
Date: Tue,  8 Aug 2023 14:31:03 +0800	[thread overview]
Message-ID: <20230808063111.1870070-6-dapeng1.mi@linux.intel.com> (raw)
In-Reply-To: <20230808063111.1870070-1-dapeng1.mi@linux.intel.com>

Add function perf_event_create_group_kernel_counters() which can be used
to create group perf events from kernel space.

Comparing with modifying function perf_event_create_kernel_counter()
directly to support create group events, creating a new function looks a
better method since function perf_event_create_kernel_counter() is called
by many places in kernel and modifying directly this function introduces
lots of changes.

Kernel space may want to create group events just like user space perf
tool does. One example is to support topdown metrics feature in KVM.

Current perf logic requires perf tool creates an perf events group to
handle the topdown metrics profiling. The events group couples one slots
event acting as group leader and multiple metric events.

To support topdown metrics feature in KVM, KVM has to follow this
requirement to create the events group from kernel space. That's why we
need to add this new function.

Suggested-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
 include/linux/perf_event.h |  6 ++++++
 kernel/events/core.c       | 39 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 2166a69e3bf2..e95152531f4c 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1104,6 +1104,12 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr,
 				struct task_struct *task,
 				perf_overflow_handler_t callback,
 				void *context);
+extern struct perf_event *
+perf_event_create_group_kernel_counters(struct perf_event_attr *attr,
+					int cpu, struct task_struct *task,
+					struct perf_event *group_leader,
+					perf_overflow_handler_t overflow_handler,
+					void *context);
 extern void perf_pmu_migrate_context(struct pmu *pmu,
 				int src_cpu, int dst_cpu);
 int perf_event_read_local(struct perf_event *event, u64 *value,
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 15eb82d1a010..1877171e9590 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -12762,11 +12762,34 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
 				 struct task_struct *task,
 				 perf_overflow_handler_t overflow_handler,
 				 void *context)
+{
+	return perf_event_create_group_kernel_counters(attr, cpu, task,
+			NULL, overflow_handler, context);
+}
+EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter);
+
+/**
+ * perf_event_create_group_kernel_counters
+ *
+ * @attr: attributes of the counter to create
+ * @cpu: cpu in which the counter is bound
+ * @task: task to profile (NULL for percpu)
+ * @group_leader: the group leader event of the created event
+ * @overflow_handler: callback to trigger when we hit the event
+ * @context: context data could be used in overflow_handler callback
+ */
+struct perf_event *
+perf_event_create_group_kernel_counters(struct perf_event_attr *attr,
+					int cpu, struct task_struct *task,
+					struct perf_event *group_leader,
+					perf_overflow_handler_t overflow_handler,
+					void *context)
 {
 	struct perf_event_pmu_context *pmu_ctx;
 	struct perf_event_context *ctx;
 	struct perf_event *event;
 	struct pmu *pmu;
+	int move_group = 0;
 	int err;
 
 	/*
@@ -12776,7 +12799,11 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
 	if (attr->aux_output)
 		return ERR_PTR(-EINVAL);
 
-	event = perf_event_alloc(attr, cpu, task, NULL, NULL,
+	if (task && group_leader &&
+	    group_leader->attr.inherit != attr->inherit)
+		return ERR_PTR(-EINVAL);
+
+	event = perf_event_alloc(attr, cpu, task, group_leader, NULL,
 				 overflow_handler, context, -1);
 	if (IS_ERR(event)) {
 		err = PTR_ERR(event);
@@ -12806,6 +12833,11 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
 		goto err_unlock;
 	}
 
+	err = perf_event_group_leader_check(group_leader, event, attr, ctx,
+					    &pmu, &move_group);
+	if (err)
+		goto err_unlock;
+
 	pmu_ctx = find_get_pmu_context(pmu, ctx, event);
 	if (IS_ERR(pmu_ctx)) {
 		err = PTR_ERR(pmu_ctx);
@@ -12833,6 +12865,9 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
 		goto err_pmu_ctx;
 	}
 
+	if (move_group)
+		perf_event_move_group(group_leader, pmu_ctx, ctx);
+
 	perf_install_in_context(ctx, event, event->cpu);
 	perf_unpin_context(ctx);
 	mutex_unlock(&ctx->mutex);
@@ -12851,7 +12886,7 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
 err:
 	return ERR_PTR(err);
 }
-EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter);
+EXPORT_SYMBOL_GPL(perf_event_create_group_kernel_counters);
 
 static void __perf_pmu_remove(struct perf_event_context *ctx,
 			      int cpu, struct pmu *pmu,
-- 
2.34.1


  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 ` Dapeng Mi [this message]
2023-08-08 10:21   ` [PATCH RFV v2 05/13] perf/core: Add function perf_event_create_group_kernel_counters() 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 ` [PATCH RFV v2 08/13] perf/core: Add new function perf_event_topdown_metrics() Dapeng Mi
2023-08-08 20:16   ` 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-6-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=maz@kernel.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox