diff options
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r-- | kernel/perf_event.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index b21d06aaef60..856e20baf13f 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -5255,9 +5255,10 @@ unlock: | |||
5255 | */ | 5255 | */ |
5256 | static struct perf_event * | 5256 | static struct perf_event * |
5257 | perf_event_alloc(struct perf_event_attr *attr, int cpu, | 5257 | perf_event_alloc(struct perf_event_attr *attr, int cpu, |
5258 | struct perf_event *group_leader, | 5258 | struct task_struct *task, |
5259 | struct perf_event *parent_event, | 5259 | struct perf_event *group_leader, |
5260 | perf_overflow_handler_t overflow_handler) | 5260 | struct perf_event *parent_event, |
5261 | perf_overflow_handler_t overflow_handler) | ||
5261 | { | 5262 | { |
5262 | struct pmu *pmu; | 5263 | struct pmu *pmu; |
5263 | struct perf_event *event; | 5264 | struct perf_event *event; |
@@ -5299,6 +5300,17 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
5299 | 5300 | ||
5300 | event->state = PERF_EVENT_STATE_INACTIVE; | 5301 | event->state = PERF_EVENT_STATE_INACTIVE; |
5301 | 5302 | ||
5303 | if (task) { | ||
5304 | event->attach_state = PERF_ATTACH_TASK; | ||
5305 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
5306 | /* | ||
5307 | * hw_breakpoint is a bit difficult here.. | ||
5308 | */ | ||
5309 | if (attr->type == PERF_TYPE_BREAKPOINT) | ||
5310 | event->hw.bp_target = task; | ||
5311 | #endif | ||
5312 | } | ||
5313 | |||
5302 | if (!overflow_handler && parent_event) | 5314 | if (!overflow_handler && parent_event) |
5303 | overflow_handler = parent_event->overflow_handler; | 5315 | overflow_handler = parent_event->overflow_handler; |
5304 | 5316 | ||
@@ -5559,7 +5571,7 @@ SYSCALL_DEFINE5(perf_event_open, | |||
5559 | } | 5571 | } |
5560 | } | 5572 | } |
5561 | 5573 | ||
5562 | event = perf_event_alloc(&attr, cpu, group_leader, NULL, NULL); | 5574 | event = perf_event_alloc(&attr, cpu, task, group_leader, NULL, NULL); |
5563 | if (IS_ERR(event)) { | 5575 | if (IS_ERR(event)) { |
5564 | err = PTR_ERR(event); | 5576 | err = PTR_ERR(event); |
5565 | goto err_task; | 5577 | goto err_task; |
@@ -5728,7 +5740,7 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, | |||
5728 | * Get the target context (task or percpu): | 5740 | * Get the target context (task or percpu): |
5729 | */ | 5741 | */ |
5730 | 5742 | ||
5731 | event = perf_event_alloc(attr, cpu, NULL, NULL, overflow_handler); | 5743 | event = perf_event_alloc(attr, cpu, task, NULL, NULL, overflow_handler); |
5732 | if (IS_ERR(event)) { | 5744 | if (IS_ERR(event)) { |
5733 | err = PTR_ERR(event); | 5745 | err = PTR_ERR(event); |
5734 | goto err; | 5746 | goto err; |
@@ -5996,6 +6008,7 @@ inherit_event(struct perf_event *parent_event, | |||
5996 | 6008 | ||
5997 | child_event = perf_event_alloc(&parent_event->attr, | 6009 | child_event = perf_event_alloc(&parent_event->attr, |
5998 | parent_event->cpu, | 6010 | parent_event->cpu, |
6011 | child, | ||
5999 | group_leader, parent_event, | 6012 | group_leader, parent_event, |
6000 | NULL); | 6013 | NULL); |
6001 | if (IS_ERR(child_event)) | 6014 | if (IS_ERR(child_event)) |