2005-04-17 02:20:36 +04:00
/**
* @ file cpu_buffer . h
*
* @ remark Copyright 2002 OProfile authors
* @ remark Read the file COPYING
*
* @ author John Levon < levon @ movementarian . org >
*/
# ifndef OPROFILE_CPU_BUFFER_H
# define OPROFILE_CPU_BUFFER_H
# include <linux/types.h>
# include <linux/spinlock.h>
# include <linux/workqueue.h>
# include <linux/cache.h>
2008-04-28 13:14:15 +04:00
# include <linux/sched.h>
2008-10-16 17:01:40 +04:00
2005-04-17 02:20:36 +04:00
struct task_struct ;
2008-10-16 17:01:40 +04:00
2005-04-17 02:20:36 +04:00
int alloc_cpu_buffers ( void ) ;
void free_cpu_buffers ( void ) ;
void start_cpu_work ( void ) ;
void end_cpu_work ( void ) ;
/* CPU buffer is composed of such entries (which are
* also used for context switch notes )
*/
struct op_sample {
unsigned long eip ;
unsigned long event ;
} ;
2008-10-16 17:01:40 +04:00
2005-04-17 02:20:36 +04:00
struct oprofile_cpu_buffer {
volatile unsigned long head_pos ;
volatile unsigned long tail_pos ;
unsigned long buffer_size ;
2008-09-05 19:12:36 +04:00
struct task_struct * last_task ;
2005-04-17 02:20:36 +04:00
int last_is_kernel ;
int tracing ;
2008-09-05 19:12:36 +04:00
struct op_sample * buffer ;
2005-04-17 02:20:36 +04:00
unsigned long sample_received ;
unsigned long sample_lost_overflow ;
unsigned long backtrace_aborted ;
2007-11-15 03:58:48 +03:00
unsigned long sample_invalid_eip ;
2005-04-17 02:20:36 +04:00
int cpu ;
2006-11-22 17:57:56 +03:00
struct delayed_work work ;
2008-05-15 03:05:31 +04:00
} ;
2005-04-17 02:20:36 +04:00
2008-04-28 13:14:15 +04:00
DECLARE_PER_CPU ( struct oprofile_cpu_buffer , cpu_buffer ) ;
2005-04-17 02:20:36 +04:00
2008-09-05 19:12:36 +04:00
void cpu_buffer_reset ( struct oprofile_cpu_buffer * cpu_buf ) ;
2005-04-17 02:20:36 +04:00
2008-11-27 12:57:09 +03:00
static inline
struct op_sample * cpu_buffer_write_entry ( struct oprofile_cpu_buffer * cpu_buf )
{
return & cpu_buf - > buffer [ cpu_buf - > head_pos ] ;
}
2008-11-27 20:36:08 +03:00
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 ;
}
2008-11-27 12:57:09 +03:00
static inline
struct op_sample * cpu_buffer_read_entry ( struct oprofile_cpu_buffer * cpu_buf )
{
return & cpu_buf - > buffer [ cpu_buf - > tail_pos ] ;
}
2005-04-17 02:20:36 +04:00
/* transient events for the CPU buffer -> event buffer */
# define CPU_IS_KERNEL 1
# define CPU_TRACE_BEGIN 2
2008-07-22 23:08:54 +04:00
# define IBS_FETCH_BEGIN 3
# define IBS_OP_BEGIN 4
2005-04-17 02:20:36 +04:00
# endif /* OPROFILE_CPU_BUFFER_H */