diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2008-01-30 07:31:20 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:31:20 -0500 |
commit | a95d67f87e1a5f1b4429be3ba3bf7b4051657908 (patch) | |
tree | 4a67994b901c5dfbf3c2ee752efd53dbce938c36 /arch/x86/kernel/ds.c | |
parent | e4811f2568c55e595a7bf15a3b9aba863b31fb94 (diff) |
x86, ptrace: new ptrace BTS API
Here's the new ptrace BTS API that supports two different overflow handling mechanisms (wrap-around and buffer-full-signal) to support two different use cases (debugging and profiling).
It further combines buffer allocation and configuration.
Opens:
- memory rlimit
- overflow signal
What would be the right signal to use?
Signed-off-by: Markus Metzger <markus.t.metzger@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/ds.c')
-rw-r--r-- | arch/x86/kernel/ds.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c index e7855def97c3..6eb5d49a36bb 100644 --- a/arch/x86/kernel/ds.c +++ b/arch/x86/kernel/ds.c | |||
@@ -177,18 +177,20 @@ static inline void set_info_data(char *base, unsigned long value) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | 179 | ||
180 | int ds_allocate(void **dsp, size_t bts_size_in_records) | 180 | int ds_allocate(void **dsp, size_t bts_size_in_bytes) |
181 | { | 181 | { |
182 | size_t bts_size_in_bytes = 0; | 182 | size_t bts_size_in_records; |
183 | void *bts = 0; | 183 | void *bts; |
184 | void *ds = 0; | 184 | void *ds; |
185 | 185 | ||
186 | if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) | 186 | if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) |
187 | return -EOPNOTSUPP; | 187 | return -EOPNOTSUPP; |
188 | 188 | ||
189 | if (bts_size_in_records < 0) | 189 | if (bts_size_in_bytes < 0) |
190 | return -EINVAL; | 190 | return -EINVAL; |
191 | 191 | ||
192 | bts_size_in_records = | ||
193 | bts_size_in_bytes / ds_cfg.sizeof_bts; | ||
192 | bts_size_in_bytes = | 194 | bts_size_in_bytes = |
193 | bts_size_in_records * ds_cfg.sizeof_bts; | 195 | bts_size_in_records * ds_cfg.sizeof_bts; |
194 | 196 | ||
@@ -233,9 +235,21 @@ int ds_get_bts_size(void *ds) | |||
233 | if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) | 235 | if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) |
234 | return -EOPNOTSUPP; | 236 | return -EOPNOTSUPP; |
235 | 237 | ||
238 | if (!ds) | ||
239 | return 0; | ||
240 | |||
236 | size_in_bytes = | 241 | size_in_bytes = |
237 | get_bts_absolute_maximum(ds) - | 242 | get_bts_absolute_maximum(ds) - |
238 | get_bts_buffer_base(ds); | 243 | get_bts_buffer_base(ds); |
244 | return size_in_bytes; | ||
245 | } | ||
246 | |||
247 | int ds_get_bts_end(void *ds) | ||
248 | { | ||
249 | size_t size_in_bytes = ds_get_bts_size(ds); | ||
250 | |||
251 | if (size_in_bytes <= 0) | ||
252 | return size_in_bytes; | ||
239 | 253 | ||
240 | return size_in_bytes / ds_cfg.sizeof_bts; | 254 | return size_in_bytes / ds_cfg.sizeof_bts; |
241 | } | 255 | } |
@@ -254,6 +268,38 @@ int ds_get_bts_index(void *ds) | |||
254 | return index_offset_in_bytes / ds_cfg.sizeof_bts; | 268 | return index_offset_in_bytes / ds_cfg.sizeof_bts; |
255 | } | 269 | } |
256 | 270 | ||
271 | int ds_set_overflow(void *ds, int method) | ||
272 | { | ||
273 | switch (method) { | ||
274 | case DS_O_SIGNAL: | ||
275 | return -EOPNOTSUPP; | ||
276 | case DS_O_WRAP: | ||
277 | return 0; | ||
278 | default: | ||
279 | return -EINVAL; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | int ds_get_overflow(void *ds) | ||
284 | { | ||
285 | return DS_O_WRAP; | ||
286 | } | ||
287 | |||
288 | int ds_clear(void *ds) | ||
289 | { | ||
290 | int bts_size = ds_get_bts_size(ds); | ||
291 | void *bts_base; | ||
292 | |||
293 | if (bts_size <= 0) | ||
294 | return bts_size; | ||
295 | |||
296 | bts_base = get_bts_buffer_base(ds); | ||
297 | memset(bts_base, 0, bts_size); | ||
298 | |||
299 | set_bts_index(ds, bts_base); | ||
300 | return 0; | ||
301 | } | ||
302 | |||
257 | int ds_read_bts(void *ds, size_t index, struct bts_struct *out) | 303 | int ds_read_bts(void *ds, size_t index, struct bts_struct *out) |
258 | { | 304 | { |
259 | void *bts; | 305 | void *bts; |