mm/slab_common: support the slub_debug boot option on specific object size
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. [akpm@linux-foundation.org: s/kmalloc_names/kmalloc_info/, tweak comment text] Signed-off-by: Gavin Guo <gavin.guo@canonical.com> Acked-by: Christoph Lameter <cl@linux.com> Cc: Pekka Enberg <penberg@kernel.org> Cc: David Rientjes <rientjes@google.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
3693a84d3b
Коммит
4066c33d03
|
@ -153,8 +153,30 @@ size_t ksize(const void *);
|
||||||
#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN
|
#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN
|
||||||
#define KMALLOC_MIN_SIZE ARCH_DMA_MINALIGN
|
#define KMALLOC_MIN_SIZE ARCH_DMA_MINALIGN
|
||||||
#define KMALLOC_SHIFT_LOW ilog2(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
|
#else
|
||||||
#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long)
|
#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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -783,6 +783,31 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags)
|
||||||
return kmalloc_caches[index];
|
return kmalloc_caches[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* kmalloc_info[] is to make slub_debug=,kmalloc-xx option work at boot time.
|
||||||
|
* kmalloc_index() supports up to 2^26=64MB, so the final entry of the table is
|
||||||
|
* kmalloc-67108864.
|
||||||
|
*/
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
unsigned long size;
|
||||||
|
} const kmalloc_info[] __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
|
* Create the kmalloc array. Some of the regular kmalloc arrays
|
||||||
* may already have been created because they were needed to
|
* may already have been created because they were needed to
|
||||||
|
@ -833,39 +858,30 @@ void __init create_kmalloc_caches(unsigned long flags)
|
||||||
for (i = 128 + 8; i <= 192; i += 8)
|
for (i = 128 + 8; i <= 192; i += 8)
|
||||||
size_index[size_index_elem(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]) {
|
if (!kmalloc_caches[i]) {
|
||||||
kmalloc_caches[i] = create_kmalloc_cache(NULL,
|
kmalloc_caches[i] = create_kmalloc_cache(
|
||||||
1 << i, flags);
|
kmalloc_info[i].name,
|
||||||
|
kmalloc_info[i].size,
|
||||||
|
flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Caches that are not of the two-to-the-power-of size.
|
* "i == 2" is the "kmalloc-192" case which is the last special
|
||||||
* These have to be created immediately after the
|
* case for initialization and it's the point to jump to
|
||||||
* earlier power of two caches
|
* 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)
|
if (i == 2)
|
||||||
kmalloc_caches[1] = create_kmalloc_cache(NULL, 96, flags);
|
i = (KMALLOC_SHIFT_LOW - 1);
|
||||||
|
|
||||||
if (KMALLOC_MIN_SIZE <= 64 && !kmalloc_caches[2] && i == 7)
|
|
||||||
kmalloc_caches[2] = create_kmalloc_cache(NULL, 192, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Kmalloc array is now usable */
|
/* Kmalloc array is now usable */
|
||||||
slab_state = UP;
|
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
|
#ifdef CONFIG_ZONE_DMA
|
||||||
for (i = 0; i <= KMALLOC_SHIFT_HIGH; i++) {
|
for (i = 0; i <= KMALLOC_SHIFT_HIGH; i++) {
|
||||||
struct kmem_cache *s = kmalloc_caches[i];
|
struct kmem_cache *s = kmalloc_caches[i];
|
||||||
|
|
Загрузка…
Ссылка в новой задаче