diff mbox series

dlmalloc: Add an option to default malloc to init

Message ID 20200318121443.14064-1-marek.bykowski@gmail.com
State New
Headers show
Series dlmalloc: Add an option to default malloc to init | expand

Commit Message

Marek Bykowski March 18, 2020, 12:14 p.m. UTC
From: Marek Bykowski <marek.bykowski at gmail.com>

If a system wants the malloc to get moved around from one to another
memory range it should call mem_malloc_init() with the updated memory
ranges. However setting aside the new memory alone isn't enough.
It should also bring the bins and static bookkeeping data to init.

One of the use cases could be SPL U-Boot that allocates first to
the (limited) static memory and then when needs more memory, and
the DDR memory becomes available, moves the pools around.

Note that defaulting the malloc to init discards all the memory
previously allocated.

Signed-off-by: Marek Bykowski <marek.bykowski at gmail.com>
---
 Kconfig           | 14 ++++++++++++++
 common/dlmalloc.c | 41 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 52 insertions(+), 3 deletions(-)

Comments

Tom Rini March 20, 2020, 6:27 p.m. UTC | #1
On Wed, Mar 18, 2020 at 01:14:43PM +0100, marek.bykowski at gmail.com wrote:

> From: Marek Bykowski <marek.bykowski at gmail.com>
> 
> If a system wants the malloc to get moved around from one to another
> memory range it should call mem_malloc_init() with the updated memory
> ranges. However setting aside the new memory alone isn't enough.
> It should also bring the bins and static bookkeeping data to init.
> 
> One of the use cases could be SPL U-Boot that allocates first to
> the (limited) static memory and then when needs more memory, and
> the DDR memory becomes available, moves the pools around.
> 
> Note that defaulting the malloc to init discards all the memory
> previously allocated.
> 
> Signed-off-by: Marek Bykowski <marek.bykowski at gmail.com>
> ---
>  Kconfig           | 14 ++++++++++++++
>  common/dlmalloc.c | 41 ++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 52 insertions(+), 3 deletions(-)
> 
> diff --git a/Kconfig b/Kconfig
> index 1f0904f704..958553c90a 100644
> --- a/Kconfig
> +++ b/Kconfig
> @@ -209,6 +209,20 @@ if EXPERT
>  	  When disabling this, please check if malloc calls, maybe
>  	  should be replaced by calloc - if one expects zeroed memory.
>  
> +config SYS_MALLOC_DEFAULT_TO_INIT
> +	bool "Default malloc to init while reserving the memory for it"
> +	default n
> +	help
> +	  It may happen that one needs to move the dynamic allocation
> +	  from one to another memory range, eg. when moving the malloc
> +	  from the limited static to a potentially large dynamic (DDR)
> +	  memory.
> +
> +	  If so then on top of setting the updated memory aside one
> +	  needs to bring the malloc init.
> +
> +	  If such a scenario is sought choose yes.
> +
>  config TOOLS_DEBUG
>  	bool "Enable debug information for tools"
>  	help
> diff --git a/common/dlmalloc.c b/common/dlmalloc.c
> index 6f12a18d54..8b2796e280 100644
> --- a/common/dlmalloc.c
> +++ b/common/dlmalloc.c
> @@ -280,6 +280,7 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>  	    |             Unused space (may be 0 bytes long)                .
>  	    .                                                               .
>  	    .                                                               |
> +
>  nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>      `foot:' |             Size of chunk, in bytes                           |
>  	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> @@ -574,6 +575,10 @@ static void malloc_bin_reloc(void)
>  static inline void malloc_bin_reloc(void) {}
>  #endif
>  
> +#ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
> +static void malloc_init(void);
> +#endif
> +
>  ulong mem_malloc_start = 0;
>  ulong mem_malloc_end = 0;
>  ulong mem_malloc_brk = 0;
> @@ -604,6 +609,10 @@ void mem_malloc_init(ulong start, ulong size)
>  	mem_malloc_end = start + size;
>  	mem_malloc_brk = start;
>  
> +#ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
> +	malloc_init();
> +#endif
> +
>  	debug("using memory %#lx-%#lx for malloc()\n", mem_malloc_start,
>  	      mem_malloc_end);
>  #ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
> @@ -708,7 +717,36 @@ static unsigned int max_n_mmaps = 0;
>  static unsigned long max_mmapped_mem = 0;
>  #endif
>  
> +#ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
> +static void malloc_init(void)
> +{
> +	int i, j;
> +
> +	debug("bins (av_ array) are at %p\n", (void *)av_);
> +
> +	av_[0] = NULL; av_[1] = NULL;
> +	for (i = 2, j = 2; i < NAV * 2 + 2; i += 2, j++) {
> +		av_[i] = bin_at(j - 2);
> +		av_[i + 1] = bin_at(j - 2);
> +
> +		/* Just print the first few bins so that
> +		 * we can see there are alright.
> +		 */
> +		if (i < 10)
> +			debug("av_[%d]=%lx av_[%d]=%lx\n",
> +			      i, (ulong)av_[i],
> +			      i + 1, (ulong)av_[i + 1]);
> +	}
>  
> +	/* Init the static bookkeeping as well */
> +	sbrk_base = (char *)(-1);
> +	max_sbrked_mem = 0;
> +	max_total_mem = 0;
> +#ifdef DEBUG
> +	memset((void *)&current_mallinfo, 0, sizeof(struct mallinfo));
> +#endif
> +}
> +#endif
>  
>  /*
>    Debugging support

Can you please showcase using this feature somewhere?  Thanks!
diff mbox series

Patch

diff --git a/Kconfig b/Kconfig
index 1f0904f704..958553c90a 100644
--- a/Kconfig
+++ b/Kconfig
@@ -209,6 +209,20 @@  if EXPERT
 	  When disabling this, please check if malloc calls, maybe
 	  should be replaced by calloc - if one expects zeroed memory.
 
+config SYS_MALLOC_DEFAULT_TO_INIT
+	bool "Default malloc to init while reserving the memory for it"
+	default n
+	help
+	  It may happen that one needs to move the dynamic allocation
+	  from one to another memory range, eg. when moving the malloc
+	  from the limited static to a potentially large dynamic (DDR)
+	  memory.
+
+	  If so then on top of setting the updated memory aside one
+	  needs to bring the malloc init.
+
+	  If such a scenario is sought choose yes.
+
 config TOOLS_DEBUG
 	bool "Enable debug information for tools"
 	help
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index 6f12a18d54..8b2796e280 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -280,6 +280,7 @@  nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 	    |             Unused space (may be 0 bytes long)                .
 	    .                                                               .
 	    .                                                               |
+
 nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     `foot:' |             Size of chunk, in bytes                           |
 	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -574,6 +575,10 @@  static void malloc_bin_reloc(void)
 static inline void malloc_bin_reloc(void) {}
 #endif
 
+#ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
+static void malloc_init(void);
+#endif
+
 ulong mem_malloc_start = 0;
 ulong mem_malloc_end = 0;
 ulong mem_malloc_brk = 0;
@@ -604,6 +609,10 @@  void mem_malloc_init(ulong start, ulong size)
 	mem_malloc_end = start + size;
 	mem_malloc_brk = start;
 
+#ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
+	malloc_init();
+#endif
+
 	debug("using memory %#lx-%#lx for malloc()\n", mem_malloc_start,
 	      mem_malloc_end);
 #ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
@@ -708,7 +717,36 @@  static unsigned int max_n_mmaps = 0;
 static unsigned long max_mmapped_mem = 0;
 #endif
 
+#ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
+static void malloc_init(void)
+{
+	int i, j;
+
+	debug("bins (av_ array) are at %p\n", (void *)av_);
+
+	av_[0] = NULL; av_[1] = NULL;
+	for (i = 2, j = 2; i < NAV * 2 + 2; i += 2, j++) {
+		av_[i] = bin_at(j - 2);
+		av_[i + 1] = bin_at(j - 2);
+
+		/* Just print the first few bins so that
+		 * we can see there are alright.
+		 */
+		if (i < 10)
+			debug("av_[%d]=%lx av_[%d]=%lx\n",
+			      i, (ulong)av_[i],
+			      i + 1, (ulong)av_[i + 1]);
+	}
 
+	/* Init the static bookkeeping as well */
+	sbrk_base = (char *)(-1);
+	max_sbrked_mem = 0;
+	max_total_mem = 0;
+#ifdef DEBUG
+	memset((void *)&current_mallinfo, 0, sizeof(struct mallinfo));
+#endif
+}
+#endif
 
 /*
   Debugging support
@@ -1051,9 +1089,6 @@  static mchunkptr mremap_chunk(p, new_size) mchunkptr p; size_t new_size;
 
 #endif /* HAVE_MMAP */
 
-
-
-
 /*
   Extend the top-most chunk by obtaining memory from system.
   Main interface to sbrk (but see also malloc_trim).