This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

malloc probes for glibc 2.19


Resending with libc-alpha@sourceware.org instead of
libc-alpha@sources.redhat.com (the latter is no longer valid
AFAIK).

On 08/13/2013 08:29 PM, Alexandre Oliva wrote:
> Since the tree is open for changes for 2.19, I've updated the malloc
> probes patchset.  The current version of the patchset is in branch
> lxoliva/malloc-probes-bz742038.

This review, along with Siddhesh's and Will's is enough to constitute
a solid review of a new set of probes for malloc.

Please post a final version for review and I'll ACK it.

> On Sep  4, 2012, Alexandre Oliva <aoliva@redhat.com> wrote:
> 
>> > I was asked to introduce probes in malloc to aid in debugging cases in
>> > which our memory allocation code performs poorly.
>> > I've grouped the probes in separate patches, in which the probes are
>> > logically connected.
> Each probe is documented in the manual, under a note that indicates
> they're not part of libc's stable ABI.

That's good. We have no ABI requirements for these probes, though gdb
is starting to use the dynamic linker probes, but maintains a fallback
if they aren't there.

> Ok to install?
> 
> 
> 01-malloc-probes.patch
> 
> 
> Add first set of memory probes.
> 
> From: Alexandre Oliva <aoliva@redhat.com>
> 
> for ChangeLog
> 
> 	* malloc/malloc.c: Include stap-probe.h.
> 	(__libc_mallopt): Add memory_mallopt probe.
> 	* malloc/arena.c (_int_new_arena): Add memory_arena_new probe.
> 	* manual/probes.texi: New.
> 	* manual/Makefile (chapters): Add probes.
> 	* manual/threads.texi: Set next node.
> ---
>  malloc/arena.c      |    1 +
>  malloc/malloc.c     |    4 ++++
>  manual/Makefile     |    2 +-
>  manual/probes.texi  |   41 +++++++++++++++++++++++++++++++++++++++++
>  manual/threads.texi |    2 +-
>  5 files changed, 48 insertions(+), 2 deletions(-)
>  create mode 100644 manual/probes.texi
> 
> diff --git a/malloc/arena.c b/malloc/arena.c
> index 12a48ad..0822fc8 100644
> --- a/malloc/arena.c
> +++ b/malloc/arena.c
> @@ -736,6 +736,7 @@ _int_new_arena(size_t size)
>    top(a) = (mchunkptr)ptr;
>    set_head(top(a), (((char*)h + h->size) - ptr) | PREV_INUSE);
>  
> +  LIBC_PROBE (memory_arena_new, 2, a, size);

OK, new arena and size of arena.

>    tsd_setspecific(arena_key, (void *)a);
>    mutex_init(&a->mutex);
>    (void)mutex_lock(&a->mutex);
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index be472b2..d256a9b 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -1878,6 +1878,8 @@ static int perturb_byte;
>  #define free_perturb(p, n) memset (p, perturb_byte & 0xff, n)
>  
>  
> +#include <stap-probe.h>
> +
>  /* ------------------- Support for multiple arenas -------------------- */
>  #include "arena.c"
>  
> @@ -4674,6 +4676,8 @@ int __libc_mallopt(int param_number, int value)
>    /* Ensure initialization/consolidation */
>    malloc_consolidate(av);
>  
> +  LIBC_PROBE (memory_mallopt, 2, param_number, value);
> +

OK, mallopt probe with options. Very useful.

