aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/events
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2014-08-01 08:33:01 -0400
committerIngo Molnar <mingo@kernel.org>2014-08-13 01:51:03 -0400
commitf86977620ee4635f26befcf436700493a38ce002 (patch)
treeebb8bbaf19da5d7eb9ccac22c68bf7c1a40a0db1 /kernel/events
parent0f7c29ce90c4d20c23de5657e1e2c2eabf51d69a (diff)
perf: Set owner pointer for kernel events
Adding fake EVENT_OWNER_KERNEL owner pointer value for kernel perf events, so we could distinguish it from user events, which needs special care in following patch. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Link: http://lkml.kernel.org/r/1406896382-18404-3-git-send-email-jolsa@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/events')
-rw-r--r--kernel/events/core.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 1cf24b3e42ec..bbb3ca22f07c 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -119,6 +119,13 @@ static int cpu_function_call(int cpu, int (*func) (void *info), void *info)
119 return data.ret; 119 return data.ret;
120} 120}
121 121
122#define EVENT_OWNER_KERNEL ((void *) -1)
123
124static bool is_kernel_event(struct perf_event *event)
125{
126 return event->owner == EVENT_OWNER_KERNEL;
127}
128
122#define PERF_FLAG_ALL (PERF_FLAG_FD_NO_GROUP |\ 129#define PERF_FLAG_ALL (PERF_FLAG_FD_NO_GROUP |\
123 PERF_FLAG_FD_OUTPUT |\ 130 PERF_FLAG_FD_OUTPUT |\
124 PERF_FLAG_PID_CGROUP |\ 131 PERF_FLAG_PID_CGROUP |\
@@ -3312,16 +3319,12 @@ static void free_event(struct perf_event *event)
3312} 3319}
3313 3320
3314/* 3321/*
3315 * Called when the last reference to the file is gone. 3322 * Remove user event from the owner task.
3316 */ 3323 */
3317static void put_event(struct perf_event *event) 3324static void perf_remove_from_owner(struct perf_event *event)
3318{ 3325{
3319 struct perf_event_context *ctx = event->ctx;
3320 struct task_struct *owner; 3326 struct task_struct *owner;
3321 3327
3322 if (!atomic_long_dec_and_test(&event->refcount))
3323 return;
3324
3325 rcu_read_lock(); 3328 rcu_read_lock();
3326 owner = ACCESS_ONCE(event->owner); 3329 owner = ACCESS_ONCE(event->owner);
3327 /* 3330 /*
@@ -3354,6 +3357,20 @@ static void put_event(struct perf_event *event)
3354 mutex_unlock(&owner->perf_event_mutex); 3357 mutex_unlock(&owner->perf_event_mutex);
3355 put_task_struct(owner); 3358 put_task_struct(owner);
3356 } 3359 }
3360}
3361
3362/*
3363 * Called when the last reference to the file is gone.
3364 */
3365static void put_event(struct perf_event *event)
3366{
3367 struct perf_event_context *ctx = event->ctx;
3368
3369 if (!atomic_long_dec_and_test(&event->refcount))
3370 return;
3371
3372 if (!is_kernel_event(event))
3373 perf_remove_from_owner(event);
3357 3374
3358 WARN_ON_ONCE(ctx->parent_ctx); 3375 WARN_ON_ONCE(ctx->parent_ctx);
3359 /* 3376 /*
@@ -7366,6 +7383,9 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
7366 goto err; 7383 goto err;
7367 } 7384 }
7368 7385
7386 /* Mark owner so we could distinguish it from user events. */
7387 event->owner = EVENT_OWNER_KERNEL;
7388
7369 account_event(event); 7389 account_event(event);
7370 7390
7371 ctx = find_get_context(event->pmu, task, cpu); 7391 ctx = find_get_context(event->pmu, task, cpu);