aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/ds.h
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2008-12-11 07:49:59 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-12 02:08:12 -0500
commitc2724775ce57c98b8af9694857b941dc61056516 (patch)
treec3936699317da3233bc31e92d68cb582ec17d193 /arch/x86/include/asm/ds.h
parentb0884e25fe361f2ca228808fb5fd1b74cb04e711 (diff)
x86, bts: provide in-kernel branch-trace interface
Impact: cleanup Move the BTS bits from ptrace.c into ds.c. Signed-off-by: Markus Metzger <markus.t.metzger@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/include/asm/ds.h')
-rw-r--r--arch/x86/include/asm/ds.h241
1 files changed, 139 insertions, 102 deletions
diff --git a/arch/x86/include/asm/ds.h b/arch/x86/include/asm/ds.h
index 99b6c39774a..ee0ea3a96c1 100644
--- a/arch/x86/include/asm/ds.h
+++ b/arch/x86/include/asm/ds.h
@@ -6,13 +6,13 @@
6 * precise-event based sampling (PEBS). 6 * precise-event based sampling (PEBS).
7 * 7 *
8 * It manages: 8 * It manages:
9 * - per-thread and per-cpu allocation of BTS and PEBS 9 * - DS and BTS hardware configuration
10 * - buffer overflow handling (to be done) 10 * - buffer overflow handling (to be done)
11 * - buffer access 11 * - buffer access
12 * 12 *
13 * It assumes: 13 * It does not do:
14 * - get_task_struct on all traced tasks 14 * - security checking (is the caller allowed to trace the task)
15 * - current is allowed to trace tasks 15 * - buffer allocation (memory accounting)
16 * 16 *
17 * 17 *
18 * Copyright (C) 2007-2008 Intel Corporation. 18 * Copyright (C) 2007-2008 Intel Corporation.
@@ -31,6 +31,7 @@
31#ifdef CONFIG_X86_DS 31#ifdef CONFIG_X86_DS
32 32
33struct task_struct; 33struct task_struct;
34struct ds_context;
34struct ds_tracer; 35struct ds_tracer;
35struct bts_tracer; 36struct bts_tracer;
36struct pebs_tracer; 37struct pebs_tracer;
@@ -38,6 +39,38 @@ struct pebs_tracer;
38typedef void (*bts_ovfl_callback_t)(struct bts_tracer *); 39typedef void (*bts_ovfl_callback_t)(struct bts_tracer *);
39typedef void (*pebs_ovfl_callback_t)(struct pebs_tracer *); 40typedef void (*pebs_ovfl_callback_t)(struct pebs_tracer *);
40 41
42
43/*
44 * A list of features plus corresponding macros to talk about them in
45 * the ds_request function's flags parameter.
46 *
47 * We use the enum to index an array of corresponding control bits;
48 * we use the macro to index a flags bit-vector.
49 */
50enum ds_feature {
51 dsf_bts = 0,
52 dsf_bts_kernel,
53#define BTS_KERNEL (1 << dsf_bts_kernel)
54 /* trace kernel-mode branches */
55
56 dsf_bts_user,
57#define BTS_USER (1 << dsf_bts_user)
58 /* trace user-mode branches */
59
60 dsf_bts_overflow,
61 dsf_bts_max,
62 dsf_pebs = dsf_bts_max,
63
64 dsf_pebs_max,
65 dsf_ctl_max = dsf_pebs_max,
66 dsf_bts_timestamps = dsf_ctl_max,
67#define BTS_TIMESTAMPS (1 << dsf_bts_timestamps)
68 /* add timestamps into BTS trace */
69
70#define BTS_USER_FLAGS (BTS_KERNEL | BTS_USER | BTS_TIMESTAMPS)
71};
72
73
41/* 74/*
42 * Request BTS or PEBS 75 * Request BTS or PEBS
43 * 76 *
@@ -58,92 +91,135 @@ typedef void (*pebs_ovfl_callback_t)(struct pebs_tracer *);
58 * NULL if cyclic buffer requested 91 * NULL if cyclic buffer requested
59 * th: the interrupt threshold in records from the end of the buffer; 92 * th: the interrupt threshold in records from the end of the buffer;
60 * -1 if no interrupt threshold is requested. 93 * -1 if no interrupt threshold is requested.
94 * flags: a bit-mask of the above flags
61 */ 95 */
62extern struct bts_tracer *ds_request_bts(struct task_struct *task, 96extern struct bts_tracer *ds_request_bts(struct task_struct *task,
63 void *base, size_t size, 97 void *base, size_t size,
64 bts_ovfl_callback_t ovfl, size_t th); 98 bts_ovfl_callback_t ovfl,
99 size_t th, unsigned int flags);
65extern struct pebs_tracer *ds_request_pebs(struct task_struct *task, 100extern struct pebs_tracer *ds_request_pebs(struct task_struct *task,
66 void *base, size_t size, 101 void *base, size_t size,
67 pebs_ovfl_callback_t ovfl, 102 pebs_ovfl_callback_t ovfl,
68 size_t th); 103 size_t th, unsigned int flags);
69 104
70/* 105/*
71 * Release BTS or PEBS resources 106 * Release BTS or PEBS resources
72 * 107 * Suspend and resume BTS or PEBS tracing
73 * Returns 0 on success; -Eerrno otherwise
74 * 108 *
75 * tracer: the tracer handle returned from ds_request_~() 109 * tracer: the tracer handle returned from ds_request_~()
76 */ 110 */
77extern int ds_release_bts(struct bts_tracer *tracer); 111extern void ds_release_bts(struct bts_tracer *tracer);
78extern int ds_release_pebs(struct pebs_tracer *tracer); 112extern void ds_suspend_bts(struct bts_tracer *tracer);
113extern void ds_resume_bts(struct bts_tracer *tracer);
114extern void ds_release_pebs(struct pebs_tracer *tracer);
115extern void ds_suspend_pebs(struct pebs_tracer *tracer);
116extern void ds_resume_pebs(struct pebs_tracer *tracer);
117
79 118
80/* 119/*
81 * Get the (array) index of the write pointer. 120 * The raw DS buffer state as it is used for BTS and PEBS recording.
82 * (assuming an array of BTS/PEBS records)
83 *
84 * Returns 0 on success; -Eerrno on error
85 * 121 *
86 * tracer: the tracer handle returned from ds_request_~() 122 * This is the low-level, arch-dependent interface for working
87 * pos (out): will hold the result 123 * directly on the raw trace data.
88 */ 124 */
89extern int ds_get_bts_index(struct bts_tracer *tracer, size_t *pos); 125struct ds_trace {
90extern int ds_get_pebs_index(struct pebs_tracer *tracer, size_t *pos); 126 /* the number of bts/pebs records */
127 size_t n;
128 /* the size of a bts/pebs record in bytes */
129 size_t size;
130 /* pointers into the raw buffer:
131 - to the first entry */
132 void *begin;
133 /* - one beyond the last entry */
134 void *end;
135 /* - one beyond the newest entry */
136 void *top;
137 /* - the interrupt threshold */
138 void *ith;
139 /* flags given on ds_request() */
140 unsigned int flags;
141};
91 142
92/* 143/*
93 * Get the (array) index one record beyond the end of the array. 144 * An arch-independent view on branch trace data.
94 * (assuming an array of BTS/PEBS records)
95 *
96 * Returns 0 on success; -Eerrno on error
97 *
98 * tracer: the tracer handle returned from ds_request_~()
99 * pos (out): will hold the result
100 */ 145 */
101extern int ds_get_bts_end(struct bts_tracer *tracer, size_t *pos); 146enum bts_qualifier {
102extern int ds_get_pebs_end(struct pebs_tracer *tracer, size_t *pos); 147 bts_invalid,
148#define BTS_INVALID bts_invalid
149
150 bts_branch,
151#define BTS_BRANCH bts_branch
152
153 bts_task_arrives,
154#define BTS_TASK_ARRIVES bts_task_arrives
155
156 bts_task_departs,
157#define BTS_TASK_DEPARTS bts_task_departs
158
159 bts_qual_bit_size = 4,
160 bts_qual_max = (1 << bts_qual_bit_size),
161};
162
163struct bts_struct {
164 __u64 qualifier;
165 union {
166 /* BTS_BRANCH */
167 struct {
168 __u64 from;
169 __u64 to;
170 } lbr;
171 /* BTS_TASK_ARRIVES or BTS_TASK_DEPARTS */
172 struct {
173 __u64 jiffies;
174 pid_t pid;
175 } timestamp;
176 } variant;
177};
178
103 179
104/* 180/*
105 * Provide a pointer to the BTS/PEBS record at parameter index. 181 * The BTS state.
106 * (assuming an array of BTS/PEBS records)
107 *
108 * The pointer points directly into the buffer. The user is
109 * responsible for copying the record.
110 *
111 * Returns the size of a single record on success; -Eerrno on error
112 * 182 *
113 * tracer: the tracer handle returned from ds_request_~() 183 * This gives access to the raw DS state and adds functions to provide
114 * index: the index of the requested record 184 * an arch-independent view of the BTS data.
115 * record (out): pointer to the requested record
116 */ 185 */
117extern int ds_access_bts(struct bts_tracer *tracer, 186struct bts_trace {
118 size_t index, const void **record); 187 struct ds_trace ds;
119extern int ds_access_pebs(struct pebs_tracer *tracer, 188
120 size_t index, const void **record); 189 int (*read)(struct bts_tracer *tracer, const void *at,
190 struct bts_struct *out);
191 int (*write)(struct bts_tracer *tracer, const struct bts_struct *in);
192};
193
121 194
122/* 195/*
123 * Write one or more BTS/PEBS records at the write pointer index and 196 * The PEBS state.
124 * advance the write pointer.
125 * 197 *
126 * If size is not a multiple of the record size, trailing bytes are 198 * This gives access to the raw DS state and the PEBS-specific counter
127 * zeroed out. 199 * reset value.
128 * 200 */
129 * May result in one or more overflow notifications. 201struct pebs_trace {
130 * 202 struct ds_trace ds;
131 * If called during overflow handling, that is, with index >= 203
132 * interrupt threshold, the write will wrap around. 204 /* the PEBS reset value */
205 unsigned long long reset_value;
206};
207
208
209/*
210 * Read the BTS or PEBS trace.
133 * 211 *
134 * An overflow notification is given if and when the interrupt 212 * Returns a view on the trace collected for the parameter tracer.
135 * threshold is reached during or after the write.
136 * 213 *
137 * Returns the number of bytes written or -Eerrno. 214 * The view remains valid as long as the traced task is not running or
215 * the tracer is suspended.
216 * Writes into the trace buffer are not reflected.
138 * 217 *
139 * tracer: the tracer handle returned from ds_request_~() 218 * tracer: the tracer handle returned from ds_request_~()
140 * buffer: the buffer to write
141 * size: the size of the buffer
142 */ 219 */
143extern int ds_write_bts(struct bts_tracer *tracer, 220extern const struct bts_trace *ds_read_bts(struct bts_tracer *tracer);
144 const void *buffer, size_t size); 221extern const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer);
145extern int ds_write_pebs(struct pebs_tracer *tracer, 222
146 const void *buffer, size_t size);
147 223
148/* 224/*
149 * Reset the write pointer of the BTS/PEBS buffer. 225 * Reset the write pointer of the BTS/PEBS buffer.
@@ -156,27 +232,6 @@ extern int ds_reset_bts(struct bts_tracer *tracer);
156extern int ds_reset_pebs(struct pebs_tracer *tracer); 232extern int ds_reset_pebs(struct pebs_tracer *tracer);
157 233
158/* 234/*
159 * Clear the BTS/PEBS buffer and reset the write pointer.
160 * The entire buffer will be zeroed out.
161 *
162 * Returns 0 on success; -Eerrno on error
163 *
164 * tracer: the tracer handle returned from ds_request_~()
165 */
166extern int ds_clear_bts(struct bts_tracer *tracer);
167extern int ds_clear_pebs(struct pebs_tracer *tracer);
168
169/*
170 * Provide the PEBS counter reset value.
171 *
172 * Returns 0 on success; -Eerrno on error
173 *
174 * tracer: the tracer handle returned from ds_request_pebs()
175 * value (out): the counter reset value
176 */
177extern int ds_get_pebs_reset(struct pebs_tracer *tracer, u64 *value);
178
179/*
180 * Set the PEBS counter reset value. 235 * Set the PEBS counter reset value.
181 * 236 *
182 * Returns 0 on success; -Eerrno on error 237 * Returns 0 on success; -Eerrno on error
@@ -192,35 +247,17 @@ extern int ds_set_pebs_reset(struct pebs_tracer *tracer, u64 value);
192struct cpuinfo_x86; 247struct cpuinfo_x86;
193extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *); 248extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
194 249
195
196
197/* 250/*
198 * The DS context - part of struct thread_struct. 251 * Context switch work
199 */ 252 */
200#define MAX_SIZEOF_DS (12 * 8) 253extern void ds_switch_to(struct task_struct *prev, struct task_struct *next);
201
202struct ds_context {
203 /* pointer to the DS configuration; goes into MSR_IA32_DS_AREA */
204 unsigned char ds[MAX_SIZEOF_DS];
205 /* the owner of the BTS and PEBS configuration, respectively */
206 struct ds_tracer *owner[2];
207 /* use count */
208 unsigned long count;
209 /* a pointer to the context location inside the thread_struct
210 * or the per_cpu context array */
211 struct ds_context **this;
212 /* a pointer to the task owning this context, or NULL, if the
213 * context is owned by a cpu */
214 struct task_struct *task;
215};
216
217/* called by exit_thread() to free leftover contexts */
218extern void ds_free(struct ds_context *context);
219 254
220#else /* CONFIG_X86_DS */ 255#else /* CONFIG_X86_DS */
221 256
222struct cpuinfo_x86; 257struct cpuinfo_x86;
223static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {} 258static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {}
259static inline void ds_switch_to(struct task_struct *prev,
260 struct task_struct *next) {}
224 261
225#endif /* CONFIG_X86_DS */ 262#endif /* CONFIG_X86_DS */
226#endif /* _ASM_X86_DS_H */ 263#endif /* _ASM_X86_DS_H */