| /** |
| * @file oprofile.h |
| * Main driver code |
| * |
| * @remark Copyright 2002 OProfile authors |
| * @remark Read the file COPYING |
| * |
| * @author John Levon |
| * @author Philippe Elie |
| */ |
| |
| #ifndef OPROFILE_H |
| #define OPROFILE_H |
| |
| #include <linux/version.h> |
| #include <linux/module.h> |
| #include <linux/config.h> |
| #include <linux/kernel.h> |
| #include <linux/init.h> |
| #include <linux/slab.h> |
| #include <linux/delay.h> |
| #include <linux/vmalloc.h> |
| #include <linux/sched.h> |
| #include <linux/sysctl.h> |
| #include <linux/smp_lock.h> |
| |
| #include <asm/uaccess.h> |
| |
| #include "compat.h" |
| |
| #include "op_config_24.h" |
| #include "op_hw_config.h" |
| #include "op_interface.h" |
| #include "op_cpu_type.h" |
| |
| #undef min |
| #undef max |
| |
| #define streq(a, b) (!strcmp((a), (b))) |
| |
| /* per-cpu dynamic data */ |
| struct _oprof_data { |
| /* eviction buffer */ |
| struct op_sample * buffer; |
| /* nr. in buffer */ |
| uint buf_size; |
| /* we try to wakeup when nextbuf >= buf_watermark */ |
| uint buf_watermark; |
| /* next in buffer (atomic) */ |
| uint nextbuf; |
| /* number of IRQs for this CPU */ |
| uint nr_irq; |
| /* buffer overflow cumulated size */ |
| uint nr_buffer_overflow; |
| /* reset counter values */ |
| uint ctr_count[OP_MAX_COUNTERS]; |
| }; |
| |
| /* reflect /proc/sys/dev/oprofile/#counter files */ |
| struct oprof_counter { |
| int count; |
| int enabled; |
| int event; |
| int kernel; |
| int user; |
| int unit_mask; |
| }; |
| |
| /* reflect /proc/sys/dev/oprofile files */ |
| struct oprof_sysctl { |
| /* nr. in eviction buffser */ |
| int buf_size; |
| /* sysctl dump */ |
| int dump; |
| /* dump and stop */ |
| int dump_stop; |
| /* nr. in note buffer */ |
| int note_size; |
| /* nr. interrupts occured */ |
| int nr_interrupts; |
| /* the cpu core type: CPU_PPRO, CPU_PII ... */ |
| int cpu_type; |
| /* nr note buffer overflow */ |
| int nr_note_buffer_overflow; |
| /* nr buffer overflow */ |
| int nr_buffer_overflow; |
| /* counter setup */ |
| struct oprof_counter ctr[OP_MAX_COUNTERS]; |
| }; |
| |
| /** |
| * A interrupt handler must implement these routines. |
| * When an interrupt arrives, it must eventually call |
| * op_do_profile(). |
| */ |
| struct op_int_operations { |
| /* initialise the interrupt handler on module load. |
| * On failure deinit handler is not called so all resources |
| * allocated by init() must be freed before returning an error code |
| * (or 0 on success) |
| */ |
| int (*init)(void); |
| /* deinitialise on module unload */ |
| void (*deinit)(void); |
| /* add any handler-specific sysctls at the position given by @next. Return 0 on success */ |
| int (*add_sysctls)(ctl_table * next); |
| /* remove handler-specific sysctls */ |
| void (*remove_sysctls)(ctl_table * next); |
| /* check given profiling parameters are correct. Return 0 on success */ |
| int (*check_params)(void); |
| /* setup the handler from profiling parameters. Return 0 on success */ |
| int (*setup)(void); |
| /* start profiling on all CPUs */ |
| void (*start)(void); |
| /* stop profiling on all CPUs */ |
| void (*stop)(void); |
| /* start profiling on the given CPU */ |
| void (*start_cpu)(uint); |
| /* stop profiling on the given CPU */ |
| void (*stop_cpu)(uint); |
| }; |
| |
| /* maximum depth of dname trees - this is just a page */ |
| #define DNAME_STACK_MAX 1024 |
| |
| /* oprof_start() copy here the sysctl settable parameters */ |
| extern struct oprof_sysctl sysctl; |
| |
| int oprof_init(void); |
| void oprof_exit(void); |
| unsigned long is_map_ready(void); |
| int oprof_hash_map_open(void); |
| int oprof_hash_map_release(void); |
| int oprof_hash_map_mmap(struct file * file, struct vm_area_struct * vma); |
| int oprof_map_open(void); |
| int oprof_map_release(void); |
| int oprof_init_hashmap(void); |
| void oprof_free_hashmap(void); |
| |
| /* used by interrupt handlers if the underlined harware doesn't support |
| * performance counter */ |
| extern struct op_int_operations op_rtc_ops; |
| |
| void op_do_profile(uint cpu, long eip, long irq_enabled, int ctr); |
| extern struct _oprof_data oprof_data[NR_CPUS]; |
| extern struct oprof_sysctl sysctl_parms; |
| extern int lproc_dointvec(ctl_table * table, int write, struct file * filp, void * buffer, size_t * lenp); |
| |
| /* functionality provided by the architecture dependent file */ |
| /* must return OP_RTC if the hardware doesn't support something like |
| * perf counter */ |
| op_cpu get_cpu_type(void); |
| /* return an interface pointer, this function is called only if get_cpu_type |
| * doesn't return OP_RTC */ |
| struct op_int_operations const * op_int_interface(void); |
| /* intercept the needed syscall */ |
| void op_intercept_syscalls(void); |
| void op_restore_syscalls(void); |
| void op_save_syscalls(void); |
| |
| #endif /* OPROFILE_H */ |