Message ID | 20200318121443.14064-1-marek.bykowski@gmail.com |
---|---|
State | New |
Headers | show |
Series | dlmalloc: Add an option to default malloc to init | expand |
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 *)¤t_mallinfo, 0, sizeof(struct mallinfo)); > +#endif > +} > +#endif > > /* > Debugging support Can you please showcase using this feature somewhere? Thanks!
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 *)¤t_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).