aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/perf_event.h7
-rw-r--r--kernel/perf_event.c14
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
547typedef 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);
748extern struct perf_event * 752extern struct perf_event *
749perf_event_create_kernel_counter(struct perf_event_attr *attr, 753perf_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);
752extern u64 perf_event_read_value(struct perf_event *event); 757extern u64 perf_event_read_value(struct perf_event *event);
753 758
754struct perf_sample_data { 759struct 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 */
4669struct perf_event * 4675struct perf_event *
4670perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, 4676perf_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);