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 | |
| 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>
| -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 */ |
