diff options
author | Robert Richter <robert.richter@amd.com> | 2008-12-29 22:10:46 -0500 |
---|---|---|
committer | Robert Richter <robert.richter@amd.com> | 2009-01-07 16:40:02 -0500 |
commit | 2d87b14cf8d0b07720de26d90789d02124141616 (patch) | |
tree | 418285e8cd7127c6207ac9a3e1acf8f0f3c2282f /drivers/oprofile | |
parent | 2cc28b9f261dd28d69767a34682ce55a27d928ed (diff) |
oprofile: modify op_cpu_buffer_read_entry()
This implements the support of samples with attached data.
Signed-off-by: Robert Richter <robert.richter@amd.com>
Diffstat (limited to 'drivers/oprofile')
-rw-r--r-- | drivers/oprofile/buffer_sync.c | 23 | ||||
-rw-r--r-- | drivers/oprofile/cpu_buffer.c | 14 | ||||
-rw-r--r-- | drivers/oprofile/cpu_buffer.h | 2 |
3 files changed, 25 insertions, 14 deletions
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index 21fd249b6e0b..908202afbae9 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c | |||
@@ -329,9 +329,10 @@ static void add_ibs_begin(int cpu, int code, struct mm_struct *mm) | |||
329 | int i, count; | 329 | int i, count; |
330 | unsigned long cookie = 0; | 330 | unsigned long cookie = 0; |
331 | off_t offset; | 331 | off_t offset; |
332 | struct op_entry entry; | ||
332 | struct op_sample *sample; | 333 | struct op_sample *sample; |
333 | 334 | ||
334 | sample = op_cpu_buffer_read_entry(cpu); | 335 | sample = op_cpu_buffer_read_entry(&entry, cpu); |
335 | if (!sample) | 336 | if (!sample) |
336 | return; | 337 | return; |
337 | pc = sample->eip; | 338 | pc = sample->eip; |
@@ -370,7 +371,7 @@ static void add_ibs_begin(int cpu, int code, struct mm_struct *mm) | |||
370 | count = IBS_OP_CODE_SIZE; /*IBS OP is 5 int64s*/ | 371 | count = IBS_OP_CODE_SIZE; /*IBS OP is 5 int64s*/ |
371 | 372 | ||
372 | for (i = 0; i < count; i++) { | 373 | for (i = 0; i < count; i++) { |
373 | sample = op_cpu_buffer_read_entry(cpu); | 374 | sample = op_cpu_buffer_read_entry(&entry, cpu); |
374 | if (!sample) | 375 | if (!sample) |
375 | return; | 376 | return; |
376 | add_event_entry(sample->eip); | 377 | add_event_entry(sample->eip); |
@@ -528,6 +529,8 @@ void sync_buffer(int cpu) | |||
528 | sync_buffer_state state = sb_buffer_start; | 529 | sync_buffer_state state = sb_buffer_start; |
529 | unsigned int i; | 530 | unsigned int i; |
530 | unsigned long available; | 531 | unsigned long available; |
532 | struct op_entry entry; | ||
533 | struct op_sample *sample; | ||
531 | 534 | ||
532 | mutex_lock(&buffer_mutex); | 535 | mutex_lock(&buffer_mutex); |
533 | 536 | ||
@@ -537,19 +540,19 @@ void sync_buffer(int cpu) | |||
537 | available = op_cpu_buffer_entries(cpu); | 540 | available = op_cpu_buffer_entries(cpu); |
538 | 541 | ||
539 | for (i = 0; i < available; ++i) { | 542 | for (i = 0; i < available; ++i) { |
540 | struct op_sample *s = op_cpu_buffer_read_entry(cpu); | 543 | sample = op_cpu_buffer_read_entry(&entry, cpu); |
541 | if (!s) | 544 | if (!sample) |
542 | break; | 545 | break; |
543 | 546 | ||
544 | if (is_code(s->eip)) { | 547 | if (is_code(sample->eip)) { |
545 | switch (s->event) { | 548 | switch (sample->event) { |
546 | case 0: | 549 | case 0: |
547 | case CPU_IS_KERNEL: | 550 | case CPU_IS_KERNEL: |
548 | /* kernel/userspace switch */ | 551 | /* kernel/userspace switch */ |
549 | in_kernel = s->event; | 552 | in_kernel = sample->event; |
550 | if (state == sb_buffer_start) | 553 | if (state == sb_buffer_start) |
551 | state = sb_sample_start; | 554 | state = sb_sample_start; |
552 | add_kernel_ctx_switch(s->event); | 555 | add_kernel_ctx_switch(sample->event); |
553 | break; | 556 | break; |
554 | case CPU_TRACE_BEGIN: | 557 | case CPU_TRACE_BEGIN: |
555 | state = sb_bt_start; | 558 | state = sb_bt_start; |
@@ -566,7 +569,7 @@ void sync_buffer(int cpu) | |||
566 | default: | 569 | default: |
567 | /* userspace context switch */ | 570 | /* userspace context switch */ |
568 | oldmm = mm; | 571 | oldmm = mm; |
569 | new = (struct task_struct *)s->event; | 572 | new = (struct task_struct *)sample->event; |
570 | release_mm(oldmm); | 573 | release_mm(oldmm); |
571 | mm = take_tasks_mm(new); | 574 | mm = take_tasks_mm(new); |
572 | if (mm != oldmm) | 575 | if (mm != oldmm) |
@@ -581,7 +584,7 @@ void sync_buffer(int cpu) | |||
581 | /* ignore sample */ | 584 | /* ignore sample */ |
582 | continue; | 585 | continue; |
583 | 586 | ||
584 | if (add_sample(mm, s, in_kernel)) | 587 | if (add_sample(mm, sample, in_kernel)) |
585 | continue; | 588 | continue; |
586 | 589 | ||
587 | /* ignore backtraces if failed to add a sample */ | 590 | /* ignore backtraces if failed to add a sample */ |
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index 934ff159e70e..400f7fcffdbe 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c | |||
@@ -182,20 +182,28 @@ int op_cpu_buffer_write_commit(struct op_entry *entry) | |||
182 | entry->irq_flags); | 182 | entry->irq_flags); |
183 | } | 183 | } |
184 | 184 | ||
185 | struct op_sample *op_cpu_buffer_read_entry(int cpu) | 185 | struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu) |
186 | { | 186 | { |
187 | struct ring_buffer_event *e; | 187 | struct ring_buffer_event *e; |
188 | e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL); | 188 | e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL); |
189 | if (e) | 189 | if (e) |
190 | return ring_buffer_event_data(e); | 190 | goto event; |
191 | if (ring_buffer_swap_cpu(op_ring_buffer_read, | 191 | if (ring_buffer_swap_cpu(op_ring_buffer_read, |
192 | op_ring_buffer_write, | 192 | op_ring_buffer_write, |
193 | cpu)) | 193 | cpu)) |
194 | return NULL; | 194 | return NULL; |
195 | e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL); | 195 | e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL); |
196 | if (e) | 196 | if (e) |
197 | return ring_buffer_event_data(e); | 197 | goto event; |
198 | return NULL; | 198 | return NULL; |
199 | |||
200 | event: | ||
201 | entry->event = e; | ||
202 | entry->sample = ring_buffer_event_data(e); | ||
203 | entry->size = (ring_buffer_event_length(e) - sizeof(struct op_sample)) | ||
204 | / sizeof(entry->sample->data[0]); | ||
205 | entry->data = entry->sample->data; | ||
206 | return entry->sample; | ||
199 | } | 207 | } |
200 | 208 | ||
201 | unsigned long op_cpu_buffer_entries(int cpu) | 209 | unsigned long op_cpu_buffer_entries(int cpu) |
diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h index 2d4bfdeb7fba..d7c0545ef8b2 100644 --- a/drivers/oprofile/cpu_buffer.h +++ b/drivers/oprofile/cpu_buffer.h | |||
@@ -75,7 +75,7 @@ static inline void op_cpu_buffer_reset(int cpu) | |||
75 | struct op_sample | 75 | struct op_sample |
76 | *op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size); | 76 | *op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size); |
77 | int op_cpu_buffer_write_commit(struct op_entry *entry); | 77 | int op_cpu_buffer_write_commit(struct op_entry *entry); |
78 | struct op_sample *op_cpu_buffer_read_entry(int cpu); | 78 | struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu); |
79 | unsigned long op_cpu_buffer_entries(int cpu); | 79 | unsigned long op_cpu_buffer_entries(int cpu); |
80 | 80 | ||
81 | /* transient events for the CPU buffer -> event buffer */ | 81 | /* transient events for the CPU buffer -> event buffer */ |