diff mbox series

[v5,6/7] malloc: Move MORECORE fallback mmap to sysmalloc_mmap_fallback

Message ID 20211214185806.4109231-7-adhemerval.zanella@linaro.org
State New
Headers show
Series malloc: Improve Huge Page support | expand

Commit Message

Adhemerval Zanella Dec. 14, 2021, 6:58 p.m. UTC
So it can be used on hugepage code as well.
---
 malloc/malloc.c | 85 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 53 insertions(+), 32 deletions(-)

Comments

DJ Delorie Dec. 15, 2021, 4:55 a.m. UTC | #1
LGTM
Reviewed-by: DJ Delorie <dj@redhat.com>

Adhemerval Zanella via Libc-alpha <libc-alpha@sourceware.org> writes:
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> +/*
> +   Allocate memory using mmap() based on S and NB requested size, aligning to
> +   PAGESIZE if required.  The EXTRA_FLAGS is used on mmap() call.  If the call
> +   succeedes S is updated with the allocated size.  This is used as a fallback
> +   if MORECORE fails.
> + */
> +static void *
> +sysmalloc_mmap_fallback (long int *s, INTERNAL_SIZE_T nb,
> +			 INTERNAL_SIZE_T old_size, size_t minsize,
> +			 size_t pagesize, int extra_flags, mstate av)
> +{
> +  long int size = *s;
> +
> +  /* Cannot merge with old top, so add its size back in */
> +  if (contiguous (av))
> +    size = ALIGN_UP (size + old_size, pagesize);
> +
> +  /* If we are relying on mmap as backup, then use larger units */
> +  if ((unsigned long) (size) < minsize)
> +    size = minsize;
> +
> +  /* Don't try if size wraps around 0 */
> +  if ((unsigned long) (size) <= (unsigned long) (nb))
> +    return MORECORE_FAILURE;
> +
> +  char *mbrk = (char *) (MMAP (0, size,
> +			       mtag_mmap_flags | PROT_READ | PROT_WRITE,
> +			       extra_flags));
> +  if (mbrk == MAP_FAILED)
> +    return MAP_FAILED;
> +
> +#ifdef MAP_HUGETLB
> +  if (!(extra_flags & MAP_HUGETLB))
> +    madvise_thp (mbrk, size);
> +#endif
> +
> +  /* Record that we no longer have a contiguous sbrk region.  After the first
> +     time mmap is used as backup, we do not ever rely on contiguous space
> +     since this could incorrectly bridge regions.  */
> +  set_noncontiguous (av);
> +
> +  *s = size;
> +  return mbrk;
> +}
> +
>  static void *
>  sysmalloc (INTERNAL_SIZE_T nb, mstate av)
>  {
> @@ -2695,38 +2740,14 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av)
>               segregated mmap region.
>             */
>  
> -          /* Cannot merge with old top, so add its size back in */
> -          if (contiguous (av))
> -            size = ALIGN_UP (size + old_size, pagesize);
> -
> -          /* If we are relying on mmap as backup, then use larger units */
> -          if ((unsigned long) (size) < (unsigned long) (MMAP_AS_MORECORE_SIZE))
> -            size = MMAP_AS_MORECORE_SIZE;
> -
> -          /* Don't try if size wraps around 0 */
> -          if ((unsigned long) (size) > (unsigned long) (nb))
> -            {
> -              char *mbrk = (char *) (MMAP (0, size,
> -					   mtag_mmap_flags | PROT_READ | PROT_WRITE,
> -					   0));
> -
> -              if (mbrk != MAP_FAILED)
> -                {
> -		  madvise_thp (mbrk, size);
> -
> -                  /* We do not need, and cannot use, another sbrk call to find end */
> -                  brk = mbrk;
> -                  snd_brk = brk + size;
> -
> -                  /*
> -                     Record that we no longer have a contiguous sbrk region.
> -                     After the first time mmap is used as backup, we do not
> -                     ever rely on contiguous space since this could incorrectly
> -                     bridge regions.
> -                   */
> -                  set_noncontiguous (av);
> -                }
> -            }
> +	  char *mbrk = sysmalloc_mmap_fallback (&size, nb, old_size, pagesize,
> +						MMAP_AS_MORECORE_SIZE, 0, av);
> +	  if (mbrk != MAP_FAILED)
> +	    {
> +	      /* We do not need, and cannot use, another sbrk call to find end */
> +	      brk = mbrk;
> +	      snd_brk = brk + size;
> +	    }
>          }
>  
>        if (brk != (char *) (MORECORE_FAILURE))
diff mbox series

