perf_counter.h 4.7 KB
Newer Older
T
Thomas Gleixner 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 *  Performance counters:
 *
 *   Copyright(C) 2008, Thomas Gleixner <tglx@linutronix.de>
 *   Copyright(C) 2008, Red Hat, Inc., Ingo Molnar
 *
 *  Data type definitions, declarations, prototypes.
 *
 *  Started by: Thomas Gleixner and Ingo Molnar
 *
 *  For licencing details see kernel-base/COPYING
 */
#ifndef _LINUX_PERF_COUNTER_H
#define _LINUX_PERF_COUNTER_H

#include <asm/atomic.h>

#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/spinlock.h>

struct task_struct;

/*
I
Ingo Molnar 已提交
27 28 29 30 31 32
 * User-space ABI bits:
 */

/*
 * Generalized performance counter event types, used by the hw_event.type
 * parameter of the sys_perf_counter_open() syscall:
T
Thomas Gleixner 已提交
33 34 35
 */
enum hw_event_types {
	/*
I
Ingo Molnar 已提交
36
	 * Common hardware events, generalized by the kernel:
T
Thomas Gleixner 已提交
37
	 */
I
Ingo Molnar 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
	PERF_COUNT_CYCLES		=  0,
	PERF_COUNT_INSTRUCTIONS		=  1,
	PERF_COUNT_CACHE_REFERENCES	=  2,
	PERF_COUNT_CACHE_MISSES		=  3,
	PERF_COUNT_BRANCH_INSTRUCTIONS	=  4,
	PERF_COUNT_BRANCH_MISSES	=  5,

	/*
	 * Special "software" counters provided by the kernel, even if
	 * the hardware does not support performance counters. These
	 * counters measure various physical and sw events of the
	 * kernel (and allow the profiling of them as well):
	 */
	PERF_COUNT_CPU_CLOCK		= -1,
	PERF_COUNT_TASK_CLOCK		= -2,
	PERF_COUNT_PAGE_FAULTS		= -3,
	PERF_COUNT_CONTEXT_SWITCHES	= -4,
T
Thomas Gleixner 已提交
55 56 57 58 59
};

/*
 * IRQ-notification data record type:
 */
I
Ingo Molnar 已提交
60 61 62 63
enum perf_counter_record_type {
	PERF_RECORD_SIMPLE		=  0,
	PERF_RECORD_IRQ			=  1,
	PERF_RECORD_GROUP		=  2,
T
Thomas Gleixner 已提交
64 65
};

I
Ingo Molnar 已提交
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
/*
 * Hardware event to monitor via a performance monitoring counter:
 */
struct perf_counter_hw_event {
	u64			type;

	u64			irq_period;
	u32			record_type;

	u32			disabled     :  1, /* off by default */
				nmi	     :  1, /* NMI sampling   */
				raw	     :  1, /* raw event type */
				__reserved_1 : 29;

	u64			__reserved_2;
81 82
};

I
Ingo Molnar 已提交
83 84 85 86
/*
 * Kernel-internal data types:
 */

T
Thomas Gleixner 已提交
87
/**
I
Ingo Molnar 已提交
88
 * struct hw_perf_counter - performance counter hardware details:
T
Thomas Gleixner 已提交
89 90
 */
struct hw_perf_counter {
I
Ingo Molnar 已提交
91 92 93 94 95 96 97 98
	u64				config;
	unsigned long			config_base;
	unsigned long			counter_base;
	int				nmi;
	unsigned int			idx;
	u64				prev_count;
	u64				irq_period;
	s32				next_count;
T
Thomas Gleixner 已提交
99 100 101 102 103
};

/*
 * Hardcoded buffer length limit for now, for IRQ-fed events:
 */
I
Ingo Molnar 已提交
104
#define PERF_DATA_BUFLEN		2048
T
Thomas Gleixner 已提交
105 106 107 108 109

/**
 * struct perf_data - performance counter IRQ data sampling ...
 */
struct perf_data {
I
Ingo Molnar 已提交
110 111 112 113
	int				len;
	int				rd_idx;
	int				overrun;
	u8				data[PERF_DATA_BUFLEN];
T
Thomas Gleixner 已提交
114 115 116 117 118 119 120 121 122 123 124 125 126
};

/**
 * struct perf_counter - performance counter kernel representation:
 */
struct perf_counter {
	struct list_head		list;
	int				active;
#if BITS_PER_LONG == 64
	atomic64_t			count;
#else
	atomic_t			count32[2];
#endif
I
Ingo Molnar 已提交
127
	struct perf_counter_hw_event	hw_event;
T
Thomas Gleixner 已提交
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
	struct hw_perf_counter		hw;

	struct perf_counter_context	*ctx;
	struct task_struct		*task;

	/*
	 * Protect attach/detach:
	 */
	struct mutex			mutex;

	int				oncpu;
	int				cpu;

	/* read() / irq related data */
	wait_queue_head_t		waitq;
	/* optional: for NMIs */
	int				wakeup_pending;
	struct perf_data		*irqdata;
	struct perf_data		*usrdata;
	struct perf_data		data[2];
};

/**
 * struct perf_counter_context - counter context structure
 *
 * Used as a container for task counters and CPU counters as well:
 */
struct perf_counter_context {
#ifdef CONFIG_PERF_COUNTERS
	/*
	 * Protect the list of counters:
	 */
	spinlock_t		lock;
	struct list_head	counters;
	int			nr_counters;
	int			nr_active;
	struct task_struct	*task;
#endif
};

/**
 * struct perf_counter_cpu_context - per cpu counter context structure
 */
struct perf_cpu_context {
	struct perf_counter_context	ctx;
	struct perf_counter_context	*task_ctx;
	int				active_oncpu;
	int				max_pertask;
};

/*
 * Set by architecture code:
 */
extern int perf_max_counters;

#ifdef CONFIG_PERF_COUNTERS
extern void perf_counter_task_sched_in(struct task_struct *task, int cpu);
extern void perf_counter_task_sched_out(struct task_struct *task, int cpu);
extern void perf_counter_task_tick(struct task_struct *task, int cpu);
extern void perf_counter_init_task(struct task_struct *task);
extern void perf_counter_notify(struct pt_regs *regs);
extern void perf_counter_print_debug(void);
190 191
extern void hw_perf_restore_ctrl(u64 ctrl);
extern u64 hw_perf_disable_all(void);
T
Thomas Gleixner 已提交
192 193 194 195 196 197 198 199 200 201
#else
static inline void
perf_counter_task_sched_in(struct task_struct *task, int cpu)		{ }
static inline void
perf_counter_task_sched_out(struct task_struct *task, int cpu)		{ }
static inline void
perf_counter_task_tick(struct task_struct *task, int cpu)		{ }
static inline void perf_counter_init_task(struct task_struct *task)	{ }
static inline void perf_counter_notify(struct pt_regs *regs)		{ }
static inline void perf_counter_print_debug(void)			{ }
202 203
static inline void hw_perf_restore_ctrl(u64 ctrl)			{ }
static inline u64 hw_perf_disable_all(void)		{ return 0; }
T
Thomas Gleixner 已提交
204 205 206
#endif

#endif /* _LINUX_PERF_COUNTER_H */