[PATCH 05/11] perf: Move cgroup init before PMU ->event_init()

2014-11-14 Thread Matt Fleming
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()

2014-11-14 Thread Matt Fleming
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/