>    switch(param_number) {
>    case M_MXFAST:
>      if (value >= 0 && value <= MAX_FAST_SIZE) {
> diff --git a/manual/Makefile b/manual/Makefile
> index 44c0fd4..7bb419a 100644
> --- a/manual/Makefile
> +++ b/manual/Makefile
> @@ -42,7 +42,7 @@ chapters = $(addsuffix .texi, \
>  		       message search pattern io stdio llio filesys	\
>  		       pipe socket terminal syslog math arith time	\
>  		       resource setjmp signal startup process job nss	\
> -		       users sysinfo conf crypt debug threads)
> +		       users sysinfo conf crypt debug threads probes)

Add probes manual section. Which is excellent IMO.

>  add-chapters = $(wildcard $(foreach d, $(add-ons), ../$d/$d.texi))
>  appendices = lang.texi header.texi install.texi maint.texi platform.texi \
>  	     contrib.texi
> diff --git a/manual/probes.texi b/manual/probes.texi
> new file mode 100644
> index 0000000..500c2432
> --- /dev/null
> +++ b/manual/probes.texi
> @@ -0,0 +1,41 @@
> +@node Internal Probes
> +@c @node Internal Probes, , POSIX Threads, Top
> +@c %MENU% Probes to monitor libc internal behavior
> +@chapter Internal probes
> +
> +In order to aid in debugging and monitoring @glibcadj{} internal

s/@glibcadj{}//g

> +behavior, @theglibc{} exposes nearly-zero-overhead probes as Systemtap

s/probes as Systemtap/SystemTap probes/g

> +process marks with the @code{libc} provider.

s/process marks/marked/g

> +
> +These probes are not part of the @glibcadj{} stable ABI, and they are
> +subject to change or removal across releases.  Our only promise with
> +regard to them is that, if we find a need to remove or modify the
> +arguments of a probe, the modified probe will have a different name, so
> +that program monitors relying on the old probe will not get unexpected
> +arguments.
> +
> +@menu
> +* Memory Allocation Probes::  Probes in the memory allocation subsystem
> +@end menu
> +
> +@node Memory Allocation Probes
> +@section Memory Allocation Probes
> +
> +These probes are designed to signal relatively unusual situations within
> +the virtual memory subsystem of @theglibc{}.
> +
> +@deftp Probe memory_arena_new (void *@var{$arg1}, size_t @var{$arg2})
> +This probe is hit when @code{malloc} allocated and initialized an
> +additional allocation arena (not the main arena), but before it is
> +assigned to the running thread and inserted in the internal linked list
> +of arenas.

Suggest active present tense voice:

This probe is triggered when @code{malloc} allocates and initializes
an additional arena (not the main arena), but before the arena is
assigned to the running thread or inserted into the internal linked
list of arenas.

Note: s/hit/triggered/g, triggered is more formal and less colloquial,
and the SystemTap manual uses "triggered" in most cases (though I saw
"hit" once).

>               The arena's @code{malloc_state} internal data structure is
> +located at @var{$arg1}, within a newly-allocated heap big enough to hold
> +at least @var{$arg2} bytes.
> +@end deftp
> +
> +@deftp Probe memory_mallopt (int @var{$arg1}, int @var{$arg2})
> +This probe is hit when function @code{mallopt} is called to change

s/hit/triggered/g

> +@code{malloc} internal configuration parameters, before any change to
> +the parameters is made.  The arguments @var{$arg1} and @var{$arg2} are
> +the ones passed to the @code{mallopt} function.
> +@end deftp
> diff --git a/manual/threads.texi b/manual/threads.texi
> index a23ac26..6b7523c 100644
> --- a/manual/threads.texi
> +++ b/manual/threads.texi
> @@ -1,5 +1,5 @@
>  @node POSIX Threads
> -@c @node POSIX Threads, , Cryptographic Functions, Top
> +@c @node POSIX Threads, Intenal Probes, Cryptographic Functions, Top
>  @chapter POSIX Threads
>  @c %MENU% POSIX Threads
>  @cindex pthreads

01 patch OK with those changes.

 
> 02-mallopt-detailed-probes.patch
> 
> 
> Add probes for all changes to malloc options.
> 
> From: Alexandre Oliva <aoliva@redhat.com>
> 
> for ChangeLog
> 
> 	* malloc/malloc.c (__libc_free): Add
> 	memory_mallopt_free_dyn_thresholds probe.
> 	(__libc_mallopt): Add multiple memory_mallopt probes.
> 	* manual/probes.texi: Document them.
> ---
>  malloc/malloc.c    |   30 +++++++++++++++++---
>  manual/probes.texi |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 103 insertions(+), 5 deletions(-)
> 
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index d256a9b..4c40c2f 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -2896,6 +2896,8 @@ __libc_free(void* mem)
>        {
>  	mp_.mmap_threshold = chunksize (p);
>  	mp_.trim_threshold = 2 * mp_.mmap_threshold;
> +	LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2,
> +		    mp_.mmap_threshold, mp_.trim_threshold);

OK.

>        }
>      munmap_chunk(p);
>      return;
> @@ -4680,19 +4682,25 @@ int __libc_mallopt(int param_number, int value)
>  
>    switch(param_number) {
>    case M_MXFAST:
> -    if (value >= 0 && value <= MAX_FAST_SIZE) {
> -      set_max_fast(value);
> -    }
> +    if (value >= 0 && value <= MAX_FAST_SIZE)
> +      {
> +	LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ());
> +	set_max_fast(value);

OK.

> +      }
>      else
>        res = 0;
>      break;
>  
>    case M_TRIM_THRESHOLD:
> +    LIBC_PROBE (memory_mallopt_trim_threshold, 3, value,
> +		mp_.trim_threshold, mp_.no_dyn_threshold);

OK.

>      mp_.trim_threshold = value;
>      mp_.no_dyn_threshold = 1;
>      break;
>  
>    case M_TOP_PAD:
> +    LIBC_PROBE (memory_mallopt_top_pad, 3, value,
> +		mp_.top_pad, mp_.no_dyn_threshold);

OK.

>      mp_.top_pad = value;
>      mp_.no_dyn_threshold = 1;
>      break;
> @@ -4703,33 +4711,45 @@ int __libc_mallopt(int param_number, int value)
>        res = 0;
>      else
>        {
> +	LIBC_PROBE (memory_mallopt_mmap_threshold, 3, value,
> +		    mp_.mmap_threshold, mp_.no_dyn_threshold);

OK.

>  	mp_.mmap_threshold = value;
>  	mp_.no_dyn_threshold = 1;
>        }
>      break;
>  
>    case M_MMAP_MAX:
> +    LIBC_PROBE (memory_mallopt_mmap_max, 3, value,
> +		mp_.mmap_threshold, mp_.no_dyn_threshold);

