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>
This commit is contained in:
Robert Richter 2008-12-30 04:10:46 +01:00
parent 2cc28b9f26
commit 2d87b14cf8
3 changed files with 25 additions and 14 deletions

View file

@ -329,9 +329,10 @@ static void add_ibs_begin(int cpu, int code, struct mm_struct *mm)
int i, count; int i, count;
unsigned long cookie = 0; unsigned long cookie = 0;
off_t offset; off_t offset;
struct op_entry entry;
struct op_sample *sample; struct op_sample *sample;
sample = op_cpu_buffer_read_entry(cpu); sample = op_cpu_buffer_read_entry(&entry, cpu);
if (!sample) if (!sample)
return; return;
pc = sample->eip; pc = sample->eip;
@ -370,7 +371,7 @@ static void add_ibs_begin(int cpu, int code, struct mm_struct *mm)
count = IBS_OP_CODE_SIZE; /*IBS OP is 5 int64s*/ count = IBS_OP_CODE_SIZE; /*IBS OP is 5 int64s*/
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
sample = op_cpu_buffer_read_entry(cpu); sample = op_cpu_buffer_read_entry(&entry, cpu);
if (!sample) if (!sample)
return; return;
add_event_entry(sample->eip); add_event_entry(sample->eip);
@ -528,6 +529,8 @@ void sync_buffer(int cpu)
sync_buffer_state state = sb_buffer_start; sync_buffer_state state = sb_buffer_start;
unsigned int i; unsigned int i;
unsigned long available; unsigned long available;
struct op_entry entry;
struct op_sample *sample;
mutex_lock(&buffer_mutex); mutex_lock(&buffer_mutex);
@ -537,19 +540,19 @@ void sync_buffer(int cpu)
available = op_cpu_buffer_entries(cpu); available = op_cpu_buffer_entries(cpu);
for (i = 0; i < available; ++i) { for (i = 0; i < available; ++i) {
struct op_sample *s = op_cpu_buffer_read_entry(cpu); sample = op_cpu_buffer_read_entry(&entry, cpu);
if (!s) if (!sample)
break; break;
if (is_code(s->eip)) { if (is_code(sample->eip)) {
switch (s->event) { switch (sample->event) {
case 0: case 0:
case CPU_IS_KERNEL: case CPU_IS_KERNEL:
/* kernel/userspace switch */ /* kernel/userspace switch */
in_kernel = s->event; in_kernel = sample->event;
if (state == sb_buffer_start) if (state == sb_buffer_start)
state = sb_sample_start; state = sb_sample_start;
add_kernel_ctx_switch(s->event); add_kernel_ctx_switch(sample->event);
break; break;
case CPU_TRACE_BEGIN: case CPU_TRACE_BEGIN:
state = sb_bt_start; state = sb_bt_start;
@ -566,7 +569,7 @@ void sync_buffer(int cpu)
default: default:
/* userspace context switch */ /* userspace context switch */
oldmm = mm; oldmm = mm;
new = (struct task_struct *)s->event; new = (struct task_struct *)sample->event;
release_mm(oldmm); release_mm(oldmm);
mm = take_tasks_mm(new); mm = take_tasks_mm(new);
if (mm != oldmm) if (mm != oldmm)
@ -581,7 +584,7 @@ void sync_buffer(int cpu)
/* ignore sample */ /* ignore sample */
continue; continue;
if (add_sample(mm, s, in_kernel)) if (add_sample(mm, sample, in_kernel))
continue; continue;
/* ignore backtraces if failed to add a sample */ /* ignore backtraces if failed to add a sample */

View file

@ -182,20 +182,28 @@ int op_cpu_buffer_write_commit(struct op_entry *entry)
entry->irq_flags); entry->irq_flags);
} }
struct op_sample *op_cpu_buffer_read_entry(int cpu) struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu)
{ {
struct ring_buffer_event *e; struct ring_buffer_event *e;
e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL); e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL);
if (e) if (e)
return ring_buffer_event_data(e); goto event;
if (ring_buffer_swap_cpu(op_ring_buffer_read, if (ring_buffer_swap_cpu(op_ring_buffer_read,
op_ring_buffer_write, op_ring_buffer_write,
cpu)) cpu))
return NULL; return NULL;
e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL); e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL);
if (e) if (e)
return ring_buffer_event_data(e); goto event;
return NULL; return NULL;
event:
entry->event = e;
entry->sample = ring_buffer_event_data(e);
entry->size = (ring_buffer_event_length(e) - sizeof(struct op_sample))
/ sizeof(entry->sample->data[0]);
entry->data = entry->sample->data;
return entry->sample;
} }
unsigned long op_cpu_buffer_entries(int cpu) unsigned long op_cpu_buffer_entries(int cpu)

View file

@ -75,7 +75,7 @@ static inline void op_cpu_buffer_reset(int cpu)
struct op_sample struct op_sample
*op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size); *op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size);
int op_cpu_buffer_write_commit(struct op_entry *entry); int op_cpu_buffer_write_commit(struct op_entry *entry);
struct op_sample *op_cpu_buffer_read_entry(int cpu); struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu);
unsigned long op_cpu_buffer_entries(int cpu); unsigned long op_cpu_buffer_entries(int cpu);
/* transient events for the CPU buffer -> event buffer */ /* transient events for the CPU buffer -> event buffer */