X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=drivers%2Foprofile%2Fcpu_buffer.h;h=6055b5678394bc51fa0ddab7235c15df92682b01;hb=bf589e32960181fa8cbca7bfdd92265e49dc2dfa;hp=d3cc26264db55b60948a71b9f8500a236666a64d;hpb=24924f884cd36603615ea5496244e542b0b513c6;p=linux-2.6-block.git diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h index d3cc26264db5..6055b5678394 100644 --- a/drivers/oprofile/cpu_buffer.h +++ b/drivers/oprofile/cpu_buffer.h @@ -52,6 +52,62 @@ DECLARE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer); void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf); +static inline +struct op_sample *cpu_buffer_write_entry(struct oprofile_cpu_buffer *cpu_buf) +{ + return &cpu_buf->buffer[cpu_buf->head_pos]; +} + +static inline +void cpu_buffer_write_commit(struct oprofile_cpu_buffer *b) +{ + unsigned long new_head = b->head_pos + 1; + + /* + * Ensure anything written to the slot before we increment is + * visible + */ + wmb(); + + if (new_head < b->buffer_size) + b->head_pos = new_head; + else + b->head_pos = 0; +} + +static inline +struct op_sample *cpu_buffer_read_entry(struct oprofile_cpu_buffer *cpu_buf) +{ + return &cpu_buf->buffer[cpu_buf->tail_pos]; +} + +/* "acquire" as many cpu buffer slots as we can */ +static inline +unsigned long cpu_buffer_entries(struct oprofile_cpu_buffer *b) +{ + unsigned long head = b->head_pos; + unsigned long tail = b->tail_pos; + + /* + * Subtle. This resets the persistent last_task + * and in_kernel values used for switching notes. + * BUT, there is a small window between reading + * head_pos, and this call, that means samples + * can appear at the new head position, but not + * be prefixed with the notes for switching + * kernel mode or a task switch. This small hole + * can lead to mis-attribution or samples where + * we don't know if it's in the kernel or not, + * at the start of an event buffer. + */ + cpu_buffer_reset(b); + + if (head >= tail) + return head - tail; + + return head + (b->buffer_size - tail); +} + /* transient events for the CPU buffer -> event buffer */ #define CPU_IS_KERNEL 1 #define CPU_TRACE_BEGIN 2