diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2008-01-30 13:31:20 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 13:31:20 +0100 |
commit | a95d67f87e1a5f1b4429be3ba3bf7b4051657908 (patch) | |
tree | 4a67994b901c5dfbf3c2ee752efd53dbce938c36 /arch/x86/kernel/ds.c | |
parent | e4811f2568c55e595a7bf15a3b9aba863b31fb94 (diff) | |
download | linux-a95d67f87e1a5f1b4429be3ba3bf7b4051657908.tar.bz2 |
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) } -int ds_allocate(void **dsp, size_t bts_size_in_records) +int ds_allocate(void **dsp, size_t bts_size_in_bytes) { - size_t bts_size_in_bytes = 0; - void *bts = 0; - void *ds = 0; + size_t bts_size_in_records; + void *bts; + void *ds; if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) return -EOPNOTSUPP; - if (bts_size_in_records < 0) + if (bts_size_in_bytes < 0) return -EINVAL; + bts_size_in_records = + bts_size_in_bytes / ds_cfg.sizeof_bts; bts_size_in_bytes = bts_size_in_records * ds_cfg.sizeof_bts; @@ -233,9 +235,21 @@ int ds_get_bts_size(void *ds) if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) return -EOPNOTSUPP; + if (!ds) + return 0; + size_in_bytes = get_bts_absolute_maximum(ds) - get_bts_buffer_base(ds); + return size_in_bytes; +} + +int ds_get_bts_end(void *ds) +{ + size_t size_in_bytes = ds_get_bts_size(ds); + + if (size_in_bytes <= 0) + return size_in_bytes; return size_in_bytes / ds_cfg.sizeof_bts; } @@ -254,6 +268,38 @@ int ds_get_bts_index(void *ds) return index_offset_in_bytes / ds_cfg.sizeof_bts; } +int ds_set_overflow(void *ds, int method) +{ + switch (method) { + case DS_O_SIGNAL: + return -EOPNOTSUPP; + case DS_O_WRAP: + return 0; + default: + return -EINVAL; + } +} + +int ds_get_overflow(void *ds) +{ + return DS_O_WRAP; +} + +int ds_clear(void *ds) +{ + int bts_size = ds_get_bts_size(ds); + void *bts_base; + + if (bts_size <= 0) + return bts_size; + + bts_base = get_bts_buffer_base(ds); + memset(bts_base, 0, bts_size); + + set_bts_index(ds, bts_base); + return 0; +} + int ds_read_bts(void *ds, size_t index, struct bts_struct *out) { void *bts; |