OK.

>      mp_.n_mmaps_max = value;
>      mp_.no_dyn_threshold = 1;
>      break;
>  
>    case M_CHECK_ACTION:
> +    LIBC_PROBE (memory_mallopt_check_action, 2, value, check_action);

OK.

>      check_action = value;
>      break;
>  
>    case M_PERTURB:
> +    LIBC_PROBE (memory_mallopt_perturb, 2, value, perturb_byte);

OK.

>      perturb_byte = value;
>      break;
>  
>  #ifdef PER_THREAD
>    case M_ARENA_TEST:
>      if (value > 0)
> -      mp_.arena_test = value;
> +      {
> +	LIBC_PROBE (memory_mallopt_arena_test, 2, value, mp_.arena_test);
> +	mp_.arena_test = value;
> +      }

OK.

>      break;
>  
>    case M_ARENA_MAX:
>      if (value > 0)
> -      mp_.arena_max = value;
> +      {
> +	LIBC_PROBE (memory_mallopt_arena_max, 2, value, mp_.arena_max);
> +	mp_.arena_max = value;

OK.

> +      }
>      break;
>  #endif
>    }
> diff --git a/manual/probes.texi b/manual/probes.texi
> index 500c2432..a6fad34 100644
> --- a/manual/probes.texi
> +++ b/manual/probes.texi
> @@ -39,3 +39,81 @@ This probe is hit when function @code{mallopt} is called to change
>  the parameters is made.  The arguments @var{$arg1} and @var{$arg2} are
>  the ones passed to the @code{mallopt} function.
>  @end deftp
> +
> +@deftp Probe memory_mallopt_mxfast (int @var{$arg1}, int @var{$arg2})
> +This probe is hit shortly after the @code{mallopt} probe, when the

s/hit/triggered/g.

> +parameter to be changed is @code{M_MXFAST}, and the requested value is
> +in an acceptable range.  Argument @var{$arg1} is the requested value,
> +and @var{$arg2} is the previous value of this @code{malloc} parameter.
> +@end deftp
> +
> +@deftp Probe memory_mallopt_trim_threshold (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
> +This probe is hit shortly after the @code{mallopt} probe, when the

s/hit/triggered/g.

> +parameter to be changed is @code{M_TRIM_THRESHOLD}.  Argument
> +@var{$arg1} is the requested value, @var{$arg2} is the previous value of
> +this @code{malloc} parameter, and @var{$arg3} is nonzero if dynamic

For anyone else reading `nonzero' is the correct use e.g. unhyphenated.

> +threshold adjustments was already disabled.

s/adjustments/adjustment/g.

> +@end deftp
> +
> +@deftp Probe memory_mallopt_top_pad (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
> +This probe is hit shortly after the @code{mallopt} probe, when the

s/hit/triggered/g.

> +parameter to be changed is @code{M_TOP_PAD}.  Argument @var{$arg1} is
> +the requested value, @var{$arg2} is the previous value of this
> +@code{malloc} parameter, and @var{$arg3} is nonzero if dynamic threshold
> +adjustments was already disabled.

s/adjustments/adjustment/g.

> +@end deftp
> +
> +@deftp Probe memory_mallopt_mmap_threshold (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
> +This probe is hit shortly after the @code{mallopt} probe, when the

s/hit/triggered/g.

> +parameter to be changed is @code{M_MMAP_THRESHOLD}, and the requested
> +value is in an acceptable range.  Argument @var{$arg1} is the requested
> +value, @var{$arg2} is the previous value of this @code{malloc}
> +parameter, and @var{$arg3} is nonzero if dynamic threshold adjustments

s/adjustments/adjustment/g.

> +was already disabled.
> +@end deftp
> +
> +@deftp Probe memory_mallopt_mmap_max (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
> +This probe is hit shortly after the @code{mallopt} probe, when the

s/hit/triggered/g.

> +parameter to be changed is @code{M_MMAP_MAX}.  Argument @var{$arg1} is
> +the requested value, @var{$arg2} is the previous value of this
> +@code{malloc} parameter, and @var{$arg3} is nonzero if dynamic threshold
> +adjustments was already disabled.

s/adjustments/adjustment/g.

> +@end deftp
> +
> +@deftp Probe memory_mallopt_check_action (int @var{$arg1}, int @var{$arg2})
> +This probe is hit shortly after the @code{mallopt} probe, when the

s/hit/triggered/g.

> +parameter to be changed is @code{M_CHECK_ACTION}.  Argument @var{$arg1}
> +is the requested value, and @var{$arg2} is the previous value of this
> +@code{malloc} parameter.
> +@end deftp
> +
> +@deftp Probe memory_mallopt_perturb (int @var{$arg1}, int @var{$arg2})
> +This probe is hit shortly after the @code{mallopt} probe, when the

s/hit/triggered/g.

> +parameter to be changed is @code{M_PERTURB}.  Argument @var{$arg1} is
> +the requested value, and @var{$arg2} is the previous value of this
> +@code{malloc} parameter.
> +@end deftp
> +
> +@deftp Probe memory_mallopt_arena_test (int @var{$arg1}, int @var{$arg2})
> +This probe is hit shortly after the @code{mallopt} probe, when the

s/hit/triggered/g.

> +parameter to be changed is @code{M_ARENA_TEST}, and the requested value
> +is in an acceptable range.  Argument @var{$arg1} is the requested value,
> +and @var{$arg2} is the previous value of this @code{malloc} parameter.
> +This probe is not available if @code{malloc} is compiled without
> +per-thread arenas (@samp{-DPER_THREAD}).

Remove the double negation:

This probe is only available if @code{malloc} is compiled with per-thread
arenas (@samp{-DPER_THREAD}).

> +@end deftp
> +
> +@deftp Probe memory_mallopt_arena_max (int @var{$arg1}, int @var{$arg2})
> +This probe is hit shortly after the @code{mallopt} probe, when the

s/hit/triggered/g.

> +parameter to be changed is @code{M_ARENA_MAX}, and the requested value
> +is in an acceptable range.  Argument @var{$arg1} is the requested value,
> +and @var{$arg2} is the previous value of this @code{malloc} parameter.
> +This probe is not available if @code{malloc} is compiled without
> +per-thread arenas (@samp{-DPER_THREAD}).

Remove the double negation:

This probe is only available if @code{malloc} is compiled with per-thread
arenas (@samp{-DPER_THREAD}).


> +@end deftp
> +
> +@deftp Probe memory_mallopt_free_dyn_thresholds (int @var{$arg1}, int @var{$arg2})
> +This probe is hit when function @code{free} decides to adjust the

s/hit/triggered/g.

> +dynamic brk/mmap thresholds.  Argument @var{$arg1} and @var{$arg2} are
> +the adjusted mmap and trim thresholds, respectively.
> +@end deftp
 
02 patch OK with those changes.
 
> 03-malloc-probe-arena-changes.patch
> 
> 
> Add probes for malloc arena changes.
> 
> From: Alexandre Oliva <aoliva@redhat.com>
> 
> for ChangeLog
> 
> 	* malloc/arena.c (get_free_list): Add probe
> 	memory_arena_reuse_free_list.
> 	(reused_arena) [PER_THREAD]: Add probes memory_arena_reuse_wait
> 	and memory_arena_reuse.
> 	(arena_get2) [!PER_THREAD]: Likewise.
> 	* malloc/malloc.c (__libc_realloc) [!PER_THREAD]: Add probe
> 	memory_arena_reuse_realloc.
> 	* manual/probes.texi: Document them.
> ---
>  malloc/arena.c     |    5 ++++
>  malloc/malloc.c    |    1 +
>  manual/probes.texi |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 66 insertions(+)
> 
> diff --git a/malloc/arena.c b/malloc/arena.c
> index 0822fc8..89e8b92 100644
> --- a/malloc/arena.c
> +++ b/malloc/arena.c
> @@ -775,6 +775,7 @@ get_free_list (void)
>  
>        if (result != NULL)
>  	{
> +	  LIBC_PROBE (memory_arena_reuse_free_list, 1, result);

OK.

>  	  (void)mutex_lock(&result->mutex);
>  	  tsd_setspecific(arena_key, (void *)result);
>  	  THREAD_STAT(++(result->stat_lock_loop));
> @@ -811,9 +812,11 @@ reused_arena (mstate avoid_arena)
>      result = result->next;
>  
>    /* No arena available.  Wait for the next in line.  */
> +  LIBC_PROBE (memory_arena_reuse_wait, 3, &result->mutex, result, avoid_arena);

OK.

>    (void)mutex_lock(&result->mutex);
>  
>   out:
> +  LIBC_PROBE (memory_arena_reuse, 2, result, avoid_arena);

OK.

>    tsd_setspecific(arena_key, (void *)result);
>    THREAD_STAT(++(result->stat_lock_loop));
>    next_to_use = result->next;
> @@ -892,6 +895,7 @@ arena_get2(mstate a_tsd, size_t size, mstate avoid_arena)
>        if (retried)
>  	(void)mutex_unlock(&list_lock);
>        THREAD_STAT(++(a->stat_lock_loop));
> +      LIBC_PROBE (memory_arena_reuse, 2, a, a_tsd);

OK.

>        tsd_setspecific(arena_key, (void *)a);
>        return a;
>      }
> @@ -904,6 +908,7 @@ arena_get2(mstate a_tsd, size_t size, mstate avoid_arena)
>       locks. */
>    if(!retried && mutex_trylock(&list_lock)) {
>      /* We will block to not run in a busy loop.  */
> +    LIBC_PROBE (memory_arena_reuse_wait, 3, &list_lock, NULL, a_tsd);

OK.

>      (void)mutex_lock(&list_lock);
>  
>      /* Since we blocked there might be an arena available now.  */
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index 4c40c2f..4620008 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -2977,6 +2977,7 @@ __libc_realloc(void* oldmem, size_t bytes)
>  #endif
>  
>  #if !defined PER_THREAD
> +  LIBC_PROBE (memory_arena_reuse_realloc, 1, ar_ptr);

OK.

>    /* As in malloc(), remember this arena for the next allocation. */
>    tsd_setspecific(arena_key, (void *)ar_ptr);
>  #endif
> diff --git a/manual/probes.texi b/manual/probes.texi
> index a6fad34..cf8c1b0 100644
> --- a/manual/probes.texi
> +++ b/manual/probes.texi
> @@ -33,6 +33,66 @@ located at @var{$arg1}, within a newly-allocated heap big enough to hold
>  at least @var{$arg2} bytes.
>  @end deftp
>  
> +@deftp Probe memory_arena_reuse (void *@var{$arg1}, void *@var{$arg2})
> +This probe is hit when @code{malloc} has just selected an existing arena

s/hit/triggered/g.

> +to reuse, and (temporarily) reserved it for exclusive use.  Argument
> +@var{$arg1} is a pointer to the newly-selected arena, and @var{$arg2} is
> +a pointer to the arena previously used by that thread.
> +
> +When per-thread arenas are enabled, this occurs within
> +@code{reused_arena}, right after the mutex mentioned in probe
> +@code{memory_arena_reuse_wait} is acquired; argument @var{$arg1} will
> +point to the same arena.  In this configuration, this will usually only
> +occur once per thread.  The exception is when a thread first selected
> +the main arena, but a subsequent allocation from it fails: then, and
> +only then, may we switch to another arena to retry that allocations, and
> +for further allocations within that thread.
> +
> +When per-thread arenas are disabled, this occurs within
> +@code{arena_get2}, whenever the mutex for the previously-selected arena
> +cannot be immediately acquired.
> +@end deftp
> +
> +@deftp Probe memory_arena_reuse_wait (void *@var{$arg1}, void *@var{$arg2}, void *@var{$arg3})
> +This probe is hit when @code{malloc} is about to wait for an arena to
> +become available for reuse.  Argument @var{$arg1} holds a pointer to the
> +mutex the thread is going to wait on, @var{$arg2} is a pointer to a
> +newly-chosen arena to be reused, and @var{$arg3} is a pointer to the
> +arena previously used by that thread.
> +
> +When per-thread arenas are enabled, this occurs within
> +@code{reused_arena}, when a thread first tries to allocate memory or
> +needs a retry after a failure to allocate from the main arena, there
> +isn't any free arena, the maximum number of arenas has been reached, and
> +an existing arena was chosen for reuse, but its mutex could not be
> +immediately acquired.  The mutex in @var{$arg1} is the mutex of the
> +selected arena.
> +
> +When per-thread arenas are disabled, this occurs within
> +@code{arena_get2}, when a thread first tries to allocate memory or the
> +mutex of the arena it previously used could not be immediately acquired,
> +and none of the existing arenas could be immediately reserved for
> +exclusive use.  The mutex in @var{$arg1} is that of the list of arenas,
> +and since the arena won't have been selected yet, @var{$arg2} will be
> +@code{NULL}.
> +@end deftp
> +
> +@deftp Probe memory_arena_reuse_free_list (void *@var{$arg1})
> +This probe is hit when @code{malloc} has chosen an arena that is in the

s/hit/triggered/g.

> +free list for use by a thread, within the @code{get_free_list} function.
> +This probe is only available when @code{malloc} is configured to use
> +per-thread arenas.  The argument @var{$arg1} holds a pointer to the
> +selected arena.
> +@end deftp
> +
> +@deftp Probe memory_arena_reuse_realloc (void *@var{$arg1})
> +This probe is hit within @code{realloc}, as the arena of the current

s/hit/triggered/g.

> +thread is changed to match that in which the given address was
> +allocated.  This probe is not available when @code{malloc} is configured
> +to use per-thread arenas.  The argument @var{$arg1} holds a pointer to
> +the newly-selected arena.
> +@end deftp
> +
>  @deftp Probe memory_mallopt (int @var{$arg1}, int @var{$arg2})
>  This probe is hit when function @code{mallopt} is called to change
>  @code{malloc} internal configuration parameters, before any change to
> 

03 patch OK with those changes.

> 04-malloc-probe-retries.patch
> 
> 
> Add probes for malloc retries.
> 
> From: Alexandre Oliva <aoliva@redhat.com>
> 
> for ChangeLog
> 
> 	* malloc/malloc.c (__libc_malloc): Add memory_malloc_retry probe.
> 	(__libc_realloc): Add memory_realloc_retry probe.
> 	(__libc_memalign): Add memory_memalign_retry probe.
> 	(__libc_valloc): Add memory_valloc_retry probe.
> 	(__libc_pvalloc): Add memory_pvalloc_retry probe.
> 	(__libc_calloc): Add memory_calloc_retry probe.
> 	* manual/probes.texi: Document them.
> ---
>  malloc/malloc.c    |    6 ++++++
>  manual/probes.texi |   20 ++++++++++++++++++++
>  2 files changed, 26 insertions(+)
> 
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index 4620008..02bff7e 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -2856,6 +2856,7 @@ __libc_malloc(size_t bytes)
>      return 0;
>    victim = _int_malloc(ar_ptr, bytes);
>    if(!victim) {
> +    LIBC_PROBE (memory_malloc_retry, 1, bytes);

OK.

>      ar_ptr = arena_get_retry(ar_ptr, bytes);
>      if (__builtin_expect(ar_ptr != NULL, 1)) {
>        victim = _int_malloc(ar_ptr, bytes);
> @@ -2991,6 +2992,7 @@ __libc_realloc(void* oldmem, size_t bytes)
>    if (newp == NULL)
>      {
>        /* Try harder to allocate memory in other arenas.  */
> +      LIBC_PROBE (memory_realloc_retry, 2, bytes, oldmem);


OK.

>        newp = __libc_malloc(bytes);
>        if (newp != NULL)
>  	{
> @@ -3025,6 +3027,7 @@ __libc_memalign(size_t alignment, size_t bytes)
>      return 0;
>    p = _int_memalign(ar_ptr, alignment, bytes);
>    if(!p) {
> +    LIBC_PROBE (memory_memalign_retry, 2, bytes, alignment);

OK.

>      ar_ptr = arena_get_retry (ar_ptr, bytes);
>      if (__builtin_expect(ar_ptr != NULL, 1)) {
>        p = _int_memalign(ar_ptr, alignment, bytes);
> @@ -3061,6 +3064,7 @@ __libc_valloc(size_t bytes)
>      return 0;
>    p = _int_valloc(ar_ptr, bytes);
>    if(!p) {
> +    LIBC_PROBE (memory_valloc_retry, 1, bytes);

OK.

>      ar_ptr = arena_get_retry (ar_ptr, bytes);
>      if (__builtin_expect(ar_ptr != NULL, 1)) {
>        p = _int_memalign(ar_ptr, pagesz, bytes);
> @@ -3095,6 +3099,7 @@ __libc_pvalloc(size_t bytes)
>    arena_get(ar_ptr, bytes + 2*pagesz + MINSIZE);
>    p = _int_pvalloc(ar_ptr, bytes);
>    if(!p) {
> +    LIBC_PROBE (memory_pvalloc_retry, 1, bytes);

OK.

>      ar_ptr = arena_get_retry (ar_ptr, bytes + 2*pagesz + MINSIZE);
>      if (__builtin_expect(ar_ptr != NULL, 1)) {
>        p = _int_memalign(ar_ptr, pagesz, rounded_bytes);
> @@ -3171,6 +3176,7 @@ __libc_calloc(size_t n, size_t elem_size)
>  	 av == arena_for_chunk(mem2chunk(mem)));
>  
>    if (mem == 0) {
> +    LIBC_PROBE (memory_calloc_retry, 1, sz);

OK.

>      av = arena_get_retry (av, sz);
>      if (__builtin_expect(av != NULL, 1)) {
>        mem = _int_malloc(av, sz);
> diff --git a/manual/probes.texi b/manual/probes.texi
> index cf8c1b0..89cbabc 100644
> --- a/manual/probes.texi
> +++ b/manual/probes.texi
> @@ -24,6 +24,26 @@ arguments.
>  These probes are designed to signal relatively unusual situations within
>  the virtual memory subsystem of @theglibc{}.
>  
> +@deftp Probe memory_malloc_retry (size_t @var{$arg1})
> +@deftpx Probe memory_realloc_retry (size_t @var{$arg1}, void *@var{$arg2})
> +@deftpx Probe memory_memalign_retry (size_t @var{$arg1}, size_t @var{$arg2})
> +@deftpx Probe memory_valloc_retry (size_t @var{$arg1})
> +@deftpx Probe memory_pvalloc_retry (size_t @var{$arg1})
> +@deftpx Probe memory_calloc_retry (size_t @var{$arg1})
> +These probes are hit when the corresponding functions fail to obtain the

s/hit/triggered/g.

> +requested amount of memory from the arena in use, before it retries on

s/, before it retries on/, but before they retry with/g

> +another arena.  Argument @var{$arg1} is the amount of memory requested
> +by the user; in the @code{calloc} case, that is the total size computed
> +from both function arguments.  In the @code{realloc} case, @var{$arg2}
> +is the pointer to the memory area being resized.  In the @code{memalign}
> +case, @var{$arg2} is the alignment to be used for the request, which may
> +be stricter than the value passed to the @code{memalign} function.
> +
> +Note that the argument order does NOT match that of the corresponding
> +two-argument functions, so that in all of these probes the
> +user-requested allocation size is in @var{$arg1}.
> +@end deftp
> +
>  @deftp Probe memory_arena_new (void *@var{$arg1}, size_t @var{$arg2})
>  This probe is hit when @code{malloc} allocated and initialized an
>  additional allocation arena (not the main arena), but before it is

04 OK with those changes.

> 
> 05-malloc-probe-arena-retry.patch
> 
> 
> Add catch-all alloc retry probe.
> 
> From: Alexandre Oliva <aoliva@redhat.com>
> 
> for ChangeLog
> 
> 	* malloc/arena.c (arena_get_retry): Add memory_arena_retry probe.
> 	* manual/probes.texi: Document it.
> ---
>  malloc/arena.c     |    1 +
>  manual/probes.texi |   12 ++++++++++++
>  2 files changed, 13 insertions(+)
> 
> diff --git a/malloc/arena.c b/malloc/arena.c
> index 89e8b92..9ace186 100644
> --- a/malloc/arena.c
> +++ b/malloc/arena.c
> @@ -932,6 +932,7 @@ arena_get2(mstate a_tsd, size_t size, mstate avoid_arena)
>  static mstate
>  arena_get_retry (mstate ar_ptr, size_t bytes)
>  {
> +  LIBC_PROBE (memory_arena_retry, 2, bytes, ar_ptr);

OK.

>    if(ar_ptr != &main_arena) {
>      (void)mutex_unlock(&ar_ptr->mutex);
>      ar_ptr = &main_arena;
> diff --git a/manual/probes.texi b/manual/probes.texi
> index 89cbabc..6cf1b91 100644
> --- a/manual/probes.texi
> +++ b/manual/probes.texi
> @@ -44,6 +44,18 @@ two-argument functions, so that in all of these probes the
>  user-requested allocation size is in @var{$arg1}.
>  @end deftp
>  
> +@deftp Probe memory_arena_retry (size_t @var{$arg1}, void *@var{$arg2})
> +This probe is hit within @code{arena_get_retry}, the function used by


s/hit/triggered/g.

> +all of the corresponding functions above to select the alternate arena
> +in which to retry the allocation, before the selection takes place.

The use of "above" is tricky in a manual where other parts of the manual
might move around.

Suggest giving the functions a name e.g. "public API wrappers":

all of the public API wrappers and selects the alternate arena in which 
to retry the allocation, before the selection takes place. 

> +This probe is redundant, but much easier to use when it's not important
> +to determine which memory allocation functions are failing to allocate
> +in the first try.  Argument @var{$arg1} is the same as in the

Common preposition is `on' for `first try':

s/in the/on their/g

> +function-specific probes, except for extra room for padding introduced
> +by functions that have to ensure stricter alignment.  Argument
> +@var{$arg2} is the arena in which allocation failed.
> +@end deftp
> +
>  @deftp Probe memory_arena_new (void *@var{$arg1}, size_t @var{$arg2})
>  This probe is hit when @code{malloc} allocated and initialized an
>  additional allocation arena (not the main arena), but before it is
> 

05 is OK with those changes.

> 06-malloc-probe-heaps.patch
> 
> 
> Add malloc probes for sbrk and heap resizing.
> 
> From: Alexandre Oliva <aoliva@redhat.com>
> 
> for ChangeLog
> 
> 	* malloc/arena.c (new_heap): New memory_heap_new probe.
> 	(grow_heap): New memory_heap_more probe.
> 	(shrink_heap): New memory_heap_less probe.
> 	(heap_trim): New memory_heap_free probe.
> 	* malloc/malloc.c (sysmalloc): New memory_sbrk_more probe.
> 	(systrim): New memory_sbrk_less probe.
> 	* manual/probes.texi: Document them.
> ---
>  malloc/arena.c     |    4 ++++
>  malloc/malloc.c    |    6 +++++-
>  manual/probes.texi |   40 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 49 insertions(+), 1 deletion(-)
> 
> diff --git a/malloc/arena.c b/malloc/arena.c
> index 9ace186..d81ed0d 100644
> --- a/malloc/arena.c
> +++ b/malloc/arena.c
> @@ -581,6 +581,7 @@ new_heap(size_t size, size_t top_pad)
>    h->size = size;
>    h->mprotect_size = size;
>    THREAD_STAT(stat_n_heaps++);
> +  LIBC_PROBE (memory_heap_new, 2, h, h->size);

OK.

>    return h;
>  }
>  
> @@ -606,6 +607,7 @@ grow_heap(heap_info *h, long diff)
>    }
>  
>    h->size = new_size;
> +  LIBC_PROBE (memory_heap_more, 2, h, h->size);

