[PATCH 05/11] perf: Move cgroup init before PMU ->event_init()
From: Matt Fleming 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. Cc: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Signed-off-by: Matt Fleming --- kernel/events/core.c | 28 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index a2ea4a52dbbf..540d995322dd 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6884,7 +6884,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, struct perf_event *group_leader, struct perf_event *parent_event, perf_overflow_handler_t overflow_handler, -void *context) +void *context, int cgroup_fd) { struct pmu *pmu; struct perf_event *event; @@ -6977,6 +6977,12 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP)) goto err_ns; + if (cgroup_fd != -1) { + err = perf_cgroup_connect(cgroup_fd, event, attr, group_leader); + if (err) + goto err_ns; + } + pmu = perf_init_event(event); if (!pmu) goto err_ns; @@ -7000,6 +7006,8 @@ err_pmu: event->destroy(event); module_put(pmu->module); err_ns: + if (is_cgroup_event(event)) + perf_detach_cgroup(event); if (event->ns) put_pid_ns(event->ns); kfree(event); @@ -7207,6 +7215,7 @@ SYSCALL_DEFINE5(perf_event_open, int move_group = 0; int err; int f_flags = O_RDWR; + int cgroup_fd = -1; /* for future expandability... */ if (flags & ~PERF_FLAG_ALL) @@ -7272,21 +7281,16 @@ SYSCALL_DEFINE5(perf_event_open, get_online_cpus(); + if (flags & PERF_FLAG_PID_CGROUP) + cgroup_fd = pid; + event = perf_event_alloc(, cpu, task, group_leader, NULL, -NULL, NULL); +NULL, NULL, cgroup_fd); if (IS_ERR(event)) { err = PTR_ERR(event); goto err_cpus; } - if (flags & PERF_FLAG_PID_CGROUP) { - err = perf_cgroup_connect(pid, event, , group_leader); - if (err) { - __free_event(event); - goto err_cpus; - } - } - if (is_sampling_event(event)) { if (event->pmu->capabilities & PERF_PMU_CAP_NO_INTERRUPT) { err = -ENOTSUPP; @@ -7486,7 +7490,7 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, */ event = perf_event_alloc(attr, cpu, task, NULL, NULL, -overflow_handler, context); +overflow_handler, context, -1); if (IS_ERR(event)) { err = PTR_ERR(event); goto err; @@ -7812,7 +7816,7 @@ inherit_event(struct perf_event *parent_event, parent_event->cpu, child, group_leader, parent_event, - NULL, NULL); + NULL, NULL, -1); if (IS_ERR(child_event)) return child_event; -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 05/11] perf: Move cgroup init before PMU -event_init()
From: Matt Fleming matt.flem...@intel.com 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. Cc: Jiri Olsa jo...@redhat.com Cc: Arnaldo Carvalho de Melo a...@redhat.com Cc: Peter Zijlstra pet...@infradead.org Signed-off-by: Matt Fleming matt.flem...@intel.com --- kernel/events/core.c | 28 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index a2ea4a52dbbf..540d995322dd 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6884,7 +6884,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, struct perf_event *group_leader, struct perf_event *parent_event, perf_overflow_handler_t overflow_handler, -void *context) +void *context, int cgroup_fd) { struct pmu *pmu; struct perf_event *event; @@ -6977,6 +6977,12 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, if (attr-inherit (attr-read_format PERF_FORMAT_GROUP)) goto err_ns; + if (cgroup_fd != -1) { + err = perf_cgroup_connect(cgroup_fd, event, attr, group_leader); + if (err) + goto err_ns; + } + pmu = perf_init_event(event); if (!pmu) goto err_ns; @@ -7000,6 +7006,8 @@ err_pmu: event-destroy(event); module_put(pmu-module); err_ns: + if (is_cgroup_event(event)) + perf_detach_cgroup(event); if (event-ns) put_pid_ns(event-ns); kfree(event); @@ -7207,6 +7215,7 @@ SYSCALL_DEFINE5(perf_event_open, int move_group = 0; int err; int f_flags = O_RDWR; + int cgroup_fd = -1; /* for future expandability... */ if (flags ~PERF_FLAG_ALL) @@ -7272,21 +7281,16 @@ SYSCALL_DEFINE5(perf_event_open, get_online_cpus(); + if (flags PERF_FLAG_PID_CGROUP) + cgroup_fd = pid; + event = perf_event_alloc(attr, cpu, task, group_leader, NULL, -NULL, NULL); +NULL, NULL, cgroup_fd); if (IS_ERR(event)) { err = PTR_ERR(event); 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 (event-pmu-capabilities PERF_PMU_CAP_NO_INTERRUPT) { err = -ENOTSUPP; @@ -7486,7 +7490,7 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, */ event = perf_event_alloc(attr, cpu, task, NULL, NULL, -overflow_handler, context); +overflow_handler, context, -1); if (IS_ERR(event)) { err = PTR_ERR(event); goto err; @@ -7812,7 +7816,7 @@ inherit_event(struct perf_event *parent_event, parent_event-cpu, child, group_leader, parent_event, - NULL, NULL); + NULL, NULL, -1); if (IS_ERR(child_event)) return child_event; -- 1.9.3 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/