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 03/13] perf/core: Add function perf_event_group_leader_check()
Date: Tue, 8 Aug 2023 14:31:01 +0800 [thread overview]
Message-ID: <20230808063111.1870070-4-dapeng1.mi@linux.intel.com> (raw)
In-Reply-To: <20230808063111.1870070-1-dapeng1.mi@linux.intel.com>
Extract the group leader checking code in function sys_perf_event_open()
to create a new function perf_event_group_leader_check().
The subsequent change would add a new function
perf_event_create_group_kernel_counters() which is used to create group
events in kernel space. The function also needs to do same check for group
leader event just like function sys_perf_event_open() does. So extract
the checking code into a separate function and avoid the code
duplication.
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
kernel/events/core.c | 143 +++++++++++++++++++++++--------------------
1 file changed, 78 insertions(+), 65 deletions(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 78ae7b6f90fd..616391158d7c 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -12324,6 +12324,81 @@ perf_check_permission(struct perf_event_attr *attr, struct task_struct *task)
return is_capable || ptrace_may_access(task, ptrace_mode);
}
+static int perf_event_group_leader_check(struct perf_event *group_leader,
+ struct perf_event *event,
+ struct perf_event_attr *attr,
+ struct perf_event_context *ctx,
+ struct pmu **pmu,
+ int *move_group)
+{
+ if (!group_leader)
+ return 0;
+
+ /*
+ * Do not allow a recursive hierarchy (this new sibling
+ * becoming part of another group-sibling):
+ */
+ if (group_leader->group_leader != group_leader)
+ return -EINVAL;
+
+ /* All events in a group should have the same clock */
+ if (group_leader->clock != event->clock)
+ return -EINVAL;
+
+ /*
+ * Make sure we're both events for the same CPU;
+ * grouping events for different CPUs is broken; since
+ * you can never concurrently schedule them anyhow.
+ */
+ if (group_leader->cpu != event->cpu)
+ return -EINVAL;
+
+ /*
+ * Make sure we're both on the same context; either task or cpu.
+ */
+ if (group_leader->ctx != ctx)
+ return -EINVAL;
+
+ /*
+ * Only a group leader can be exclusive or pinned
+ */
+ if (attr->exclusive || attr->pinned)
+ return -EINVAL;
+
+ if (is_software_event(event) &&
+ !in_software_context(group_leader)) {
+ /*
+ * If the event is a sw event, but the group_leader
+ * is on hw context.
+ *
+ * Allow the addition of software events to hw
+ * groups, this is safe because software events
+ * never fail to schedule.
+ *
+ * Note the comment that goes with struct
+ * perf_event_pmu_context.
+ */
+ *pmu = group_leader->pmu_ctx->pmu;
+ } else if (!is_software_event(event)) {
+ if (is_software_event(group_leader) &&
+ (group_leader->group_caps & PERF_EV_CAP_SOFTWARE)) {
+ /*
+ * In case the group is a pure software group, and we
+ * try to add a hardware event, move the whole group to
+ * the hardware context.
+ */
+ *move_group = 1;
+ }
+
+ /* Don't allow group of multiple hw events from different pmus */
+ if (!in_software_context(group_leader) &&
+ group_leader->pmu_ctx->pmu != *pmu)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/**
* sys_perf_event_open - open a performance event, associate it to a task/cpu
*
@@ -12518,71 +12593,9 @@ SYSCALL_DEFINE5(perf_event_open,
}
}
- if (group_leader) {
- err = -EINVAL;
-
- /*
- * Do not allow a recursive hierarchy (this new sibling
- * becoming part of another group-sibling):
- */
- if (group_leader->group_leader != group_leader)
- goto err_locked;
-
- /* All events in a group should have the same clock */
- if (group_leader->clock != event->clock)
- goto err_locked;
-
- /*
- * Make sure we're both events for the same CPU;
- * grouping events for different CPUs is broken; since
- * you can never concurrently schedule them anyhow.
- */
- if (group_leader->cpu != event->cpu)
- goto err_locked;
-
- /*
- * Make sure we're both on the same context; either task or cpu.
- */
- if (group_leader->ctx != ctx)
- goto err_locked;
-
- /*
- * Only a group leader can be exclusive or pinned
- */
- if (attr.exclusive || attr.pinned)
- goto err_locked;
-
- if (is_software_event(event) &&
- !in_software_context(group_leader)) {
- /*
- * If the event is a sw event, but the group_leader
- * is on hw context.
- *
- * Allow the addition of software events to hw
- * groups, this is safe because software events
- * never fail to schedule.
- *
- * Note the comment that goes with struct
- * perf_event_pmu_context.
- */
- pmu = group_leader->pmu_ctx->pmu;
- } else if (!is_software_event(event)) {
- if (is_software_event(group_leader) &&
- (group_leader->group_caps & PERF_EV_CAP_SOFTWARE)) {
- /*
- * In case the group is a pure software group, and we
- * try to add a hardware event, move the whole group to
- * the hardware context.
- */
- move_group = 1;
- }
-
- /* Don't allow group of multiple hw events from different pmus */
- if (!in_software_context(group_leader) &&
- group_leader->pmu_ctx->pmu != pmu)
- goto err_locked;
- }
- }
+ err = perf_event_group_leader_check(group_leader, event, &attr, ctx, &pmu, &move_group);
+ if (err)
+ goto err_locked;
/*
* Now that we're certain of the pmu; find the pmu_ctx.
--
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 ` Dapeng Mi [this message]
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 ` [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-4-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.