From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759743Ab2HXQHm (ORCPT ); Fri, 24 Aug 2012 12:07:42 -0400 Received: from mail-pz0-f46.google.com ([209.85.210.46]:55814 "EHLO mail-pz0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759719Ab2HXQHL (ORCPT ); Fri, 24 Aug 2012 12:07:11 -0400 From: Joonsoo Kim To: Pekka Enberg Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, Joonsoo Kim , Christoph Lameter Subject: [PATCH 2/2] slub: correct the calculation of the number of cpu objects in get_partial_node Date: Sat, 25 Aug 2012 01:05:03 +0900 Message-Id: <1345824303-30292-2-git-send-email-js1304@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1345824303-30292-1-git-send-email-js1304@gmail.com> References: <1345824303-30292-1-git-send-email-js1304@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In get_partial_node(), we want to refill cpu slab and cpu partial slabs until the number of object kept in the per cpu slab and cpu partial lists of a processor is reached to max_cpu_object. However, in current implementation, it is not achieved. See following code in get_partial_node(). if (!object) { c->page = page; stat(s, ALLOC_FROM_PARTIAL); object = t; available = page->objects - page->inuse; } else { available = put_cpu_partial(s, page, 0); stat(s, CPU_PARTIAL_NODE); } if (kmem_cache_debug(s) || available > s->cpu_partial / 2) break; In case of !object (available = page->objects - page->inuse), "available" means the number of objects in cpu slab. In this time, we don't have any cpu partial slab, so "available" imply the number of objects available to the cpu without locking. This is what we want. But, look at another "available" (available = put_cpu_partial(s, page, 0)). This "available" doesn't include the number of objects in cpu slab. It only include the number of objects in cpu partial slabs. So, it doesn't imply the number of objects available to the cpu without locking. This isn't what we want. Therefore fix it to imply same meaning in both case and rename "available" to "cpu_slab_objects" for readability. Signed-off-by: Joonsoo Kim Cc: Christoph Lameter diff --git a/mm/slub.c b/mm/slub.c index d597530..c96e0e4 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1538,6 +1538,7 @@ static void *get_partial_node(struct kmem_cache *s, { struct page *page, *page2; void *object = NULL; + int cpu_slab_objects = 0, pobjects = 0; /* * Racy check. If we mistakenly see no partial slabs then we @@ -1551,7 +1552,6 @@ static void *get_partial_node(struct kmem_cache *s, spin_lock(&n->list_lock); list_for_each_entry_safe(page, page2, &n->partial, lru) { void *t = acquire_slab(s, n, page, object == NULL); - int available; if (!t) break; @@ -1560,12 +1560,13 @@ static void *get_partial_node(struct kmem_cache *s, c->page = page; stat(s, ALLOC_FROM_PARTIAL); object = t; - available = page->objects - page->inuse; + cpu_slab_objects = page->objects - page->inuse; } else { - available = put_cpu_partial(s, page, 0); + pobjects = put_cpu_partial(s, page, 0); stat(s, CPU_PARTIAL_NODE); } - if (kmem_cache_debug(s) || available > s->max_cpu_object / 2) + if (kmem_cache_debug(s) + || cpu_slab_objects + pobjects > s->max_cpu_object / 2) break; } -- 1.7.9.5