aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2008-11-25 03:01:25 -0500
committerIngo Molnar <mingo@elte.hu>2008-11-25 11:31:11 -0500
commitca0002a179bfa532d009a9272d619732872c49bd (patch)
tree9a9ca02164dfb2c13afaa38ab67f3f15d8dd5ce8 /arch/x86/include
parent7d55718b0c19ba611241c330f688ee824e9bab79 (diff)
x86, bts: base in-kernel ds interface on handles
Impact: generalize the DS code to shared buffers Change the in-kernel ds.h interface to identify the tracer via a handle returned on ds_request_~(). Tracers used to be identified via their task_struct. The changes are required to allow DS to be shared between different tasks, which is needed for perfmon2 and for ftrace. For ptrace, the handle is stored in the traced task's task_struct. This should probably go into a (arch-specific) ptrace context some time. Signed-off-by: Markus Metzger <markus.t.metzger@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/include')
-rw-r--r--arch/x86/include/asm/ds.h124
1 files changed, 57 insertions, 67 deletions
diff --git a/arch/x86/include/asm/ds.h b/arch/x86/include/asm/ds.h
index a95008457ea..0af997de5f0 100644
--- a/arch/x86/include/asm/ds.h
+++ b/arch/x86/include/asm/ds.h
@@ -26,11 +26,18 @@
26 26
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/err.h>
29 30
30 31
31#ifdef CONFIG_X86_DS 32#ifdef CONFIG_X86_DS
32 33
33struct task_struct; 34struct task_struct;
35struct ds_tracer;
36struct bts_tracer;
37struct pebs_tracer;
38
39typedef void (*bts_ovfl_callback_t)(struct bts_tracer *);
40typedef void (*pebs_ovfl_callback_t)(struct pebs_tracer *);
34 41
35/* 42/*
36 * Request BTS or PEBS 43 * Request BTS or PEBS
@@ -38,21 +45,29 @@ struct task_struct;
38 * Due to alignement constraints, the actual buffer may be slightly 45 * Due to alignement constraints, the actual buffer may be slightly
39 * smaller than the requested or provided buffer. 46 * smaller than the requested or provided buffer.
40 * 47 *
41 * Returns 0 on success; -Eerrno otherwise 48 * Returns a pointer to a tracer structure on success, or
49 * ERR_PTR(errcode) on failure.
50 *
51 * The interrupt threshold is independent from the overflow callback
52 * to allow users to use their own overflow interrupt handling mechanism.
42 * 53 *
43 * task: the task to request recording for; 54 * task: the task to request recording for;
44 * NULL for per-cpu recording on the current cpu 55 * NULL for per-cpu recording on the current cpu
45 * base: the base pointer for the (non-pageable) buffer; 56 * base: the base pointer for the (non-pageable) buffer;
46 * NULL if buffer allocation requested 57 * NULL if buffer allocation requested
47 * size: the size of the requested or provided buffer 58 * size: the size of the requested or provided buffer in bytes
48 * ovfl: pointer to a function to be called on buffer overflow; 59 * ovfl: pointer to a function to be called on buffer overflow;
49 * NULL if cyclic buffer requested 60 * NULL if cyclic buffer requested
61 * th: the interrupt threshold in records from the end of the buffer;
62 * -1 if no interrupt threshold is requested.
50 */ 63 */
51typedef void (*ds_ovfl_callback_t)(struct task_struct *); 64extern struct bts_tracer *ds_request_bts(struct task_struct *task,
52extern int ds_request_bts(struct task_struct *task, void *base, size_t size, 65 void *base, size_t size,
53 ds_ovfl_callback_t ovfl); 66 bts_ovfl_callback_t ovfl, size_t th);
54extern int ds_request_pebs(struct task_struct *task, void *base, size_t size, 67extern struct pebs_tracer *ds_request_pebs(struct task_struct *task,
55 ds_ovfl_callback_t ovfl); 68 void *base, size_t size,
69 pebs_ovfl_callback_t ovfl,
70 size_t th);
56 71
57/* 72/*
58 * Release BTS or PEBS resources 73 * Release BTS or PEBS resources
@@ -61,37 +76,34 @@ extern int ds_request_pebs(struct task_struct *task, void *base, size_t size,
61 * 76 *
62 * Returns 0 on success; -Eerrno otherwise 77 * Returns 0 on success; -Eerrno otherwise
63 * 78 *
64 * task: the task to release resources for; 79 * tracer: the tracer handle returned from ds_request_~()
65 * NULL to release resources for the current cpu
66 */ 80 */
67extern int ds_release_bts(struct task_struct *task); 81extern int ds_release_bts(struct bts_tracer *tracer);
68extern int ds_release_pebs(struct task_struct *task); 82extern int ds_release_pebs(struct pebs_tracer *tracer);
69 83
70/* 84/*
71 * Return the (array) index of the write pointer. 85 * Get the (array) index of the write pointer.
72 * (assuming an array of BTS/PEBS records) 86 * (assuming an array of BTS/PEBS records)
73 * 87 *
74 * Returns -Eerrno on error 88 * Returns 0 on success; -Eerrno on error
75 * 89 *
76 * task: the task to access; 90 * tracer: the tracer handle returned from ds_request_~()
77 * NULL to access the current cpu 91 * pos (out): will hold the result
78 * pos (out): if not NULL, will hold the result
79 */ 92 */
80extern int ds_get_bts_index(struct task_struct *task, size_t *pos); 93extern int ds_get_bts_index(struct bts_tracer *tracer, size_t *pos);
81extern int ds_get_pebs_index(struct task_struct *task, size_t *pos); 94extern int ds_get_pebs_index(struct pebs_tracer *tracer, size_t *pos);
82 95
83/* 96/*
84 * Return the (array) index one record beyond the end of the array. 97 * Get the (array) index one record beyond the end of the array.
85 * (assuming an array of BTS/PEBS records) 98 * (assuming an array of BTS/PEBS records)
86 * 99 *
87 * Returns -Eerrno on error 100 * Returns 0 on success; -Eerrno on error
88 * 101 *
89 * task: the task to access; 102 * tracer: the tracer handle returned from ds_request_~()
90 * NULL to access the current cpu 103 * pos (out): will hold the result
91 * pos (out): if not NULL, will hold the result
92 */ 104 */
93extern int ds_get_bts_end(struct task_struct *task, size_t *pos); 105extern int ds_get_bts_end(struct bts_tracer *tracer, size_t *pos);
94extern int ds_get_pebs_end(struct task_struct *task, size_t *pos); 106extern int ds_get_pebs_end(struct pebs_tracer *tracer, size_t *pos);
95 107
96/* 108/*
97 * Provide a pointer to the BTS/PEBS record at parameter index. 109 * Provide a pointer to the BTS/PEBS record at parameter index.
@@ -102,14 +114,13 @@ extern int ds_get_pebs_end(struct task_struct *task, size_t *pos);
102 * 114 *
103 * Returns the size of a single record on success; -Eerrno on error 115 * Returns the size of a single record on success; -Eerrno on error
104 * 116 *
105 * task: the task to access; 117 * tracer: the tracer handle returned from ds_request_~()
106 * NULL to access the current cpu
107 * index: the index of the requested record 118 * index: the index of the requested record
108 * record (out): pointer to the requested record 119 * record (out): pointer to the requested record
109 */ 120 */
110extern int ds_access_bts(struct task_struct *task, 121extern int ds_access_bts(struct bts_tracer *tracer,
111 size_t index, const void **record); 122 size_t index, const void **record);
112extern int ds_access_pebs(struct task_struct *task, 123extern int ds_access_pebs(struct pebs_tracer *tracer,
113 size_t index, const void **record); 124 size_t index, const void **record);
114 125
115/* 126/*
@@ -129,38 +140,24 @@ extern int ds_access_pebs(struct task_struct *task,
129 * 140 *
130 * Returns the number of bytes written or -Eerrno. 141 * Returns the number of bytes written or -Eerrno.
131 * 142 *
132 * task: the task to access; 143 * tracer: the tracer handle returned from ds_request_~()
133 * NULL to access the current cpu
134 * buffer: the buffer to write 144 * buffer: the buffer to write
135 * size: the size of the buffer 145 * size: the size of the buffer
136 */ 146 */
137extern int ds_write_bts(struct task_struct *task, 147extern int ds_write_bts(struct bts_tracer *tracer,
138 const void *buffer, size_t size); 148 const void *buffer, size_t size);
139extern int ds_write_pebs(struct task_struct *task, 149extern int ds_write_pebs(struct pebs_tracer *tracer,
140 const void *buffer, size_t size); 150 const void *buffer, size_t size);
141 151
142/* 152/*
143 * Same as ds_write_bts/pebs, but omit ownership checks.
144 *
145 * This is needed to have some other task than the owner of the
146 * BTS/PEBS buffer or the parameter task itself write into the
147 * respective buffer.
148 */
149extern int ds_unchecked_write_bts(struct task_struct *task,
150 const void *buffer, size_t size);
151extern int ds_unchecked_write_pebs(struct task_struct *task,
152 const void *buffer, size_t size);
153
154/*
155 * Reset the write pointer of the BTS/PEBS buffer. 153 * Reset the write pointer of the BTS/PEBS buffer.
156 * 154 *
157 * Returns 0 on success; -Eerrno on error 155 * Returns 0 on success; -Eerrno on error
158 * 156 *
159 * task: the task to access; 157 * tracer: the tracer handle returned from ds_request_~()
160 * NULL to access the current cpu
161 */ 158 */
162extern int ds_reset_bts(struct task_struct *task); 159extern int ds_reset_bts(struct bts_tracer *tracer);
163extern int ds_reset_pebs(struct task_struct *task); 160extern int ds_reset_pebs(struct pebs_tracer *tracer);
164 161
165/* 162/*
166 * Clear the BTS/PEBS buffer and reset the write pointer. 163 * Clear the BTS/PEBS buffer and reset the write pointer.
@@ -168,33 +165,30 @@ extern int ds_reset_pebs(struct task_struct *task);
168 * 165 *
169 * Returns 0 on success; -Eerrno on error 166 * Returns 0 on success; -Eerrno on error
170 * 167 *
171 * task: the task to access; 168 * tracer: the tracer handle returned from ds_request_~()
172 * NULL to access the current cpu
173 */ 169 */
174extern int ds_clear_bts(struct task_struct *task); 170extern int ds_clear_bts(struct bts_tracer *tracer);
175extern int ds_clear_pebs(struct task_struct *task); 171extern int ds_clear_pebs(struct pebs_tracer *tracer);
176 172
177/* 173/*
178 * Provide the PEBS counter reset value. 174 * Provide the PEBS counter reset value.
179 * 175 *
180 * Returns 0 on success; -Eerrno on error 176 * Returns 0 on success; -Eerrno on error
181 * 177 *
182 * task: the task to access; 178 * tracer: the tracer handle returned from ds_request_pebs()
183 * NULL to access the current cpu
184 * value (out): the counter reset value 179 * value (out): the counter reset value
185 */ 180 */
186extern int ds_get_pebs_reset(struct task_struct *task, u64 *value); 181extern int ds_get_pebs_reset(struct pebs_tracer *tracer, u64 *value);
187 182
188/* 183/*
189 * Set the PEBS counter reset value. 184 * Set the PEBS counter reset value.
190 * 185 *
191 * Returns 0 on success; -Eerrno on error 186 * Returns 0 on success; -Eerrno on error
192 * 187 *
193 * task: the task to access; 188 * tracer: the tracer handle returned from ds_request_pebs()
194 * NULL to access the current cpu
195 * value: the new counter reset value 189 * value: the new counter reset value
196 */ 190 */
197extern int ds_set_pebs_reset(struct task_struct *task, u64 value); 191extern int ds_set_pebs_reset(struct pebs_tracer *tracer, u64 value);
198 192
199/* 193/*
200 * Initialization 194 * Initialization
@@ -207,17 +201,13 @@ extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
207/* 201/*
208 * The DS context - part of struct thread_struct. 202 * The DS context - part of struct thread_struct.
209 */ 203 */
204#define MAX_SIZEOF_DS (12 * 8)
205
210struct ds_context { 206struct ds_context {
211 /* pointer to the DS configuration; goes into MSR_IA32_DS_AREA */ 207 /* pointer to the DS configuration; goes into MSR_IA32_DS_AREA */
212 unsigned char *ds; 208 unsigned char ds[MAX_SIZEOF_DS];
213 /* the owner of the BTS and PEBS configuration, respectively */ 209 /* the owner of the BTS and PEBS configuration, respectively */
214 struct task_struct *owner[2]; 210 struct ds_tracer *owner[2];
215 /* buffer overflow notification function for BTS and PEBS */
216 ds_ovfl_callback_t callback[2];
217 /* the original buffer address */
218 void *buffer[2];
219 /* the number of allocated pages for on-request allocated buffers */
220 unsigned int pages[2];
221 /* use count */ 211 /* use count */
222 unsigned long count; 212 unsigned long count;
223 /* a pointer to the context location inside the thread_struct 213 /* a pointer to the context location inside the thread_struct