diff options
| author | David S. Miller <davem@davemloft.net> | 2010-03-22 20:05:26 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-03-22 20:05:26 -0700 | 
| commit | 91c030b4d6445ebe9fbddb86d584441f300df15c (patch) | |
| tree | e8a48e3ad9e0448c690268175e555fa651983546 /include/linux/perf_event.h | |
| parent | 7c3456fdb503071787f7f972de1069b9cacd16f0 (diff) | |
| parent | ae6be51ed01d6c4aaf249a207b4434bc7785853b (diff) | |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'include/linux/perf_event.h')
| -rw-r--r-- | include/linux/perf_event.h | 59 | 
1 files changed, 58 insertions, 1 deletions
| diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 6f8cd7da1a01..95477038a72a 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -452,6 +452,8 @@ enum perf_callchain_context {  #include <linux/fs.h>  #include <linux/pid_namespace.h>  #include <linux/workqueue.h> +#include <linux/ftrace.h> +#include <linux/cpu.h>  #include <asm/atomic.h>  #define PERF_MAX_STACK_DEPTH		255 @@ -847,6 +849,44 @@ perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr)  		__perf_sw_event(event_id, nr, nmi, regs, addr);  } +extern void +perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip); + +/* + * Take a snapshot of the regs. Skip ip and frame pointer to + * the nth caller. We only need a few of the regs: + * - ip for PERF_SAMPLE_IP + * - cs for user_mode() tests + * - bp for callchains + * - eflags, for future purposes, just in case + */ +static inline void perf_fetch_caller_regs(struct pt_regs *regs, int skip) +{ +	unsigned long ip; + +	memset(regs, 0, sizeof(*regs)); + +	switch (skip) { +	case 1 : +		ip = CALLER_ADDR0; +		break; +	case 2 : +		ip = CALLER_ADDR1; +		break; +	case 3 : +		ip = CALLER_ADDR2; +		break; +	case 4: +		ip = CALLER_ADDR3; +		break; +	/* No need to support further for now */ +	default: +		ip = 0; +	} + +	return perf_arch_fetch_caller_regs(regs, ip, skip); +} +  extern void __perf_event_mmap(struct vm_area_struct *vma);  static inline void perf_event_mmap(struct vm_area_struct *vma) @@ -880,7 +920,8 @@ static inline bool perf_paranoid_kernel(void)  }  extern void perf_event_init(void); -extern void perf_tp_event(int event_id, u64 addr, u64 count, void *record, int entry_size); +extern void perf_tp_event(int event_id, u64 addr, u64 count, void *record, +			  int entry_size, struct pt_regs *regs);  extern void perf_bp_event(struct perf_event *event, void *data);  #ifndef perf_misc_flags @@ -936,5 +977,21 @@ static inline void perf_event_disable(struct perf_event *event)		{ }  #define perf_output_put(handle, x) \  	perf_output_copy((handle), &(x), sizeof(x)) +/* + * This has to have a higher priority than migration_notifier in sched.c. + */ +#define perf_cpu_notifier(fn)					\ +do {								\ +	static struct notifier_block fn##_nb __cpuinitdata =	\ +		{ .notifier_call = fn, .priority = 20 };	\ +	fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE,		\ +		(void *)(unsigned long)smp_processor_id());	\ +	fn(&fn##_nb, (unsigned long)CPU_STARTING,		\ +		(void *)(unsigned long)smp_processor_id());	\ +	fn(&fn##_nb, (unsigned long)CPU_ONLINE,			\ +		(void *)(unsigned long)smp_processor_id());	\ +	register_cpu_notifier(&fn##_nb);			\ +} while (0) +  #endif /* __KERNEL__ */  #endif /* _LINUX_PERF_EVENT_H */ | 
