mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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:
		
							parent
							
								
									3693a84d3b
								
							
						
					
					
						commit
						4066c33d03
					
				
					 2 changed files with 61 additions and 23 deletions
				
			
		| 
						 | 
				
			
			@ -153,8 +153,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
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -783,6 +783,31 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags)
 | 
			
		|||
	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
 | 
			
		||||
 * 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)
 | 
			
		||||
			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_info[i].name,
 | 
			
		||||
						kmalloc_info[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];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue