perf: Move cgroup init before PMU ->event_init()
The Intel QoS PMU needs to know whether an event is part of a cgroup during ->event_init(), because tasks in the same cgroup share a monitoring ID. Move the cgroup initialisation before calling into the PMU driver. Signed-off-by: Matt Fleming <matt.fleming@intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Kanaka Juvva <kanaka.d.juvva@intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Vikas Shivappa <vikas.shivappa@linux.intel.com> Link: http://lkml.kernel.org/r/1422038748-21397-4-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
committed by
Ingo Molnar
parent
eacd3ecc34
commit
79dff51e90
@@ -7116,7 +7116,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
|
|||||||
struct perf_event *group_leader,
|
struct perf_event *group_leader,
|
||||||
struct perf_event *parent_event,
|
struct perf_event *parent_event,
|
||||||
perf_overflow_handler_t overflow_handler,
|
perf_overflow_handler_t overflow_handler,
|
||||||
void *context)
|
void *context, int cgroup_fd)
|
||||||
{
|
{
|
||||||
struct pmu *pmu;
|
struct pmu *pmu;
|
||||||
struct perf_event *event;
|
struct perf_event *event;
|
||||||
@@ -7212,6 +7212,12 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
|
|||||||
if (!has_branch_stack(event))
|
if (!has_branch_stack(event))
|
||||||
event->attr.branch_sample_type = 0;
|
event->attr.branch_sample_type = 0;
|
||||||
|
|
||||||
|
if (cgroup_fd != -1) {
|
||||||
|
err = perf_cgroup_connect(cgroup_fd, event, attr, group_leader);
|
||||||
|
if (err)
|
||||||
|
goto err_ns;
|
||||||
|
}
|
||||||
|
|
||||||
pmu = perf_init_event(event);
|
pmu = perf_init_event(event);
|
||||||
if (!pmu)
|
if (!pmu)
|
||||||
goto err_ns;
|
goto err_ns;
|
||||||
@@ -7235,6 +7241,8 @@ err_pmu:
|
|||||||
event->destroy(event);
|
event->destroy(event);
|
||||||
module_put(pmu->module);
|
module_put(pmu->module);
|
||||||
err_ns:
|
err_ns:
|
||||||
|
if (is_cgroup_event(event))
|
||||||
|
perf_detach_cgroup(event);
|
||||||
if (event->ns)
|
if (event->ns)
|
||||||
put_pid_ns(event->ns);
|
put_pid_ns(event->ns);
|
||||||
kfree(event);
|
kfree(event);
|
||||||
@@ -7453,6 +7461,7 @@ SYSCALL_DEFINE5(perf_event_open,
|
|||||||
int move_group = 0;
|
int move_group = 0;
|
||||||
int err;
|
int err;
|
||||||
int f_flags = O_RDWR;
|
int f_flags = O_RDWR;
|
||||||
|
int cgroup_fd = -1;
|
||||||
|
|
||||||
/* for future expandability... */
|
/* for future expandability... */
|
||||||
if (flags & ~PERF_FLAG_ALL)
|
if (flags & ~PERF_FLAG_ALL)
|
||||||
@@ -7518,21 +7527,16 @@ SYSCALL_DEFINE5(perf_event_open,
|
|||||||
|
|
||||||
get_online_cpus();
|
get_online_cpus();
|
||||||
|
|
||||||
|
if (flags & PERF_FLAG_PID_CGROUP)
|
||||||
|
cgroup_fd = pid;
|
||||||
|
|
||||||
event = perf_event_alloc(&attr, cpu, task, group_leader, NULL,
|
event = perf_event_alloc(&attr, cpu, task, group_leader, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL, cgroup_fd);
|
||||||
if (IS_ERR(event)) {
|
if (IS_ERR(event)) {
|
||||||
err = PTR_ERR(event);
|
err = PTR_ERR(event);
|
||||||
goto err_cpus;
|
goto err_cpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & PERF_FLAG_PID_CGROUP) {
|
|
||||||
err = perf_cgroup_connect(pid, event, &attr, group_leader);
|
|
||||||
if (err) {
|
|
||||||
__free_event(event);
|
|
||||||
goto err_cpus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_sampling_event(event)) {
|
if (is_sampling_event(event)) {
|
||||||
if (event->pmu->capabilities & PERF_PMU_CAP_NO_INTERRUPT) {
|
if (event->pmu->capabilities & PERF_PMU_CAP_NO_INTERRUPT) {
|
||||||
err = -ENOTSUPP;
|
err = -ENOTSUPP;
|
||||||
@@ -7769,7 +7773,7 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
event = perf_event_alloc(attr, cpu, task, NULL, NULL,
|
event = perf_event_alloc(attr, cpu, task, NULL, NULL,
|
||||||
overflow_handler, context);
|
overflow_handler, context, -1);
|
||||||
if (IS_ERR(event)) {
|
if (IS_ERR(event)) {
|
||||||
err = PTR_ERR(event);
|
err = PTR_ERR(event);
|
||||||
goto err;
|
goto err;
|
||||||
@@ -8130,7 +8134,7 @@ inherit_event(struct perf_event *parent_event,
|
|||||||
parent_event->cpu,
|
parent_event->cpu,
|
||||||
child,
|
child,
|
||||||
group_leader, parent_event,
|
group_leader, parent_event,
|
||||||
NULL, NULL);
|
NULL, NULL, -1);
|
||||||
if (IS_ERR(child_event))
|
if (IS_ERR(child_event))
|
||||||
return child_event;
|
return child_event;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user