Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d87b14c authored by Robert Richter's avatar Robert Richter
Browse files

oprofile: modify op_cpu_buffer_read_entry()



This implements the support of samples with attached data.

Signed-off-by: default avatarRobert Richter <robert.richter@amd.com>
parent 2cc28b9f
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -329,9 +329,10 @@ static void add_ibs_begin(int cpu, int code, struct mm_struct *mm)
	int i, count;
	unsigned long cookie = 0;
	off_t offset;
	struct op_entry entry;
	struct op_sample *sample;

	sample = op_cpu_buffer_read_entry(cpu);
	sample = op_cpu_buffer_read_entry(&entry, cpu);
	if (!sample)
		return;
	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*/

	for (i = 0; i < count; i++) {
		sample = op_cpu_buffer_read_entry(cpu);
		sample = op_cpu_buffer_read_entry(&entry, cpu);
		if (!sample)
			return;
		add_event_entry(sample->eip);
@@ -528,6 +529,8 @@ void sync_buffer(int cpu)
	sync_buffer_state state = sb_buffer_start;
	unsigned int i;
	unsigned long available;
	struct op_entry entry;
	struct op_sample *sample;

	mutex_lock(&buffer_mutex);

@@ -537,19 +540,19 @@ void sync_buffer(int cpu)
	available = op_cpu_buffer_entries(cpu);

	for (i = 0; i < available; ++i) {
		struct op_sample *s = op_cpu_buffer_read_entry(cpu);
		if (!s)
		sample = op_cpu_buffer_read_entry(&entry, cpu);
		if (!sample)
			break;

		if (is_code(s->eip)) {
			switch (s->event) {
		if (is_code(sample->eip)) {
			switch (sample->event) {
			case 0:
			case CPU_IS_KERNEL:
				/* kernel/userspace switch */
				in_kernel = s->event;
				in_kernel = sample->event;
				if (state == sb_buffer_start)
					state = sb_sample_start;
				add_kernel_ctx_switch(s->event);
				add_kernel_ctx_switch(sample->event);
				break;
			case CPU_TRACE_BEGIN:
				state = sb_bt_start;
@@ -566,7 +569,7 @@ void sync_buffer(int cpu)
			default:
				/* userspace context switch */
				oldmm = mm;
				new = (struct task_struct *)s->event;
				new = (struct task_struct *)sample->event;
				release_mm(oldmm);
				mm = take_tasks_mm(new);
				if (mm != oldmm)
@@ -581,7 +584,7 @@ void sync_buffer(int cpu)
			/* ignore sample */
			continue;

		if (add_sample(mm, s, in_kernel))
		if (add_sample(mm, sample, in_kernel))
			continue;

		/* ignore backtraces if failed to add a sample */
+11 −3
Original line number Diff line number Diff line
@@ -182,20 +182,28 @@ int op_cpu_buffer_write_commit(struct op_entry *entry)
					 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;
	e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL);
	if (e)
		return ring_buffer_event_data(e);
		goto event;
	if (ring_buffer_swap_cpu(op_ring_buffer_read,
				 op_ring_buffer_write,
				 cpu))
		return NULL;
	e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL);
	if (e)
		return ring_buffer_event_data(e);
		goto event;
	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)
+1 −1
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ static inline void op_cpu_buffer_reset(int cpu)
struct op_sample
*op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size);
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);

/* transient events for the CPU buffer -> event buffer */