perf: Ensure consistent inherit state in groups
authorPeter Zijlstra <[email protected]>
Tue, 6 May 2014 07:59:34 +0000 (09:59 +0200)
committerIngo Molnar <[email protected]>
Wed, 7 May 2014 11:44:17 +0000 (13:44 +0200)
Make sure all events in a group have the same inherit state. It was
possible for group leaders to have inherit set while sibling events
would not have inherit set.

In this case we'd still inherit the siblings, leading to some
non-fatal weirdness.

Signed-off-by: Peter Zijlstra <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/n/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
kernel/events/core.c

index 09866a330af8d5c147019c32762c65c7ad8859c8..1de0d709f69fd83924c5ff6b8df077624c4bf151 100644 (file)
@@ -7081,20 +7081,26 @@ SYSCALL_DEFINE5(perf_event_open,
                }
        }
 
+       if (task && group_leader &&
+           group_leader->attr.inherit != attr.inherit) {
+               err = -EINVAL;
+               goto err_task;
+       }
+
        get_online_cpus();
 
        event = perf_event_alloc(&attr, cpu, task, group_leader, NULL,
                                 NULL, NULL);
        if (IS_ERR(event)) {
                err = PTR_ERR(event);
-               goto err_task;
+               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_task;
+                       goto err_cpus;
                }
        }
 
@@ -7256,8 +7262,9 @@ err_context:
        put_ctx(ctx);
 err_alloc:
        free_event(event);
-err_task:
+err_cpus:
        put_online_cpus();
+err_task:
        if (task)
                put_task_struct(task);
 err_group_fd: