From patchwork Fri May 22 10:00:46 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Guo X-Patchwork-Id: 475520 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 2241F1402BD; Fri, 22 May 2015 20:01:17 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1YvjlQ-0007Ha-HI; Fri, 22 May 2015 10:01:12 +0000 Received: from mail-pd0-f170.google.com ([209.85.192.170]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1YvjlD-000778-NH for kernel-team@lists.ubuntu.com; Fri, 22 May 2015 10:00:59 +0000 Received: by pdea3 with SMTP id a3so15839929pde.2 for ; Fri, 22 May 2015 03:00:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=fMpCd+lHhshshwgGve8nt3mnQlPa0XjpVpY0bbCuF/8=; b=WqzbUmlu8yl8JwBSNoIJX92tx91xnU/HAJHF46tLr597edkLs16Cyr/XSANM1ugYe8 KzjiWe+DRZnSwbHiT93pUdi1vymmovysTPnjDTk+M8c1HOTrnxNdxj245ANwNRWOf7Ab WhYvAEzLXk93TbTw7M58BmF1ZZrjxRu1LEvGYUCbBtfgLKZve+xC48+CaHLutVRQxejD OXTdTfaLiio+q8ZVnK9wf8/VYbbCDnl+1Ewi6G55ANwnpCIDyT8w1mXnIWc2J6DUya8T WJz4mvgupk/aR4JhUlwjqi4Pbt+HcdxaFSJZM+4N847JJ+rS3XiPJLycPOT7tI13p1IT 7QUQ== X-Gm-Message-State: ALoCoQm7P5iNWdOWbPOdTq/UqlwA7UxAS2y7guubfr7dXooc1Z09WULsqPMXDztp9I5wHCDunZ+y X-Received: by 10.70.40.164 with SMTP id y4mr14134340pdk.25.1432288859064; Fri, 22 May 2015 03:00:59 -0700 (PDT) Received: from localhost.localdomain (114-35-245-81.HINET-IP.hinet.net. [114.35.245.81]) by mx.google.com with ESMTPSA id im6sm1615394pbc.72.2015.05.22.03.00.57 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 22 May 2015 03:00:58 -0700 (PDT) From: Gavin Guo To: kernel-team@lists.ubuntu.com Subject: [Utopic][SRU][PATCH] mm/slab_common: support the slub_debug boot option on specific object size Date: Fri, 22 May 2015 18:00:46 +0800 Message-Id: <1432288847-3241-3-git-send-email-gavin.guo@canonical.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1432288847-3241-1-git-send-email-gavin.guo@canonical.com> References: <1432288847-3241-1-git-send-email-gavin.guo@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com BugLink: http://bugs.launchpad.net/bugs/1456952 The slub_debug=PU,kmalloc-xx cannot work because in the create_kmalloc_caches() the s->name is created after the create_kmalloc_cache() is called. The name is NULL in the create_kmalloc_cache() so the kmem_cache_flags() would not set the slub_debug flags to the s->flags. The fix here set up a kmalloc_names string array for the initialization purpose and delete the dynamic name creation of kmalloc_caches. Signed-off-by: Gavin Guo Acked-by: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton (cherry picked from commit 28ef5f80ed151391d35a533d0438446c0dc2d77b linux-next) Signed-off-by: Gavin Guo --- include/linux/slab.h | 22 +++++++++++++++++++ mm/slab_common.c | 62 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/include/linux/slab.h b/include/linux/slab.h index 1d9abb7..02226e7 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -154,8 +154,30 @@ size_t ksize(const void *); #define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN #define KMALLOC_MIN_SIZE ARCH_DMA_MINALIGN #define KMALLOC_SHIFT_LOW ilog2(ARCH_DMA_MINALIGN) +/* + * The KMALLOC_LOOP_LOW is the definition for the for loop index start number + * to create the kmalloc_caches object in create_kmalloc_caches(). The first + * and the second are 96 and 192. You can see that in the kmalloc_index(), if + * the KMALLOC_MIN_SIZE <= 32, then return 1 (96). If KMALLOC_MIN_SIZE <= 64, + * then return 2 (192). If the KMALLOC_MIN_SIZE is bigger than 64, we don't + * need to initialize 96 and 192. Go directly to start the KMALLOC_SHIFT_LOW. + */ +#if KMALLOC_MIN_SIZE <= 32 +#define KMALLOC_LOOP_LOW 1 +#elif KMALLOC_MIN_SIZE <= 64 +#define KMALLOC_LOOP_LOW 2 +#else +#define KMALLOC_LOOP_LOW KMALLOC_SHIFT_LOW +#endif + #else #define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long) +/* + * The KMALLOC_MIN_SIZE of slub/slab/slob is 2^3/2^5/2^3. So, even slab is used. + * The KMALLOC_MIN_SIZE <= 32. The kmalloc-96 and kmalloc-192 should also be + * initialized. + */ +#define KMALLOC_LOOP_LOW 1 #endif #ifdef CONFIG_SLOB diff --git a/mm/slab_common.c b/mm/slab_common.c index d31c4ba..ee5d373 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -509,6 +509,31 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags) } /* + * The kmalloc_names is to make slub_debug=,kmalloc-xx option work in the boot + * time. The kmalloc_index() support to 2^26=64MB. So, the final entry of the + * table is kmalloc-67108864. + */ +static struct { + const char *name; + unsigned long size; +} const kmalloc_names[] __initconst = { + {NULL, 0}, {"kmalloc-96", 96}, + {"kmalloc-192", 192}, {"kmalloc-8", 8}, + {"kmalloc-16", 16}, {"kmalloc-32", 32}, + {"kmalloc-64", 64}, {"kmalloc-128", 128}, + {"kmalloc-256", 256}, {"kmalloc-512", 512}, + {"kmalloc-1024", 1024}, {"kmalloc-2048", 2048}, + {"kmalloc-4096", 4096}, {"kmalloc-8192", 8192}, + {"kmalloc-16384", 16384}, {"kmalloc-32768", 32768}, + {"kmalloc-65536", 65536}, {"kmalloc-131072", 131072}, + {"kmalloc-262144", 262144}, {"kmalloc-524288", 524288}, + {"kmalloc-1048576", 1048576}, {"kmalloc-2097152", 2097152}, + {"kmalloc-4194304", 4194304}, {"kmalloc-8388608", 8388608}, + {"kmalloc-16777216", 16777216}, {"kmalloc-33554432", 33554432}, + {"kmalloc-67108864", 67108864} +}; + +/* * Create the kmalloc array. Some of the regular kmalloc arrays * may already have been created because they were needed to * enable allocations for slab creation. @@ -558,39 +583,30 @@ void __init create_kmalloc_caches(unsigned long flags) for (i = 128 + 8; i <= 192; i += 8) size_index[size_index_elem(i)] = 8; } - for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) { + for (i = KMALLOC_LOOP_LOW; i <= KMALLOC_SHIFT_HIGH; i++) { if (!kmalloc_caches[i]) { - kmalloc_caches[i] = create_kmalloc_cache(NULL, - 1 << i, flags); + kmalloc_caches[i] = create_kmalloc_cache( + kmalloc_names[i].name, + kmalloc_names[i].size, + flags); } /* - * Caches that are not of the two-to-the-power-of size. - * These have to be created immediately after the - * earlier power of two caches + * "i == 2" is the "kmalloc-192" case which is the last special + * case for initialization and it's the point to jump to + * allocate the minimize size of the object. In slab allocator, + * the KMALLOC_SHIFT_LOW = 5. So, it needs to skip 2^3 and 2^4 + * and go straight to allocate 2^5. If the ARCH_DMA_MINALIGN is + * defined, it may be larger than 2^5 and here is also the + * trick to skip the empty gap. */ - if (KMALLOC_MIN_SIZE <= 32 && !kmalloc_caches[1] && i == 6) - kmalloc_caches[1] = create_kmalloc_cache(NULL, 96, flags); - - if (KMALLOC_MIN_SIZE <= 64 && !kmalloc_caches[2] && i == 7) - kmalloc_caches[2] = create_kmalloc_cache(NULL, 192, flags); + if (i == 2) + i = (KMALLOC_SHIFT_LOW - 1); } /* Kmalloc array is now usable */ slab_state = UP; - for (i = 0; i <= KMALLOC_SHIFT_HIGH; i++) { - struct kmem_cache *s = kmalloc_caches[i]; - char *n; - - if (s) { - n = kasprintf(GFP_NOWAIT, "kmalloc-%d", kmalloc_size(i)); - - BUG_ON(!n); - s->name = n; - } - } - #ifdef CONFIG_ZONE_DMA for (i = 0; i <= KMALLOC_SHIFT_HIGH; i++) { struct kmem_cache *s = kmalloc_caches[i];