OK.

>    return 0;
>  }
>  
> @@ -633,6 +635,7 @@ shrink_heap(heap_info *h, long diff)
>    /*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/
>  
>    h->size = new_size;
> +  LIBC_PROBE (memory_heap_less, 2, h, h->size);

OK.

>    return 0;
>  }
>  
> @@ -674,6 +677,7 @@ heap_trim(heap_info *heap, size_t pad)
>        break;
>      ar_ptr->system_mem -= heap->size;
>      arena_mem -= heap->size;
> +    LIBC_PROBE (memory_heap_free, 2, heap, heap->size);

OK.

>      delete_heap(heap);
>      heap = prev_heap;
>      if(!prev_inuse(p)) { /* consolidate backward */
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index 02bff7e..a1ed3b1 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -2448,8 +2448,10 @@ static void* sysmalloc(INTERNAL_SIZE_T nb, mstate av)
>      below even if we cannot call MORECORE.
>    */
>  
> -  if (size > 0)
> +  if (size > 0) {
>      brk = (char*)(MORECORE(size));
> +    LIBC_PROBE (memory_sbrk_more, 2, brk, size);

OK.

> +  }
>  
>    if (brk != (char*)(MORECORE_FAILURE)) {
>      /* Call the `morecore' hook if necessary.  */
> @@ -2747,6 +2749,8 @@ static int systrim(size_t pad, mstate av)
>  	(*hook) ();
>        new_brk = (char*)(MORECORE(0));
>  
> +      LIBC_PROBE (memory_sbrk_less, 2, new_brk, extra);

OK.

> +
>        if (new_brk != (char*)MORECORE_FAILURE) {
>  	released = (long)(current_brk - new_brk);
>  
> diff --git a/manual/probes.texi b/manual/probes.texi
> index 6cf1b91..650bea7 100644
> --- a/manual/probes.texi
> +++ b/manual/probes.texi
> @@ -24,6 +24,46 @@ arguments.
>  These probes are designed to signal relatively unusual situations within
>  the virtual memory subsystem of @theglibc{}.
>  
> +@deftp Probe memory_sbrk_more (void *@var{$arg1}, size_t @var{$arg2})
> +This probe is hit after the main arena is extended by calling

s/hit/triggered/g.

> +@code{sbrk}.  Argument @var{$arg1} is the additional size requested to
> +@code{sbrk}, and @var{$arg2} is the pointer that marks the end of the
> +@code{sbrk} area, returned in response to the request.
> +@end deftp
> +
> +@deftp Probe memory_sbrk_less (void *@var{$arg1}, size_t @var{$arg2})
> +This probe is hit after the main arena is shortened by calling

s/hit/triggered/g.

The use of "shortened" may not be entirely clear here.

Suggest:

The probe is triggered after the size of the main arena is decreased by calling

> +@code{sbrk}.  Argument @var{$arg1} is the size released by @code{sbrk}
> +(the positive value, rather than the negated number passed to

s/negated number/negative value/g.

> +@code{sbrk}), and @var{$arg2} is the pointer that marks the end of the
> +@code{sbrk} area, returned in response to the request.
> +@end deftp
> +
> +@deftp Probe memory_heap_new (void *@var{$arg1}, size_t @var{$arg2})
> +This probe is hit after a new heap is @code{mmap}ed.  Argument

s/hit/triggered/g.

> +@var{$arg1} is a pointer to the base of the memory area, where the
> +@code{heap_info} data structure is held, and @var{$arg2} is the size of
> +the heap.
> +@end deftp
> +
> +@deftp Probe memory_heap_free (void *@var{$arg1}, size_t @var{$arg2})
> +This probe is hit before (unlike the other sbrk and heap probes) a heap

s/hit/triggered/g.

> +is completely un@code{mmap}ped.  Argument @var{$arg1} is a pointer to

s/un@code{mmap}ped/removed via @code{munmap}./g.

> +the heap, and @var{$arg2} is the size of the heap.
> +@end deftp
> +
> +@deftp Probe memory_heap_less (void *@var{$arg1}, size_t @var{$arg2})
> +This probe is hit after a trailing portion of an @code{mmap}ed heap is

s/hit/triggered/g.

> +released.  Argument @var{$arg1} is a pointer to the heap, and
> +@var{$arg2} is the new size of the heap.
> +@end deftp
> +
> +@deftp Probe memory_heap_more (void *@var{$arg1}, size_t @var{$arg2})
> +This probe is hit after a trailing portion of an @code{mmap}ed heap is

s/hit/triggered/g.

> +extended.  Argument @var{$arg1} is a pointer to the heap, and
> +@var{$arg2} is the new size of the heap.
> +@end deftp
> +
>  @deftp Probe memory_malloc_retry (size_t @var{$arg1})
>  @deftpx Probe memory_realloc_retry (size_t @var{$arg1}, void *@var{$arg2})
>  @deftpx Probe memory_memalign_retry (size_t @var{$arg1}, size_t @var{$arg2})
> 

06 is OK with those changes.

Cheers,
Carlos.





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]