aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/perf_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r--kernel/perf_event.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 7223ea875861..357ee8d5e8ae 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -4709,6 +4709,8 @@ static int perf_swevent_init(struct perf_event *event)
4709} 4709}
4710 4710
4711static struct pmu perf_swevent = { 4711static struct pmu perf_swevent = {
4712 .task_ctx_nr = perf_sw_context,
4713
4712 .event_init = perf_swevent_init, 4714 .event_init = perf_swevent_init,
4713 .add = perf_swevent_add, 4715 .add = perf_swevent_add,
4714 .del = perf_swevent_del, 4716 .del = perf_swevent_del,
@@ -4800,6 +4802,8 @@ static int perf_tp_event_init(struct perf_event *event)
4800} 4802}
4801 4803
4802static struct pmu perf_tracepoint = { 4804static struct pmu perf_tracepoint = {
4805 .task_ctx_nr = perf_sw_context,
4806
4803 .event_init = perf_tp_event_init, 4807 .event_init = perf_tp_event_init,
4804 .add = perf_trace_add, 4808 .add = perf_trace_add,
4805 .del = perf_trace_del, 4809 .del = perf_trace_del,
@@ -4988,6 +4992,8 @@ static int cpu_clock_event_init(struct perf_event *event)
4988} 4992}
4989 4993
4990static struct pmu perf_cpu_clock = { 4994static struct pmu perf_cpu_clock = {
4995 .task_ctx_nr = perf_sw_context,
4996
4991 .event_init = cpu_clock_event_init, 4997 .event_init = cpu_clock_event_init,
4992 .add = cpu_clock_event_add, 4998 .add = cpu_clock_event_add,
4993 .del = cpu_clock_event_del, 4999 .del = cpu_clock_event_del,
@@ -5063,6 +5069,8 @@ static int task_clock_event_init(struct perf_event *event)
5063} 5069}
5064 5070
5065static struct pmu perf_task_clock = { 5071static struct pmu perf_task_clock = {
5072 .task_ctx_nr = perf_sw_context,
5073
5066 .event_init = task_clock_event_init, 5074 .event_init = task_clock_event_init,
5067 .add = task_clock_event_add, 5075 .add = task_clock_event_add,
5068 .del = task_clock_event_del, 5076 .del = task_clock_event_del,
@@ -5490,6 +5498,7 @@ SYSCALL_DEFINE5(perf_event_open,
5490 struct perf_event_context *ctx; 5498 struct perf_event_context *ctx;
5491 struct file *event_file = NULL; 5499 struct file *event_file = NULL;
5492 struct file *group_file = NULL; 5500 struct file *group_file = NULL;
5501 struct pmu *pmu;
5493 int event_fd; 5502 int event_fd;
5494 int fput_needed = 0; 5503 int fput_needed = 0;
5495 int err; 5504 int err;
@@ -5522,20 +5531,11 @@ SYSCALL_DEFINE5(perf_event_open,
5522 goto err_fd; 5531 goto err_fd;
5523 } 5532 }
5524 5533
5525 /*
5526 * Get the target context (task or percpu):
5527 */
5528 ctx = find_get_context(event->pmu, pid, cpu);
5529 if (IS_ERR(ctx)) {
5530 err = PTR_ERR(ctx);
5531 goto err_alloc;
5532 }
5533
5534 if (group_fd != -1) { 5534 if (group_fd != -1) {
5535 group_leader = perf_fget_light(group_fd, &fput_needed); 5535 group_leader = perf_fget_light(group_fd, &fput_needed);
5536 if (IS_ERR(group_leader)) { 5536 if (IS_ERR(group_leader)) {
5537 err = PTR_ERR(group_leader); 5537 err = PTR_ERR(group_leader);
5538 goto err_context; 5538 goto err_alloc;
5539 } 5539 }
5540 group_file = group_leader->filp; 5540 group_file = group_leader->filp;
5541 if (flags & PERF_FLAG_FD_OUTPUT) 5541 if (flags & PERF_FLAG_FD_OUTPUT)
@@ -5545,6 +5545,23 @@ SYSCALL_DEFINE5(perf_event_open,
5545 } 5545 }
5546 5546
5547 /* 5547 /*
5548 * Special case software events and allow them to be part of
5549 * any hardware group.
5550 */
5551 pmu = event->pmu;
5552 if ((pmu->task_ctx_nr == perf_sw_context) && group_leader)
5553 pmu = group_leader->pmu;
5554
5555 /*
5556 * Get the target context (task or percpu):
5557 */
5558 ctx = find_get_context(pmu, pid, cpu);
5559 if (IS_ERR(ctx)) {
5560 err = PTR_ERR(ctx);
5561 goto err_group_fd;
5562 }
5563
5564 /*
5548 * Look up the group leader (we will attach this event to it): 5565 * Look up the group leader (we will attach this event to it):
5549 */ 5566 */
5550 if (group_leader) { 5567 if (group_leader) {
@@ -5605,8 +5622,9 @@ SYSCALL_DEFINE5(perf_event_open,
5605 return event_fd; 5622 return event_fd;
5606 5623
5607err_context: 5624err_context:
5608 fput_light(group_file, fput_needed);
5609 put_ctx(ctx); 5625 put_ctx(ctx);
5626err_group_fd:
5627 fput_light(group_file, fput_needed);
5610err_alloc: 5628err_alloc:
5611 free_event(event); 5629 free_event(event);
5612err_fd: 5630err_fd: