aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/perf_event.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-12-03 13:36:35 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-12-04 19:56:48 -0500
commit6844c09d849aeb00e8ddfe9525e8567a531c22d0 (patch)
tree6377067b6979199b249596aa6f3c9204d38cb8eb /kernel/perf_event.c
parent614b6780eb0c393d2fb49ff62d61f29b877bd07e (diff)
perf events: Separate the routines handling the PERF_SAMPLE_ identity fields
Those will be made available in sample like events like MMAP, EXEC, etc in a followup patch. So precalculate the extra id header space and have a separate routine to fill them up. V2: Thomas noticed that the id header needs to be precalculated at inherit_events too: LKML-Reference: <alpine.LFD.2.00.1012031245220.2653@localhost6.localdomain6> Tested-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Ian Munsie <imunsie@au1.ibm.com> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Acked-by: Thomas Gleixner <tglx@linutronix.de> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Ian Munsie <imunsie@au1.ibm.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> LKML-Reference: <1291318772-30880-2-git-send-email-acme@infradead.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r--kernel/perf_event.c129
1 files changed, 75 insertions, 54 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 7961b27aceea..a04799769566 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -133,6 +133,28 @@ static void unclone_ctx(struct perf_event_context *ctx)
133 } 133 }
134} 134}
135 135
136static u32 perf_event_pid(struct perf_event *event, struct task_struct *p)
137{
138 /*
139 * only top level events have the pid namespace they were created in
140 */
141 if (event->parent)
142 event = event->parent;
143
144 return task_tgid_nr_ns(p, event->ns);
145}
146
147static u32 perf_event_tid(struct perf_event *event, struct task_struct *p)
148{
149 /*
150 * only top level events have the pid namespace they were created in
151 */
152 if (event->parent)
153 event = event->parent;
154
155 return task_pid_nr_ns(p, event->ns);
156}
157
136/* 158/*
137 * If we inherit events we want to return the parent event id 159 * If we inherit events we want to return the parent event id
138 * to userspace. 160 * to userspace.
@@ -351,15 +373,30 @@ static void perf_event__header_size(struct perf_event *event)
351 if (sample_type & PERF_SAMPLE_IP) 373 if (sample_type & PERF_SAMPLE_IP)
352 size += sizeof(data->ip); 374 size += sizeof(data->ip);
353 375
376 if (sample_type & PERF_SAMPLE_ADDR)
377 size += sizeof(data->addr);
378
379 if (sample_type & PERF_SAMPLE_PERIOD)
380 size += sizeof(data->period);
381
382 if (sample_type & PERF_SAMPLE_READ)
383 size += event->read_size;
384
385 event->header_size = size;
386}
387
388static void perf_event__id_header_size(struct perf_event *event)
389{
390 struct perf_sample_data *data;
391 u64 sample_type = event->attr.sample_type;
392 u16 size = 0;
393
354 if (sample_type & PERF_SAMPLE_TID) 394 if (sample_type & PERF_SAMPLE_TID)
355 size += sizeof(data->tid_entry); 395 size += sizeof(data->tid_entry);
356 396
357 if (sample_type & PERF_SAMPLE_TIME) 397 if (sample_type & PERF_SAMPLE_TIME)
358 size += sizeof(data->time); 398 size += sizeof(data->time);
359 399
360 if (sample_type & PERF_SAMPLE_ADDR)
361 size += sizeof(data->addr);
362
363 if (sample_type & PERF_SAMPLE_ID) 400 if (sample_type & PERF_SAMPLE_ID)
364 size += sizeof(data->id); 401 size += sizeof(data->id);
365 402
@@ -369,13 +406,7 @@ static void perf_event__header_size(struct perf_event *event)
369 if (sample_type & PERF_SAMPLE_CPU) 406 if (sample_type & PERF_SAMPLE_CPU)
370 size += sizeof(data->cpu_entry); 407 size += sizeof(data->cpu_entry);
371 408
372 if (sample_type & PERF_SAMPLE_PERIOD) 409 event->id_header_size = size;
373 size += sizeof(data->period);
374
375 if (sample_type & PERF_SAMPLE_READ)
376 size += event->read_size;
377
378 event->header_size = size;
379} 410}
380 411
381static void perf_group_attach(struct perf_event *event) 412static void perf_group_attach(struct perf_event *event)
@@ -3357,6 +3388,36 @@ __always_inline void perf_output_copy(struct perf_output_handle *handle,
3357 } while (len); 3388 } while (len);
3358} 3389}
3359 3390
3391static void perf_event_header__init_id(struct perf_event_header *header,
3392 struct perf_sample_data *data,
3393 struct perf_event *event)
3394{
3395 u64 sample_type = event->attr.sample_type;
3396
3397 data->type = sample_type;
3398 header->size += event->id_header_size;
3399
3400 if (sample_type & PERF_SAMPLE_TID) {
3401 /* namespace issues */
3402 data->tid_entry.pid = perf_event_pid(event, current);
3403 data->tid_entry.tid = perf_event_tid(event, current);
3404 }
3405
3406 if (sample_type & PERF_SAMPLE_TIME)
3407 data->time = perf_clock();
3408
3409 if (sample_type & PERF_SAMPLE_ID)
3410 data->id = primary_event_id(event);
3411
3412 if (sample_type & PERF_SAMPLE_STREAM_ID)
3413 data->stream_id = event->id;
3414
3415 if (sample_type & PERF_SAMPLE_CPU) {
3416 data->cpu_entry.cpu = raw_smp_processor_id();
3417 data->cpu_entry.reserved = 0;
3418 }
3419}
3420
3360int perf_output_begin(struct perf_output_handle *handle, 3421int perf_output_begin(struct perf_output_handle *handle,
3361 struct perf_event *event, unsigned int size, 3422 struct perf_event *event, unsigned int size,
3362 int nmi, int sample) 3423 int nmi, int sample)
@@ -3459,28 +3520,6 @@ void perf_output_end(struct perf_output_handle *handle)
3459 rcu_read_unlock(); 3520 rcu_read_unlock();
3460} 3521}
3461 3522
3462static u32 perf_event_pid(struct perf_event *event, struct task_struct *p)
3463{
3464 /*
3465 * only top level events have the pid namespace they were created in
3466 */
3467 if (event->parent)
3468 event = event->parent;
3469
3470 return task_tgid_nr_ns(p, event->ns);
3471}
3472
3473static u32 perf_event_tid(struct perf_event *event, struct task_struct *p)
3474{
3475 /*
3476 * only top level events have the pid namespace they were created in
3477 */
3478 if (event->parent)
3479 event = event->parent;
3480
3481 return task_pid_nr_ns(p, event->ns);
3482}
3483
3484static void perf_output_read_one(struct perf_output_handle *handle, 3523static void perf_output_read_one(struct perf_output_handle *handle,
3485 struct perf_event *event, 3524 struct perf_event *event,
3486 u64 enabled, u64 running) 3525 u64 enabled, u64 running)
@@ -3655,37 +3694,17 @@ void perf_prepare_sample(struct perf_event_header *header,
3655{ 3694{
3656 u64 sample_type = event->attr.sample_type; 3695 u64 sample_type = event->attr.sample_type;
3657 3696
3658 data->type = sample_type;
3659
3660 header->type = PERF_RECORD_SAMPLE; 3697 header->type = PERF_RECORD_SAMPLE;
3661 header->size = sizeof(*header) + event->header_size; 3698 header->size = sizeof(*header) + event->header_size;
3662 3699
3663 header->misc = 0; 3700 header->misc = 0;
3664 header->misc |= perf_misc_flags(regs); 3701 header->misc |= perf_misc_flags(regs);
3665 3702
3703 perf_event_header__init_id(header, data, event);
3704
3666 if (sample_type & PERF_SAMPLE_IP) 3705 if (sample_type & PERF_SAMPLE_IP)
3667 data->ip = perf_instruction_pointer(regs); 3706 data->ip = perf_instruction_pointer(regs);
3668 3707
3669 if (sample_type & PERF_SAMPLE_TID) {
3670 /* namespace issues */
3671 data->tid_entry.pid = perf_event_pid(event, current);
3672 data->tid_entry.tid = perf_event_tid(event, current);
3673 }
3674
3675 if (sample_type & PERF_SAMPLE_TIME)
3676 data->time = perf_clock();
3677
3678 if (sample_type & PERF_SAMPLE_ID)
3679 data->id = primary_event_id(event);
3680
3681 if (sample_type & PERF_SAMPLE_STREAM_ID)
3682 data->stream_id = event->id;
3683
3684 if (sample_type & PERF_SAMPLE_CPU) {
3685 data->cpu_entry.cpu = raw_smp_processor_id();
3686 data->cpu_entry.reserved = 0;
3687 }
3688
3689 if (sample_type & PERF_SAMPLE_CALLCHAIN) { 3708 if (sample_type & PERF_SAMPLE_CALLCHAIN) {
3690 int size = 1; 3709 int size = 1;
3691 3710
@@ -5745,6 +5764,7 @@ SYSCALL_DEFINE5(perf_event_open,
5745 * Precalculate sample_data sizes 5764 * Precalculate sample_data sizes
5746 */ 5765 */
5747 perf_event__header_size(event); 5766 perf_event__header_size(event);
5767 perf_event__id_header_size(event);
5748 5768
5749 /* 5769 /*
5750 * Drop the reference on the group_event after placing the 5770 * Drop the reference on the group_event after placing the
@@ -6102,6 +6122,7 @@ inherit_event(struct perf_event *parent_event,
6102 * Precalculate sample_data sizes 6122 * Precalculate sample_data sizes
6103 */ 6123 */
6104 perf_event__header_size(child_event); 6124 perf_event__header_size(child_event);
6125 perf_event__id_header_size(child_event);
6105 6126
6106 /* 6127 /*
6107 * Link it up in the child's context: 6128 * Link it up in the child's context: