Messages in this thread Patch in this message | | | From | Ed Tomlinson <> | Subject | Re: 2.5.39 kmem_cache bug | Date | Sun, 29 Sep 2002 09:15:52 -0400 |
| |
On September 28, 2002 04:56 pm, Andrew Morton wrote: > John Levon wrote: > > kmem_cache_destroy() is falsely reporting > > "kmem_cache_destroy: Can't free all objects" in 2.5.39. I have > > verified my code was freeing all allocated items correctly. > > > > Reverting this chunk : > > > > - list_add(&slabp->list, &cachep->slabs_free); > > +/* list_add(&slabp->list, &cachep->slabs_free); > > */ + if > > (unlikely(list_empty(&cachep->slabs_partial))) + > > list_add(&slabp->list, &cachep->slabs_partial); + > > else > > + kmem_slab_destroy(cachep, slabp); > > > > and the problem goes away. I haven't investigated why. > > Thanks. That's the code which leaves one empty page available > for new allocations rather than freeing it immediately. > > It's temporary. Ed, I think we can just do > > if (list_empty(&cachep->slabs_free)) > list_add(&slabp->list, &cachep->slabs_free); > else > kmem_slab_destroy(cachep, slabp); > > there?
How about this (untested) instead. If we can avoid using cachep->slabs_free its a good thing. Why use three lists when two can do the job? I use a loop to clean the partial list since its possible that for some caches we may want to have more than one slabp of buffer.
Thoughts? Ed
--------- diff -Nru a/mm/slab.c b/mm/slab.c --- a/mm/slab.c Sun Sep 29 09:08:53 2002 +++ b/mm/slab.c Sun Sep 29 09:08:53 2002 @@ -1036,7 +1036,26 @@ list_del(&cachep->next); up(&cache_chain_sem); - if (__kmem_cache_shrink(cachep)) { + /* remove any empty partial pages */ + spin_lock_irq(&cachep->spinlock); + while (!cachep->growing) { + struct list_head *p; + slab_t *slabp; + + p = cachep->slabs_partial.prev; + if (p == &cachep->slabs_partial) + break; + + slabp = list_entry(cachep->slabs_partial.prev, slab_t, list); + if (slabp->inuse) + break; + + list_del(&slabp->list); + + } + spin_unlock_irq(&cachep->spinlock); + + if (!list_empty(&cachep->slabs_full) || !list_empty(&cachep->slabs_partial)) { printk(KERN_ERR "kmem_cache_destroy: Can't free all objects %p\n", cachep); down(&cache_chain_sem); --------- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |