On Wed, 27 Oct 2010 11:39:24 +0100
Grant Likely <[email protected]> wrote:

> On Fri, Oct 22, 2010 at 05:22:47PM -0700, Andres Salomon wrote:
> > 
> > Calling alloc_bootmem() for tiny chunks of memory over and over is
> > really slow; on an XO-1, it caused the time between when the kernel
> > started booting and when the display came alive (post-lxfb probe)
> > to increase to 44s.  This patch optimizes the prom_early_alloc
> > function by calling alloc_bootmem for 4k-sized blocks of memory,
> > and handing out chunks of that to callers.  With this hack, the
> > time between kernel load and display initialization decreased to
> > 23s.  If there's a better way to do this early in the boot process,
> > please let me know.
> > 
> > (Note: increasing the chunk size to 16k didn't noticably affect
> > boot time, and wasted 9k.)
> > 
> > Signed-off-by: Andres Salomon <[email protected]>
> > ---
> >  arch/x86/kernel/olpc_dt.c |   27 +++++++++++++++++++++++----
> >  1 files changed, 23 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/x86/kernel/olpc_dt.c b/arch/x86/kernel/olpc_dt.c
> > index f660a11..44dd2ae 100644
> > --- a/arch/x86/kernel/olpc_dt.c
> > +++ b/arch/x86/kernel/olpc_dt.c
> > @@ -123,16 +123,35 @@ static int __init olpc_dt_pkg2path(phandle
> > node, char *buf, }
> >  
> >  static unsigned int prom_early_allocated __initdata;
> > +#define DT_CHUNK_SIZE (1<<12)
> 
> PAGE_SIZE perhaps?
> 

I'd rather not imply that it's anything but completely arbitrary..



> >  
> >  void * __init prom_early_alloc(unsigned long size)
> >  {
> > +   static u8 *mem = NULL;
> > +   static size_t free_mem = 0;
> >     void *res;
> >  
> > -   res = alloc_bootmem(size);
> > -   if (res)
> > -           memset(res, 0, size);
> > +   if (free_mem >= size) {
> > +           /* allocate from the local cache */
> > +           free_mem -= size;
> > +           res = mem;
> > +           mem += size;
> > +           return res;
> > +   }
> >  
> > -   prom_early_allocated += size;
> > +   /*
> > +    * To mimimize the number of allocations, grab 4k of
> > memory (that's
> > +    * an arbitrary choice that matches PAGE_SIZE on the
> > platforms we care
> > +    * about, and minimizes wasted bootmem) and hand off
> > chunks of it to
> > +    * callers.
> > +    */
> > +   res = alloc_bootmem(DT_CHUNK_SIZE);
> > +   if (res) {
> > +           prom_early_allocated += DT_CHUNK_SIZE;
> > +           memset(res, 0, DT_CHUNK_SIZE);
> > +           free_mem = DT_CHUNK_SIZE - size;
> > +           mem = res + size;
> > +   }
> 
> These two hunks should be flipped around so that only one chunk does
> the allocation from the pool.  As so:
> 
>       /*
>        * To mimimize the number of allocations, grab 4k of memory
> (that's
>        * an arbitrary choice that matches PAGE_SIZE on the
> platforms we care
>        * about, and minimizes wasted bootmem) and hand off chunks
> of it to
>        * callers.
>        */
>       if (free_mem < size) {
>               free_mem = max(DT_CHUNK_SIZE, size);
>               mem = alloc_bootmem(free_mem);
>               if (!mem) {
>                       free_mem = 0;
>                       return NULL;
>               }
>               memset(mem, 0, free_mem);
>               prom_early_allocated += free_mem;
>       }
> 
>       res = mem;
>       free_mem -= size;
>       mem += size;
>       return res;
> 
> g.

Makes sense, thanks.
_______________________________________________
devicetree-discuss mailing list
[email protected]
https://lists.ozlabs.org/listinfo/devicetree-discuss

Reply via email to