aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2008-12-29 22:10:46 -0500
committerRobert Richter <robert.richter@amd.com>2009-01-07 16:40:02 -0500
commit2d87b14cf8d0b07720de26d90789d02124141616 (patch)
tree418285e8cd7127c6207ac9a3e1acf8f0f3c2282f
parent2cc28b9f261dd28d69767a34682ce55a27d928ed (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.c23
-rw-r--r--drivers/oprofile/cpu_buffer.c14
-rw-r--r--drivers/oprofile/cpu_buffer.h2
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
185struct op_sample *op_cpu_buffer_read_entry(int cpu) 185struct 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
200event:
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
201unsigned long op_cpu_buffer_entries(int cpu) 209unsigned 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)
75struct op_sample 75struct 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);
77int op_cpu_buffer_write_commit(struct op_entry *entry); 77int op_cpu_buffer_write_commit(struct op_entry *entry);
78struct op_sample *op_cpu_buffer_read_entry(int cpu); 78struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu);
79unsigned long op_cpu_buffer_entries(int cpu); 79unsigned 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 */