From 1af3af1431037f87d29434a46b91e1a059f785c2 Mon Sep 17 00:00:00 2001 From: Richard Braun Date: Sun, 21 Apr 2013 21:17:53 +0200 Subject: Optimize slab reaping Instead of walking the list of free slabs while holding the cache lock, detach the list from the cache and directly compute the final count values, and destroy slabs after releasing the cache lock. * kern/slab.c (kmem_cache_reap): Optimize. --- kern/slab.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'kern') diff --git a/kern/slab.c b/kern/slab.c index cff8096..0f0d4cb 100644 --- a/kern/slab.c +++ b/kern/slab.c @@ -899,31 +899,28 @@ static void kmem_cache_reap(struct kmem_cache *cache) { struct kmem_slab *slab; struct list dead_slabs; + unsigned long nr_free_slabs; if (cache->flags & KMEM_CF_NO_RECLAIM) return; - list_init(&dead_slabs); - simple_lock(&cache->lock); - - while (!list_empty(&cache->free_slabs)) { - slab = list_first_entry(&cache->free_slabs, struct kmem_slab, - list_node); - list_remove(&slab->list_node); - list_insert(&dead_slabs, &slab->list_node); - cache->nr_bufs -= cache->bufs_per_slab; - cache->nr_slabs--; - cache->nr_free_slabs--; - } - + list_set_head(&dead_slabs, &cache->free_slabs); + list_init(&cache->free_slabs); + nr_free_slabs = cache->nr_free_slabs; + cache->nr_bufs -= cache->bufs_per_slab * nr_free_slabs; + cache->nr_slabs -= nr_free_slabs; + cache->nr_free_slabs = 0; simple_unlock(&cache->lock); while (!list_empty(&dead_slabs)) { slab = list_first_entry(&dead_slabs, struct kmem_slab, list_node); list_remove(&slab->list_node); kmem_slab_destroy(slab, cache); + nr_free_slabs--; } + + assert(nr_free_slabs == 0); } /* -- cgit v1.2.3