Patch

diff --git a/malloc/malloc.c b/malloc/malloc.c
index 37fbd7e51d..9118306923 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2498,6 +2498,51 @@  sysmalloc_mmap (INTERNAL_SIZE_T nb, size_t pagesize, int extra_flags, mstate av)
   return chunk2mem (p);
 }
 
+/*
+   Allocate memory using mmap() based on S and NB requested size, aligning to
+   PAGESIZE if required.  The EXTRA_FLAGS is used on mmap() call.  If the call
+   succeedes S is updated with the allocated size.  This is used as a fallback
+   if MORECORE fails.
+ */
+static void *
+sysmalloc_mmap_fallback (long int *s, INTERNAL_SIZE_T nb,
+			 INTERNAL_SIZE_T old_size, size_t minsize,
+			 size_t pagesize, int extra_flags, mstate av)
+{
+  long int size = *s;
+
+  /* Cannot merge with old top, so add its size back in */
+  if (contiguous (av))
+    size = ALIGN_UP (size + old_size, pagesize);
+
+  /* If we are relying on mmap as backup, then use larger units */
+  if ((unsigned long) (size) < minsize)
+    size = minsize;
+
+  /* Don't try if size wraps around 0 */
+  if ((unsigned long) (size) <= (unsigned long) (nb))
+    return MORECORE_FAILURE;
+
+  char *mbrk = (char *) (MMAP (0, size,
+			       mtag_mmap_flags | PROT_READ | PROT_WRITE,
+			       extra_flags));
+  if (mbrk == MAP_FAILED)
+    return MAP_FAILED;
+
+#ifdef MAP_HUGETLB
+  if (!(extra_flags & MAP_HUGETLB))
+    madvise_thp (mbrk, size);
+#endif
+
+  /* Record that we no longer have a contiguous sbrk region.  After the first
+     time mmap is used as backup, we do not ever rely on contiguous space
+     since this could incorrectly bridge regions.  */
+  set_noncontiguous (av);
+
+  *s = size;
+  return mbrk;
+}
+
 static void *
 sysmalloc (INTERNAL_SIZE_T nb, mstate av)
 {
@@ -2695,38 +2740,14 @@  sysmalloc (INTERNAL_SIZE_T nb, mstate av)
              segregated mmap region.
            */
 
-          /* Cannot merge with old top, so add its size back in */
-          if (contiguous (av))
-            size = ALIGN_UP (size + old_size, pagesize);
-
-          /* If we are relying on mmap as backup, then use larger units */
-          if ((unsigned long) (size) < (unsigned long) (MMAP_AS_MORECORE_SIZE))
-            size = MMAP_AS_MORECORE_SIZE;
-
-          /* Don't try if size wraps around 0 */
-          if ((unsigned long) (size) > (unsigned long) (nb))
-            {
-              char *mbrk = (char *) (MMAP (0, size,
-					   mtag_mmap_flags | PROT_READ | PROT_WRITE,
-					   0));
-
-              if (mbrk != MAP_FAILED)
-                {
-		  madvise_thp (mbrk, size);
-
-                  /* We do not need, and cannot use, another sbrk call to find end */
-                  brk = mbrk;
-                  snd_brk = brk + size;
-
-                  /*
-                     Record that we no longer have a contiguous sbrk region.
-                     After the first time mmap is used as backup, we do not
-                     ever rely on contiguous space since this could incorrectly
-                     bridge regions.
-                   */
-                  set_noncontiguous (av);
-                }
-            }
+	  char *mbrk = sysmalloc_mmap_fallback (&size, nb, old_size, pagesize,
+						MMAP_AS_MORECORE_SIZE, 0, av);
+	  if (mbrk != MAP_FAILED)
+	    {
+	      /* We do not need, and cannot use, another sbrk call to find end */
+	      brk = mbrk;
+	      snd_brk = brk + size;
+	    }
         }
 
       if (brk != (char *) (MORECORE_FAILURE))