Help with shared memory usage

Maxim Dounin mdounin at mdounin.ru
Mon Jul 29 17:11:10 UTC 2013


Hello!

On Sat, Jul 27, 2013 at 04:10:51PM -0300, Wandenberg Peixoto wrote:

> Hello Maxim.
> 
> I've been looking into those functions and guided by your comments
> made the following patch to merge continuous block of memory.
> Can you check if it is ok?
> Comments are welcome.
> 
> --- src/core/ngx_slab.c    2013-05-06 07:27:10.000000000 -0300
> +++ src/core/ngx_slab.c    2013-07-27 15:54:55.316995223 -0300
> @@ -687,6 +687,25 @@ ngx_slab_free_pages(ngx_slab_pool_t *poo
>      page->next->prev = (uintptr_t) page;
> 
>      pool->free.next = page;
> +
> +    for (page = pool->pages; ((page->slab > 0) && (&page[page->slab] <
> (ngx_slab_page_t *) (pool->start - sizeof(ngx_slab_page_t))));) {
> +        ngx_slab_page_t *neighbour = &page[page->slab];
> +        if (((ngx_slab_page_t *) page->prev != NULL) && (page->next !=
> NULL) && ((page->prev & NGX_SLAB_PAGE_MASK) == NGX_SLAB_PAGE) &&
> +            ((ngx_slab_page_t *) neighbour->prev != NULL) &&
> (neighbour->next != NULL) && ((neighbour->prev & NGX_SLAB_PAGE_MASK) ==
> NGX_SLAB_PAGE)) {
> +
> +            page->slab += neighbour->slab;
> +
> +            ((ngx_slab_page_t *) neighbour->prev)->next = neighbour->next;
> +            neighbour->next->prev = neighbour->prev;
> +
> +            neighbour->slab = NGX_SLAB_PAGE_FREE;
> +            neighbour->prev = (uintptr_t) &pool->free;
> +            neighbour->next = &pool->free;
> +            continue;
> +        }
> +
> +        page += ((page->prev & NGX_SLAB_PAGE_MASK) == NGX_SLAB_PAGE) ?
> page->slab : 1;
> +    }
>  }

The patch doesn't look right (well, may be it works - but at least it's 
not something I would like to see committed).

The pool->pages isn't something you should iterate though, it's 
just a preallocated storage space for ngx_slab_page_t structures.  

Additionally, doing a full merge of all free blocks on a free 
operation looks too much.  It might be something we want to do on 
allocation failure, but not on a normal path in 
ngx_slab_free_pages().  And/or something lightweight may be done 
in ngx_slab_free_pages(), e.g., checking if pages following pages 
we are freeing are free too, and merging them in this case.

> 
> 
> 
> Regards,
> Wandenberg
> 
> 
> On Mon, Jul 1, 2013 at 8:36 AM, Maxim Dounin <mdounin at mdounin.ru> wrote:
> 
> > Hello!
> >
> > On Fri, Jun 28, 2013 at 10:36:39PM -0300, Wandenberg Peixoto wrote:
> >
> > > Hi,
> > >
> > > I'm trying to understand how the shared memory pool works inside the
> > Nginx.
> > > To do that, I made a very small module which create a shared memory zone
> > > with 2097152 bytes,
> > > and allocating and freeing blocks of memory, starting from 0 and
> > increasing
> > > by 1kb until the allocation fails.
> > >
> > > The strange parts to me were:
> > > - the maximum block I could allocate was 128000 bytes
> > > - each time the allocation fails, I started again from 0, but the maximum
> > > allocated block changed with the following profile
> > > 128000
> > > 87040
> > > 70656
> > > 62464
> > > 58368
> > > 54272
> > > 50176
> > > 46080
> > > 41984
> > > 37888
> > > 33792
> > > 29696
> > >
> > > This is the expected behavior?
> > > Can anyone help me explaining how shared memory works?
> > > I have another module which do an intensive shared memory usage, and
> > > understanding this can help me improve it solving some "no memory"
> > messages.
> > >
> > > I put the code in attach.
> >
> > I've looked into this, and the behaviour is expected as per
> > nginx slab allocator code and the way you do allocations in your
> > test.
> >
> > Increasing allocations of large blocks immediately followed by
> > freeing them result in free memory blocks split into smaller
> > blocks, eventually resulting in at most page size allocations
> > being possible.  Take a look at ngx_slab_alloc_pages() and
> > ngx_slab_free_pages() for details.
> >
> > Note that slab allocator nginx uses for allocations in shared
> > memory is designed mostly for small allocations.  It works well
> > for allocations less than page size, but large allocations support
> > is very simple.  Probably it should be improved, but as of now
> > nothing in nginx uses large allocations in shared memory.
> >
> > --
> > Maxim Dounin
> > http://nginx.org/en/donation.html
> >
> > _______________________________________________
> > nginx-devel mailing list
> > nginx-devel at nginx.org
> > http://mailman.nginx.org/mailman/listinfo/nginx-devel
> >


> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel


-- 
Maxim Dounin
http://nginx.org/en/donation.html



More information about the nginx-devel mailing list