Re: [patch 4/5] x86, ptrace: new ptrace BTS API
* Markus Metzger <[EMAIL PROTECTED]> wrote: > 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? i think we tend to have such signal targets configurable (like in the POSIX timers APIs) - or we could use SIGIO. I've Cc:-ed Ulrich - maybe he has some specific ideas how to structure this. Ingo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[patch 4/5] 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 <[EMAIL PROTECTED]> --- Index: linux-2.6-x86/arch/x86/kernel/ds.c === --- linux-2.6-x86.orig/arch/x86/kernel/ds.c 2007-12-14 15:31:48.%N +0100 +++ linux-2.6-x86/arch/x86/kernel/ds.c 2007-12-14 15:31:48.%N +0100 @@ -177,18 +177,20 @@ } -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 @@ 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 @@ 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; Index: linux-2.6-x86/arch/x86/kernel/ptrace.c === --- linux-2.6-x86.orig/arch/x86/kernel/ptrace.c 2007-12-14 15:31:48.%N +0100 +++ linux-2.6-x86/arch/x86/kernel/ptrace.c 2007-12-14 17:32:40.%N +0100 @@ -33,12 +33,6 @@ /* - * The maximal size of a BTS buffer per traced task in number of BTS - * records. - */ -#define PTRACE_BTS_BUFFER_MAX 4000 - -/* * does not yet catch signals sent when the child dies. * in exit.c or in signal.c. */ @@ -466,17 +460,12 @@ return 0; } -static int ptrace_bts_max_buffer_size(void) -{ - return PTRACE_BTS_BUFFER_MAX; -} - -static int ptrace_bts_get_buffer_size(struct task_struct *child) +static int ptrace_bts_get_size(struct task_struct *child) { if (!child->thread.ds_area_msr) return -ENXIO; - return ds_get_bts_size((void *)child->thread.ds_area_msr); + return ds_get_bts_index((void *)child->thread.ds_area_msr); } static int ptrace_bts_read_record(struct task_struct *child, @@ -485,7 +474,7 @@ { struct bts_struct ret; int retval; - int bts_size; + int bts_end; int bts_index; if (!child->thread.ds_area_msr) @@ -494,15 +483,15 @@ if (index < 0) return -EINVAL; - bts_size = ds_get_bts_size((void *)child->thread.ds_area_msr); - if (bts_size <= index) + bts_end = ds_get_bts_end((void *)child->thread.ds_area_msr); + if (bts_end <= index) return -EINVAL; /* translate the ptrace bts index into the ds bts index */ bts_index = ds_get_bts_index((void *)child->thread.ds_area_msr); bts_index -= (index + 1); if (bts_index < 0) - bts_index += bts_size; + bts_index += bts_end; retval = ds_read_bts((void *)child->thread.ds_area_msr, bts_index, ); @@ -530,19 +519,97 @@ return sizeof(*in); } -static int ptrace_bts_config(struct task_struct *child, -unsigned long options) +static int ptrace_bts_clear(struct task_struct *child) { - unsigned long debugctl_mask = ds_debugctl_mask(); - int retval; + if (!child->thread.ds_area_msr) + return -ENXIO; - retval = ptrace_bts_get_buffer_size(child); - if
[patch 4/5] 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 [EMAIL PROTECTED] --- Index: linux-2.6-x86/arch/x86/kernel/ds.c === --- linux-2.6-x86.orig/arch/x86/kernel/ds.c 2007-12-14 15:31:48.%N +0100 +++ linux-2.6-x86/arch/x86/kernel/ds.c 2007-12-14 15:31:48.%N +0100 @@ -177,18 +177,20 @@ } -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 @@ 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 @@ 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; Index: linux-2.6-x86/arch/x86/kernel/ptrace.c === --- linux-2.6-x86.orig/arch/x86/kernel/ptrace.c 2007-12-14 15:31:48.%N +0100 +++ linux-2.6-x86/arch/x86/kernel/ptrace.c 2007-12-14 17:32:40.%N +0100 @@ -33,12 +33,6 @@ /* - * The maximal size of a BTS buffer per traced task in number of BTS - * records. - */ -#define PTRACE_BTS_BUFFER_MAX 4000 - -/* * does not yet catch signals sent when the child dies. * in exit.c or in signal.c. */ @@ -466,17 +460,12 @@ return 0; } -static int ptrace_bts_max_buffer_size(void) -{ - return PTRACE_BTS_BUFFER_MAX; -} - -static int ptrace_bts_get_buffer_size(struct task_struct *child) +static int ptrace_bts_get_size(struct task_struct *child) { if (!child-thread.ds_area_msr) return -ENXIO; - return ds_get_bts_size((void *)child-thread.ds_area_msr); + return ds_get_bts_index((void *)child-thread.ds_area_msr); } static int ptrace_bts_read_record(struct task_struct *child, @@ -485,7 +474,7 @@ { struct bts_struct ret; int retval; - int bts_size; + int bts_end; int bts_index; if (!child-thread.ds_area_msr) @@ -494,15 +483,15 @@ if (index 0) return -EINVAL; - bts_size = ds_get_bts_size((void *)child-thread.ds_area_msr); - if (bts_size = index) + bts_end = ds_get_bts_end((void *)child-thread.ds_area_msr); + if (bts_end = index) return -EINVAL; /* translate the ptrace bts index into the ds bts index */ bts_index = ds_get_bts_index((void *)child-thread.ds_area_msr); bts_index -= (index + 1); if (bts_index 0) - bts_index += bts_size; + bts_index += bts_end; retval = ds_read_bts((void *)child-thread.ds_area_msr, bts_index, ret); @@ -530,19 +519,97 @@ return sizeof(*in); } -static int ptrace_bts_config(struct task_struct *child, -unsigned long options) +static int ptrace_bts_clear(struct task_struct *child) { - unsigned long debugctl_mask = ds_debugctl_mask(); - int retval; + if (!child-thread.ds_area_msr) + return -ENXIO; - retval = ptrace_bts_get_buffer_size(child); - if (retval 0) -
Re: [patch 4/5] x86, ptrace: new ptrace BTS API
* Markus Metzger [EMAIL PROTECTED] wrote: 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? i think we tend to have such signal targets configurable (like in the POSIX timers APIs) - or we could use SIGIO. I've Cc:-ed Ulrich - maybe he has some specific ideas how to structure this. Ingo -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/