diff options
-rw-r--r-- | include/linux/perf_event.h | 7 | ||||
-rw-r--r-- | kernel/perf_event.c | 14 |
2 files changed, 16 insertions, 5 deletions
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index fa151d49a2ee..8d54e6d25eeb 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -544,6 +544,8 @@ struct perf_pending_entry { | |||
544 | void (*func)(struct perf_pending_entry *); | 544 | void (*func)(struct perf_pending_entry *); |
545 | }; | 545 | }; |
546 | 546 | ||
547 | typedef void (*perf_callback_t)(struct perf_event *, void *); | ||
548 | |||
547 | /** | 549 | /** |
548 | * struct perf_event - performance event kernel representation: | 550 | * struct perf_event - performance event kernel representation: |
549 | */ | 551 | */ |
@@ -639,6 +641,8 @@ struct perf_event { | |||
639 | struct event_filter *filter; | 641 | struct event_filter *filter; |
640 | #endif | 642 | #endif |
641 | 643 | ||
644 | perf_callback_t callback; | ||
645 | |||
642 | #endif /* CONFIG_PERF_EVENTS */ | 646 | #endif /* CONFIG_PERF_EVENTS */ |
643 | }; | 647 | }; |
644 | 648 | ||
@@ -748,7 +752,8 @@ extern int perf_event_release_kernel(struct perf_event *event); | |||
748 | extern struct perf_event * | 752 | extern struct perf_event * |
749 | perf_event_create_kernel_counter(struct perf_event_attr *attr, | 753 | perf_event_create_kernel_counter(struct perf_event_attr *attr, |
750 | int cpu, | 754 | int cpu, |
751 | pid_t pid); | 755 | pid_t pid, |
756 | perf_callback_t callback); | ||
752 | extern u64 perf_event_read_value(struct perf_event *event); | 757 | extern u64 perf_event_read_value(struct perf_event *event); |
753 | 758 | ||
754 | struct perf_sample_data { | 759 | struct perf_sample_data { |
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 02d4ff041b01..5087125e2a00 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -4293,6 +4293,7 @@ perf_event_alloc(struct perf_event_attr *attr, | |||
4293 | struct perf_event_context *ctx, | 4293 | struct perf_event_context *ctx, |
4294 | struct perf_event *group_leader, | 4294 | struct perf_event *group_leader, |
4295 | struct perf_event *parent_event, | 4295 | struct perf_event *parent_event, |
4296 | perf_callback_t callback, | ||
4296 | gfp_t gfpflags) | 4297 | gfp_t gfpflags) |
4297 | { | 4298 | { |
4298 | const struct pmu *pmu; | 4299 | const struct pmu *pmu; |
@@ -4335,6 +4336,11 @@ perf_event_alloc(struct perf_event_attr *attr, | |||
4335 | 4336 | ||
4336 | event->state = PERF_EVENT_STATE_INACTIVE; | 4337 | event->state = PERF_EVENT_STATE_INACTIVE; |
4337 | 4338 | ||
4339 | if (!callback && parent_event) | ||
4340 | callback = parent_event->callback; | ||
4341 | |||
4342 | event->callback = callback; | ||
4343 | |||
4338 | if (attr->disabled) | 4344 | if (attr->disabled) |
4339 | event->state = PERF_EVENT_STATE_OFF; | 4345 | event->state = PERF_EVENT_STATE_OFF; |
4340 | 4346 | ||
@@ -4611,7 +4617,7 @@ SYSCALL_DEFINE5(perf_event_open, | |||
4611 | } | 4617 | } |
4612 | 4618 | ||
4613 | event = perf_event_alloc(&attr, cpu, ctx, group_leader, | 4619 | event = perf_event_alloc(&attr, cpu, ctx, group_leader, |
4614 | NULL, GFP_KERNEL); | 4620 | NULL, NULL, GFP_KERNEL); |
4615 | err = PTR_ERR(event); | 4621 | err = PTR_ERR(event); |
4616 | if (IS_ERR(event)) | 4622 | if (IS_ERR(event)) |
4617 | goto err_put_context; | 4623 | goto err_put_context; |
@@ -4668,7 +4674,7 @@ err_put_context: | |||
4668 | */ | 4674 | */ |
4669 | struct perf_event * | 4675 | struct perf_event * |
4670 | perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, | 4676 | perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, |
4671 | pid_t pid) | 4677 | pid_t pid, perf_callback_t callback) |
4672 | { | 4678 | { |
4673 | struct perf_event *event; | 4679 | struct perf_event *event; |
4674 | struct perf_event_context *ctx; | 4680 | struct perf_event_context *ctx; |
@@ -4683,7 +4689,7 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, | |||
4683 | return NULL ; | 4689 | return NULL ; |
4684 | 4690 | ||
4685 | event = perf_event_alloc(attr, cpu, ctx, NULL, | 4691 | event = perf_event_alloc(attr, cpu, ctx, NULL, |
4686 | NULL, GFP_KERNEL); | 4692 | NULL, callback, GFP_KERNEL); |
4687 | err = PTR_ERR(event); | 4693 | err = PTR_ERR(event); |
4688 | if (IS_ERR(event)) | 4694 | if (IS_ERR(event)) |
4689 | goto err_put_context; | 4695 | goto err_put_context; |
@@ -4736,7 +4742,7 @@ inherit_event(struct perf_event *parent_event, | |||
4736 | child_event = perf_event_alloc(&parent_event->attr, | 4742 | child_event = perf_event_alloc(&parent_event->attr, |
4737 | parent_event->cpu, child_ctx, | 4743 | parent_event->cpu, child_ctx, |
4738 | group_leader, parent_event, | 4744 | group_leader, parent_event, |
4739 | GFP_KERNEL); | 4745 | NULL, GFP_KERNEL); |
4740 | if (IS_ERR(child_event)) | 4746 | if (IS_ERR(child_event)) |
4741 | return child_event; | 4747 | return child_event; |
4742 | get_ctx(child_ctx); | 4748 | get_ctx(child_ctx); |